mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-22 04:58:49 +03:00
Add custom element support
This commit is contained in:
parent
94542e85d3
commit
61e39d98eb
BIN
docs/assets/sortTableV2.png
Normal file
BIN
docs/assets/sortTableV2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
@ -14,6 +14,7 @@ import Page.ProgressIndicator
|
|||||||
import Page.Select
|
import Page.Select
|
||||||
import Page.Snackbar
|
import Page.Snackbar
|
||||||
import Page.SortTable
|
import Page.SortTable
|
||||||
|
import Page.SortTableV2
|
||||||
import Page.Switch
|
import Page.Switch
|
||||||
import Page.Tab
|
import Page.Tab
|
||||||
import Page.TextInput
|
import Page.TextInput
|
||||||
@ -29,6 +30,7 @@ pages =
|
|||||||
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|
||||||
|> UIExplorer.nextPage "Text Input" Page.TextInput.page
|
|> UIExplorer.nextPage "Text Input" Page.TextInput.page
|
||||||
|> UIExplorer.nextPage "Sort Table" Page.SortTable.page
|
|> UIExplorer.nextPage "Sort Table" Page.SortTable.page
|
||||||
|
|> UIExplorer.nextPage "Sort Table V2" Page.SortTableV2.page
|
||||||
|> UIExplorer.nextPage "Snackbar" Page.Snackbar.page
|
|> UIExplorer.nextPage "Snackbar" Page.Snackbar.page
|
||||||
|> UIExplorer.nextPage "Item" Page.Item.page
|
|> UIExplorer.nextPage "Item" Page.Item.page
|
||||||
|> UIExplorer.nextPage "ProgressIndicator" Page.ProgressIndicator.page
|
|> UIExplorer.nextPage "ProgressIndicator" Page.ProgressIndicator.page
|
||||||
|
286
explorer/src/Page/SortTableV2.elm
Normal file
286
explorer/src/Page/SortTableV2.elm
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
module Page.SortTableV2 exposing (page)
|
||||||
|
|
||||||
|
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Material.Icons
|
||||||
|
import Material.Icons.Types exposing (Coloring(..))
|
||||||
|
import Page
|
||||||
|
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
|
||||||
|
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
|
||||||
|
import Widget
|
||||||
|
import Widget.Icon
|
||||||
|
import Widget.Material as Material
|
||||||
|
|
||||||
|
|
||||||
|
{-| The title of this page
|
||||||
|
-}
|
||||||
|
title : String
|
||||||
|
title =
|
||||||
|
"Sort Table V2"
|
||||||
|
|
||||||
|
|
||||||
|
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||||
|
-}
|
||||||
|
description : String
|
||||||
|
description =
|
||||||
|
"A simple sort table with custom elements in columns."
|
||||||
|
|
||||||
|
|
||||||
|
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||||
|
-}
|
||||||
|
viewFunctions =
|
||||||
|
let
|
||||||
|
viewTable style content columns asc sortBy { palette } () =
|
||||||
|
Widget.sortTableV2 (style palette)
|
||||||
|
{ content = content
|
||||||
|
, columns = columns
|
||||||
|
, asc = asc
|
||||||
|
, sortBy = sortBy
|
||||||
|
, onChange = always ()
|
||||||
|
}
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.sortTableV2"
|
||||||
|
in
|
||||||
|
[ viewTable ]
|
||||||
|
|> List.foldl Story.addTile
|
||||||
|
Story.initStaticTiles
|
||||||
|
|
||||||
|
|
||||||
|
{-| Let's you play around with the options.
|
||||||
|
Note that the order of these stories must follow the order of the arguments from the view functions.
|
||||||
|
-}
|
||||||
|
book : Tile.Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) flags
|
||||||
|
book =
|
||||||
|
Story.book (Just "Options")
|
||||||
|
viewFunctions
|
||||||
|
--Adding a option for different styles.
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Style"
|
||||||
|
( "SortTable", Material.sortTable )
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Content"
|
||||||
|
( "Data"
|
||||||
|
, [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||||
|
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||||
|
, { id = 3, name = "Alfred", rating = 4.22, hash = Just "6fs1" }
|
||||||
|
, { id = 4, name = "Thomas", rating = 3, hash = Just "k52f" }
|
||||||
|
]
|
||||||
|
)
|
||||||
|
[ ( "None", [] )
|
||||||
|
]
|
||||||
|
)
|
||||||
|
--Changing the text of the label
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Columns"
|
||||||
|
( "5 Columns"
|
||||||
|
, [ Widget.intColumnV2
|
||||||
|
{ title = "Id"
|
||||||
|
, value = .id
|
||||||
|
, toString = \int -> "#" ++ String.fromInt int
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.stringColumnV2
|
||||||
|
{ title = "Name"
|
||||||
|
, value = .name
|
||||||
|
, toString = identity
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.floatColumnV2
|
||||||
|
{ title = "Rating"
|
||||||
|
, value = .rating
|
||||||
|
, toString = String.fromFloat
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.customColumnV2
|
||||||
|
{ title = "Action"
|
||||||
|
, value =
|
||||||
|
\{name} ->
|
||||||
|
Element.el
|
||||||
|
[ Element.padding 10
|
||||||
|
]
|
||||||
|
(Widget.iconButton
|
||||||
|
(Material.containedButton Material.defaultPalette)
|
||||||
|
{ text = name
|
||||||
|
, icon =
|
||||||
|
Widget.Icon.elmMaterialIcons
|
||||||
|
Color
|
||||||
|
Material.Icons.favorite
|
||||||
|
, onPress = Nothing
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.unsortableColumnV2
|
||||||
|
{ title = "Hash"
|
||||||
|
, toString = .hash >> Maybe.withDefault "None"
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
[ ( "1 Column"
|
||||||
|
, [ Widget.intColumnV2
|
||||||
|
{ title = "Id"
|
||||||
|
, value = .id
|
||||||
|
, toString = \int -> "#" ++ String.fromInt int
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, ( "None", [] )
|
||||||
|
]
|
||||||
|
)
|
||||||
|
--Change the Icon
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "Sort ascendingly"
|
||||||
|
( True
|
||||||
|
, False
|
||||||
|
)
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Sort by"
|
||||||
|
( "Id", "Id" )
|
||||||
|
[ ( "Name", "Name" )
|
||||||
|
, ( "Rating", "Rating" )
|
||||||
|
, ( "Hash", "Hash" )
|
||||||
|
, ( "None", "" )
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|> Story.build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{- This next section is essentially just a normal Elm program. -}
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Interactive Demonstration
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
type alias Model =
|
||||||
|
{ title : String
|
||||||
|
, asc : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= ChangedSorting String
|
||||||
|
| PressedButton String
|
||||||
|
|
||||||
|
|
||||||
|
init : ( Model, Cmd Msg )
|
||||||
|
init =
|
||||||
|
( { title = "Name", asc = True }
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
|
update msg model =
|
||||||
|
case msg of
|
||||||
|
ChangedSorting string ->
|
||||||
|
( { title = string
|
||||||
|
, asc =
|
||||||
|
if model.title == string then
|
||||||
|
not model.asc
|
||||||
|
|
||||||
|
else
|
||||||
|
True
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
PressedButton _ ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
subscriptions : Model -> Sub Msg
|
||||||
|
subscriptions _ =
|
||||||
|
Sub.none
|
||||||
|
|
||||||
|
|
||||||
|
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
||||||
|
-}
|
||||||
|
view : Context -> Model -> Element Msg
|
||||||
|
view { palette } model =
|
||||||
|
Widget.sortTableV2 (Material.sortTable palette)
|
||||||
|
{ content =
|
||||||
|
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||||
|
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||||
|
, { id = 3, name = "Alfred", rating = 4.22, hash = Just "6fs1" }
|
||||||
|
, { id = 4, name = "Thomas", rating = 3, hash = Just "k52f" }
|
||||||
|
]
|
||||||
|
, columns =
|
||||||
|
[ Widget.intColumnV2
|
||||||
|
{ title = "Id"
|
||||||
|
, value = .id
|
||||||
|
, toString = \int -> "#" ++ String.fromInt int
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.stringColumnV2
|
||||||
|
{ title = "Name"
|
||||||
|
, value = .name
|
||||||
|
, toString = identity
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.floatColumnV2
|
||||||
|
{ title = "Rating"
|
||||||
|
, value = .rating
|
||||||
|
, toString = String.fromFloat
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.customColumnV2
|
||||||
|
{ title = "Action"
|
||||||
|
, value =
|
||||||
|
\{name} ->
|
||||||
|
Element.el
|
||||||
|
[ Element.padding 10
|
||||||
|
]
|
||||||
|
(Widget.iconButton
|
||||||
|
(Material.containedButton Material.defaultPalette)
|
||||||
|
{ text = name
|
||||||
|
, icon =
|
||||||
|
Widget.Icon.elmMaterialIcons
|
||||||
|
Color
|
||||||
|
Material.Icons.favorite
|
||||||
|
, onPress = Just <| PressedButton name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.unsortableColumnV2
|
||||||
|
{ title = "Hash"
|
||||||
|
, toString = .hash >> Maybe.withDefault "None"
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
]
|
||||||
|
, asc = model.asc
|
||||||
|
, sortBy = model.title
|
||||||
|
, onChange = ChangedSorting
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
demo : Tile Model Msg flags
|
||||||
|
demo =
|
||||||
|
{ init = always init
|
||||||
|
, update = update
|
||||||
|
, view = Page.demo view
|
||||||
|
, subscriptions = subscriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
page =
|
||||||
|
Page.create
|
||||||
|
{ title = title
|
||||||
|
, description = description
|
||||||
|
, book = book
|
||||||
|
, demo = demo
|
||||||
|
}
|
@ -34,11 +34,10 @@ type alias SortTableStyle msg =
|
|||||||
|
|
||||||
{-| A Sortable list allows you to sort coulmn.
|
{-| A Sortable list allows you to sort coulmn.
|
||||||
-}
|
-}
|
||||||
type ColumnType a msg
|
type ColumnType a
|
||||||
= StringColumn { value : a -> String, toString : String -> String }
|
= StringColumn { value : a -> String, toString : String -> String }
|
||||||
| IntColumn { value : a -> Int, toString : Int -> String }
|
| IntColumn { value : a -> Int, toString : Int -> String }
|
||||||
| FloatColumn { value : a -> Float, toString : Float -> String }
|
| FloatColumn { value : a -> Float, toString : Float -> String }
|
||||||
| ElementColumn { value : a -> Element msg }
|
|
||||||
| UnsortableColumn (a -> String)
|
| UnsortableColumn (a -> String)
|
||||||
|
|
||||||
|
|
||||||
@ -46,22 +45,22 @@ type ColumnType a msg
|
|||||||
-}
|
-}
|
||||||
type alias SortTable a msg =
|
type alias SortTable a msg =
|
||||||
{ content : List a
|
{ content : List a
|
||||||
, columns : List (Column a msg)
|
, columns : List (Column a)
|
||||||
, sortBy : String
|
, sortBy : String
|
||||||
, asc : Bool
|
, asc : Bool
|
||||||
, onChange : String -> msg
|
, onChange : String -> msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Column a msg
|
type Column a
|
||||||
= Column
|
= Column
|
||||||
{ title : String
|
{ title : String
|
||||||
, content : ColumnType a msg
|
, content : ColumnType a
|
||||||
, width : Length
|
, width : Length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsortableColumn : { title : String, toString : a -> String, width : Length } -> Column a msg
|
unsortableColumn : { title : String, toString : a -> String, width : Length } -> Column a
|
||||||
unsortableColumn { title, toString, width } =
|
unsortableColumn { title, toString, width } =
|
||||||
Column
|
Column
|
||||||
{ title = title
|
{ title = title
|
||||||
@ -72,7 +71,7 @@ unsortableColumn { title, toString, width } =
|
|||||||
|
|
||||||
{-| A Column containing a Int
|
{-| A Column containing a Int
|
||||||
-}
|
-}
|
||||||
intColumn : { title : String, value : a -> Int, toString : Int -> String, width : Length } -> Column a msg
|
intColumn : { title : String, value : a -> Int, toString : Int -> String, width : Length } -> Column a
|
||||||
intColumn { title, value, toString, width } =
|
intColumn { title, value, toString, width } =
|
||||||
Column
|
Column
|
||||||
{ title = title
|
{ title = title
|
||||||
@ -83,7 +82,7 @@ intColumn { title, value, toString, width } =
|
|||||||
|
|
||||||
{-| A Column containing a Float
|
{-| A Column containing a Float
|
||||||
-}
|
-}
|
||||||
floatColumn : { title : String, value : a -> Float, toString : Float -> String, width : Length } -> Column a msg
|
floatColumn : { title : String, value : a -> Float, toString : Float -> String, width : Length } -> Column a
|
||||||
floatColumn { title, value, toString, width } =
|
floatColumn { title, value, toString, width } =
|
||||||
Column
|
Column
|
||||||
{ title = title
|
{ title = title
|
||||||
@ -94,7 +93,7 @@ floatColumn { title, value, toString, width } =
|
|||||||
|
|
||||||
{-| A Column containing a String
|
{-| A Column containing a String
|
||||||
-}
|
-}
|
||||||
stringColumn : { title : String, value : a -> String, toString : String -> String, width : Length } -> Column a msg
|
stringColumn : { title : String, value : a -> String, toString : String -> String, width : Length } -> Column a
|
||||||
stringColumn { title, value, toString, width } =
|
stringColumn { title, value, toString, width } =
|
||||||
Column
|
Column
|
||||||
{ title = title
|
{ title = title
|
||||||
@ -111,7 +110,7 @@ sortTable :
|
|||||||
-> Element msg
|
-> Element msg
|
||||||
sortTable style model =
|
sortTable style model =
|
||||||
let
|
let
|
||||||
findTitle : List (Column a msg) -> Maybe (ColumnType a msg)
|
findTitle : List (Column a) -> Maybe (ColumnType a)
|
||||||
findTitle list =
|
findTitle list =
|
||||||
case list of
|
case list of
|
||||||
[] ->
|
[] ->
|
||||||
@ -141,9 +140,6 @@ sortTable style model =
|
|||||||
FloatColumn { value } ->
|
FloatColumn { value } ->
|
||||||
Just <| List.sortBy value
|
Just <| List.sortBy value
|
||||||
|
|
||||||
ElementColumn _ ->
|
|
||||||
Nothing
|
|
||||||
|
|
||||||
UnsortableColumn _ ->
|
UnsortableColumn _ ->
|
||||||
Nothing
|
Nothing
|
||||||
)
|
)
|
||||||
@ -184,20 +180,18 @@ sortTable style model =
|
|||||||
, view =
|
, view =
|
||||||
(case column.content of
|
(case column.content of
|
||||||
IntColumn { value, toString } ->
|
IntColumn { value, toString } ->
|
||||||
value >> toString >> Element.text
|
value >> toString
|
||||||
|
|
||||||
FloatColumn { value, toString } ->
|
FloatColumn { value, toString } ->
|
||||||
value >> toString >> Element.text
|
value >> toString
|
||||||
|
|
||||||
StringColumn { value, toString } ->
|
StringColumn { value, toString } ->
|
||||||
value >> toString >> Element.text
|
value >> toString
|
||||||
|
|
||||||
ElementColumn { value } ->
|
|
||||||
value
|
|
||||||
|
|
||||||
UnsortableColumn toString ->
|
UnsortableColumn toString ->
|
||||||
toString >> Element.text
|
toString
|
||||||
)
|
)
|
||||||
|
>> Element.text
|
||||||
>> List.singleton
|
>> List.singleton
|
||||||
>> Element.paragraph []
|
>> Element.paragraph []
|
||||||
}
|
}
|
||||||
|
212
src/Internal/SortTableV2.elm
Normal file
212
src/Internal/SortTableV2.elm
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
module Internal.SortTableV2 exposing
|
||||||
|
( ColumnV2
|
||||||
|
, ColumnTypeV2
|
||||||
|
, SortTableV2
|
||||||
|
, floatColumnV2
|
||||||
|
, intColumnV2
|
||||||
|
, sortTableV2
|
||||||
|
, stringColumnV2
|
||||||
|
, unsortableColumnV2
|
||||||
|
, customColumnV2
|
||||||
|
)
|
||||||
|
|
||||||
|
import Element exposing (Attribute, Element, Length)
|
||||||
|
import Internal.Button as Button exposing (ButtonStyle)
|
||||||
|
import Widget.Icon exposing (Icon)
|
||||||
|
import Internal.SortTable as SortTable
|
||||||
|
|
||||||
|
|
||||||
|
{-| A Sortable list allows you to sort column.
|
||||||
|
-}
|
||||||
|
type ColumnTypeV2 a msg
|
||||||
|
= StringColumn { value : a -> String, toString : String -> String }
|
||||||
|
| IntColumn { value : a -> Int, toString : Int -> String }
|
||||||
|
| FloatColumn { value : a -> Float, toString : Float -> String }
|
||||||
|
| CustomColumn { value : a -> Element msg }
|
||||||
|
| UnsortableColumn (a -> String)
|
||||||
|
|
||||||
|
|
||||||
|
{-| The Model contains the sorting column name and if ascending or descending.
|
||||||
|
-}
|
||||||
|
type alias SortTableV2 a msg =
|
||||||
|
{ content : List a
|
||||||
|
, columns : List (ColumnV2 a msg)
|
||||||
|
, sortBy : String
|
||||||
|
, asc : Bool
|
||||||
|
, onChange : String -> msg
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type ColumnV2 a msg
|
||||||
|
= Column
|
||||||
|
{ title : String
|
||||||
|
, content : ColumnTypeV2 a msg
|
||||||
|
, width : Length
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsortableColumnV2 : { title : String, toString : a -> String, width : Length } -> ColumnV2 a msg
|
||||||
|
unsortableColumnV2 { title, toString, width } =
|
||||||
|
Column
|
||||||
|
{ title = title
|
||||||
|
, content = UnsortableColumn toString
|
||||||
|
, width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| A Column containing a Int
|
||||||
|
-}
|
||||||
|
intColumnV2 : { title : String, value : a -> Int, toString : Int -> String, width : Length } -> ColumnV2 a msg
|
||||||
|
intColumnV2 { title, value, toString, width } =
|
||||||
|
Column
|
||||||
|
{ title = title
|
||||||
|
, content = IntColumn { value = value, toString = toString }
|
||||||
|
, width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| A Column containing a Float
|
||||||
|
-}
|
||||||
|
floatColumnV2 : { title : String, value : a -> Float, toString : Float -> String, width : Length } -> ColumnV2 a msg
|
||||||
|
floatColumnV2 { title, value, toString, width } =
|
||||||
|
Column
|
||||||
|
{ title = title
|
||||||
|
, content = FloatColumn { value = value, toString = toString }
|
||||||
|
, width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| A Column containing a String
|
||||||
|
-}
|
||||||
|
stringColumnV2 : { title : String, value : a -> String, toString : String -> String, width : Length } -> ColumnV2 a msg
|
||||||
|
stringColumnV2 { title, value, toString, width } =
|
||||||
|
Column
|
||||||
|
{ title = title
|
||||||
|
, content = StringColumn { value = value, toString = toString }
|
||||||
|
, width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
{-| A Column containing an Element
|
||||||
|
-}
|
||||||
|
customColumnV2 : { title : String, value : a -> Element msg, width : Length } -> ColumnV2 a msg
|
||||||
|
customColumnV2 { title, value, width } =
|
||||||
|
Column
|
||||||
|
{ title = title
|
||||||
|
, content = CustomColumn { value = value }
|
||||||
|
, width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| The View
|
||||||
|
-}
|
||||||
|
sortTableV2 :
|
||||||
|
SortTable.SortTableStyle msg
|
||||||
|
-> SortTableV2 a msg
|
||||||
|
-> Element msg
|
||||||
|
sortTableV2 style model =
|
||||||
|
let
|
||||||
|
findTitle : List (ColumnV2 a msg) -> Maybe (ColumnTypeV2 a msg)
|
||||||
|
findTitle list =
|
||||||
|
case list of
|
||||||
|
[] ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
(Column head) :: tail ->
|
||||||
|
if head.title == model.sortBy then
|
||||||
|
Just head.content
|
||||||
|
|
||||||
|
else
|
||||||
|
findTitle tail
|
||||||
|
in
|
||||||
|
Element.table style.elementTable
|
||||||
|
{ data =
|
||||||
|
model.content
|
||||||
|
|> (model.columns
|
||||||
|
|> findTitle
|
||||||
|
|> Maybe.andThen
|
||||||
|
(\c ->
|
||||||
|
case c of
|
||||||
|
StringColumn { value } ->
|
||||||
|
Just <| List.sortBy value
|
||||||
|
|
||||||
|
IntColumn { value } ->
|
||||||
|
Just <| List.sortBy value
|
||||||
|
|
||||||
|
FloatColumn { value } ->
|
||||||
|
Just <| List.sortBy value
|
||||||
|
|
||||||
|
CustomColumn _ ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
UnsortableColumn _ ->
|
||||||
|
Nothing
|
||||||
|
)
|
||||||
|
|> Maybe.withDefault identity
|
||||||
|
)
|
||||||
|
|> (if model.asc then
|
||||||
|
identity
|
||||||
|
|
||||||
|
else
|
||||||
|
List.reverse
|
||||||
|
)
|
||||||
|
, columns =
|
||||||
|
model.columns
|
||||||
|
|> List.map
|
||||||
|
(\(Column column) ->
|
||||||
|
{ header =
|
||||||
|
Button.button style.content.header
|
||||||
|
{ text = column.title
|
||||||
|
, icon =
|
||||||
|
if column.title == model.sortBy then
|
||||||
|
if model.asc then
|
||||||
|
style.content.ascIcon
|
||||||
|
|
||||||
|
else
|
||||||
|
style.content.descIcon
|
||||||
|
|
||||||
|
else
|
||||||
|
style.content.defaultIcon
|
||||||
|
, onPress =
|
||||||
|
case column.content of
|
||||||
|
UnsortableColumn _ ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
CustomColumn _ ->
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Just <| model.onChange <| column.title
|
||||||
|
}
|
||||||
|
, width = column.width
|
||||||
|
, view =
|
||||||
|
(case column.content of
|
||||||
|
IntColumn { value, toString } ->
|
||||||
|
value
|
||||||
|
>> toString
|
||||||
|
>> Element.text
|
||||||
|
>> List.singleton
|
||||||
|
>> Element.paragraph []
|
||||||
|
|
||||||
|
FloatColumn { value, toString } ->
|
||||||
|
value
|
||||||
|
>> toString
|
||||||
|
>> Element.text
|
||||||
|
>> List.singleton
|
||||||
|
>> Element.paragraph []
|
||||||
|
|
||||||
|
StringColumn { value, toString } ->
|
||||||
|
value
|
||||||
|
>> toString
|
||||||
|
>> Element.text
|
||||||
|
>> List.singleton
|
||||||
|
>> Element.paragraph []
|
||||||
|
|
||||||
|
CustomColumn { value } ->
|
||||||
|
value >> Element.el []
|
||||||
|
|
||||||
|
UnsortableColumn toString ->
|
||||||
|
toString >> Element.text
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
208
src/Widget.elm
208
src/Widget.elm
@ -19,6 +19,7 @@ module Widget exposing
|
|||||||
, itemList
|
, itemList
|
||||||
, AppBarStyle, menuBar, tabBar
|
, AppBarStyle, menuBar, tabBar
|
||||||
, SortTableStyle, SortTable, Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
, SortTableStyle, SortTable, Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
||||||
|
, SortTableV2, ColumnV2, sortTableV2, floatColumnV2, intColumnV2, stringColumnV2, unsortableColumnV2, customColumnV2
|
||||||
, TextInputStyle, TextInput, textInput, usernameInput, emailInput, searchInput, spellCheckedInput
|
, TextInputStyle, TextInput, textInput, usernameInput, emailInput, searchInput, spellCheckedInput
|
||||||
, PasswordInputStyle, PasswordInput, newPasswordInputV2, currentPasswordInputV2
|
, PasswordInputStyle, PasswordInput, newPasswordInputV2, currentPasswordInputV2
|
||||||
, TabStyle, Tab, tab
|
, TabStyle, Tab, tab
|
||||||
@ -131,6 +132,13 @@ You can create you own widgets by sticking widgets types together.
|
|||||||
@docs SortTableStyle, SortTable, Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
@docs SortTableStyle, SortTable, Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
||||||
|
|
||||||
|
|
||||||
|
# Sort Table V2
|
||||||
|
|
||||||
|
![Sort Table V2](https://orasund.github.io/elm-ui-widgets/assets/sortTableV2.png)
|
||||||
|
|
||||||
|
@docs SortTableStyle, SortTableV2, ColumnV2, sortTableV2, floatColumnV2, intColumnV2, stringColumnV2, customColumnV2, unsortableColumnV2
|
||||||
|
|
||||||
|
|
||||||
# Text Input
|
# Text Input
|
||||||
|
|
||||||
![textInput](https://orasund.github.io/elm-ui-widgets/assets/textInput.png)
|
![textInput](https://orasund.github.io/elm-ui-widgets/assets/textInput.png)
|
||||||
@ -172,6 +180,7 @@ import Internal.PasswordInput as PasswordInput
|
|||||||
import Internal.ProgressIndicator as ProgressIndicator
|
import Internal.ProgressIndicator as ProgressIndicator
|
||||||
import Internal.Select as Select
|
import Internal.Select as Select
|
||||||
import Internal.SortTable as SortTable
|
import Internal.SortTable as SortTable
|
||||||
|
import Internal.SortTableV2 as SortTableV2
|
||||||
import Internal.Switch as Switch
|
import Internal.Switch as Switch
|
||||||
import Internal.Tab as Tab
|
import Internal.Tab as Tab
|
||||||
import Internal.TextInput as TextInput
|
import Internal.TextInput as TextInput
|
||||||
@ -1901,15 +1910,15 @@ type alias SortTableStyle msg =
|
|||||||
|
|
||||||
{-| Column for the Sort Table widget type
|
{-| Column for the Sort Table widget type
|
||||||
-}
|
-}
|
||||||
type alias Column a msg =
|
type alias Column a =
|
||||||
SortTable.Column a msg
|
SortTable.Column a
|
||||||
|
|
||||||
|
|
||||||
{-| Sort Table widget type
|
{-| Sort Table widget type
|
||||||
-}
|
-}
|
||||||
type alias SortTable a msg =
|
type alias SortTable a msg =
|
||||||
{ content : List a
|
{ content : List a
|
||||||
, columns : List (Column a msg)
|
, columns : List (Column a)
|
||||||
, sortBy : String
|
, sortBy : String
|
||||||
, asc : Bool
|
, asc : Bool
|
||||||
, onChange : String -> msg
|
, onChange : String -> msg
|
||||||
@ -1923,7 +1932,7 @@ unsortableColumn :
|
|||||||
, toString : a -> String
|
, toString : a -> String
|
||||||
, width : Length
|
, width : Length
|
||||||
}
|
}
|
||||||
-> Column a msg
|
-> Column a
|
||||||
unsortableColumn =
|
unsortableColumn =
|
||||||
SortTable.unsortableColumn
|
SortTable.unsortableColumn
|
||||||
|
|
||||||
@ -1936,7 +1945,7 @@ intColumn :
|
|||||||
, toString : Int -> String
|
, toString : Int -> String
|
||||||
, width : Length
|
, width : Length
|
||||||
}
|
}
|
||||||
-> Column a msg
|
-> Column a
|
||||||
intColumn =
|
intColumn =
|
||||||
SortTable.intColumn
|
SortTable.intColumn
|
||||||
|
|
||||||
@ -1949,7 +1958,7 @@ floatColumn :
|
|||||||
, toString : Float -> String
|
, toString : Float -> String
|
||||||
, width : Length
|
, width : Length
|
||||||
}
|
}
|
||||||
-> Column a msg
|
-> Column a
|
||||||
floatColumn =
|
floatColumn =
|
||||||
SortTable.floatColumn
|
SortTable.floatColumn
|
||||||
|
|
||||||
@ -1969,7 +1978,7 @@ stringColumn :
|
|||||||
, toString : String -> String
|
, toString : String -> String
|
||||||
, width : Length
|
, width : Length
|
||||||
}
|
}
|
||||||
-> Column a msg
|
-> Column a
|
||||||
stringColumn =
|
stringColumn =
|
||||||
SortTable.stringColumn
|
SortTable.stringColumn
|
||||||
|
|
||||||
@ -2033,7 +2042,7 @@ sortTable :
|
|||||||
SortTableStyle msg
|
SortTableStyle msg
|
||||||
->
|
->
|
||||||
{ content : List a
|
{ content : List a
|
||||||
, columns : List (Column a msg)
|
, columns : List (Column a)
|
||||||
, sortBy : String
|
, sortBy : String
|
||||||
, asc : Bool
|
, asc : Bool
|
||||||
, onChange : String -> msg
|
, onChange : String -> msg
|
||||||
@ -2049,6 +2058,189 @@ sortTable =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{----------------------------------------------------------
|
||||||
|
- SORT TABLE V2
|
||||||
|
----------------------------------------------------------}
|
||||||
|
|
||||||
|
|
||||||
|
{-| Column for the Sort Table V2 widget type
|
||||||
|
-}
|
||||||
|
type alias ColumnV2 a msg =
|
||||||
|
SortTableV2.ColumnV2 a msg
|
||||||
|
|
||||||
|
|
||||||
|
{-| Sort Table V2 widget type
|
||||||
|
-}
|
||||||
|
type alias SortTableV2 a msg =
|
||||||
|
{ content : List a
|
||||||
|
, columns : List (ColumnV2 a msg)
|
||||||
|
, sortBy : String
|
||||||
|
, asc : Bool
|
||||||
|
, onChange : String -> msg
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| An unsortable ColumnV2, when trying to sort by this column, nothing will change.
|
||||||
|
-}
|
||||||
|
unsortableColumnV2 :
|
||||||
|
{ title : String
|
||||||
|
, toString : a -> String
|
||||||
|
, width : Length
|
||||||
|
}
|
||||||
|
-> ColumnV2 a msg
|
||||||
|
unsortableColumnV2 =
|
||||||
|
SortTableV2.unsortableColumnV2
|
||||||
|
|
||||||
|
|
||||||
|
{-| A ColumnV2 containing a Int
|
||||||
|
-}
|
||||||
|
intColumnV2 :
|
||||||
|
{ title : String
|
||||||
|
, value : a -> Int
|
||||||
|
, toString : Int -> String
|
||||||
|
, width : Length
|
||||||
|
}
|
||||||
|
-> ColumnV2 a msg
|
||||||
|
intColumnV2 =
|
||||||
|
SortTableV2.intColumnV2
|
||||||
|
|
||||||
|
|
||||||
|
{-| A ColumnV2 containing a Float
|
||||||
|
-}
|
||||||
|
floatColumnV2 :
|
||||||
|
{ title : String
|
||||||
|
, value : a -> Float
|
||||||
|
, toString : Float -> String
|
||||||
|
, width : Length
|
||||||
|
}
|
||||||
|
-> ColumnV2 a msg
|
||||||
|
floatColumnV2 =
|
||||||
|
SortTableV2.floatColumnV2
|
||||||
|
|
||||||
|
|
||||||
|
{-| A ColumnV2 containing an Element
|
||||||
|
|
||||||
|
`value` will be used for displaying content.
|
||||||
|
|
||||||
|
This column is not sortable.
|
||||||
|
-}
|
||||||
|
customColumnV2 :
|
||||||
|
{ title : String
|
||||||
|
, value : a -> Element msg
|
||||||
|
, width : Length
|
||||||
|
}
|
||||||
|
-> ColumnV2 a msg
|
||||||
|
customColumnV2 =
|
||||||
|
SortTableV2.customColumnV2
|
||||||
|
|
||||||
|
|
||||||
|
{-| A ColumnV2 containing a String
|
||||||
|
|
||||||
|
`value >> toString` field will be used for displaying the content.
|
||||||
|
|
||||||
|
`value` will be used for comparing the content
|
||||||
|
|
||||||
|
For example `value = String.toLower` will make the sorting case-insensitive.
|
||||||
|
|
||||||
|
-}
|
||||||
|
stringColumnV2 :
|
||||||
|
{ title : String
|
||||||
|
, value : a -> String
|
||||||
|
, toString : String -> String
|
||||||
|
, width : Length
|
||||||
|
}
|
||||||
|
-> ColumnV2 a msg
|
||||||
|
stringColumnV2 =
|
||||||
|
SortTableV2.stringColumnV2
|
||||||
|
|
||||||
|
|
||||||
|
{-| A table where the rows can be sorted by columns
|
||||||
|
|
||||||
|
import Widget.Material as Material
|
||||||
|
import Element
|
||||||
|
|
||||||
|
type Msg
|
||||||
|
= ChangedSorting String
|
||||||
|
| PressedButton String
|
||||||
|
|
||||||
|
sortBy : String
|
||||||
|
sortBy =
|
||||||
|
"Id"
|
||||||
|
|
||||||
|
asc : Bool
|
||||||
|
asc =
|
||||||
|
True
|
||||||
|
|
||||||
|
Widget.sortTableV2 (Material.sortTable Material.defaultPalette)
|
||||||
|
{ content =
|
||||||
|
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||||
|
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||||
|
, { id = 3, name = "Alfred", rating = 4.22, hash = Just "6fs1" }
|
||||||
|
, { id = 4, name = "Thomas", rating = 3, hash = Just "k52f" }
|
||||||
|
]
|
||||||
|
, columns =
|
||||||
|
[ Widget.intColumnV2
|
||||||
|
{ title = "Id"
|
||||||
|
, value = .id
|
||||||
|
, toString = \int -> "#" ++ String.fromInt int
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.stringColumnV2
|
||||||
|
{ title = "Name"
|
||||||
|
, value = .name
|
||||||
|
, toString = identity
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.floatColumnV2
|
||||||
|
{ title = "Rating"
|
||||||
|
, value = .rating
|
||||||
|
, toString = String.fromFloat
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.customColumnV2
|
||||||
|
{ title = "Action"
|
||||||
|
, value =
|
||||||
|
\{name} ->
|
||||||
|
Widget.textButton
|
||||||
|
(Material.textButton Material.defaultPalette)
|
||||||
|
{ text = name
|
||||||
|
, onPress = Just <| PressedButton name
|
||||||
|
}
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
, Widget.unsortableColumnV2
|
||||||
|
{ title = "Hash"
|
||||||
|
, toString = (\{hash} -> hash |> Maybe.withDefault "None")
|
||||||
|
, width = Element.fill
|
||||||
|
}
|
||||||
|
]
|
||||||
|
, asc = asc
|
||||||
|
, sortBy = sortBy
|
||||||
|
, onChange = ChangedSorting
|
||||||
|
}
|
||||||
|
|> always "Ignore this line" --> "Ignore this line"
|
||||||
|
|
||||||
|
-}
|
||||||
|
sortTableV2 :
|
||||||
|
SortTableStyle msg
|
||||||
|
->
|
||||||
|
{ content : List a
|
||||||
|
, columns : List (ColumnV2 a msg)
|
||||||
|
, sortBy : String
|
||||||
|
, asc : Bool
|
||||||
|
, onChange : String -> msg
|
||||||
|
}
|
||||||
|
-> Element msg
|
||||||
|
sortTableV2 =
|
||||||
|
let
|
||||||
|
fun : SortTableStyle msg -> SortTableV2 a msg -> Element msg
|
||||||
|
fun =
|
||||||
|
SortTableV2.sortTableV2
|
||||||
|
in
|
||||||
|
fun
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{----------------------------------------------------------
|
{----------------------------------------------------------
|
||||||
- TAB
|
- TAB
|
||||||
----------------------------------------------------------}
|
----------------------------------------------------------}
|
||||||
|
Loading…
Reference in New Issue
Block a user