mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-21 18:05:00 +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.Snackbar
|
||||
import Page.SortTable
|
||||
import Page.SortTableV2
|
||||
import Page.Switch
|
||||
import Page.Tab
|
||||
import Page.TextInput
|
||||
@ -29,6 +30,7 @@ pages =
|
||||
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|
||||
|> UIExplorer.nextPage "Text Input" Page.TextInput.page
|
||||
|> UIExplorer.nextPage "Sort Table" Page.SortTable.page
|
||||
|> UIExplorer.nextPage "Sort Table V2" Page.SortTableV2.page
|
||||
|> UIExplorer.nextPage "Snackbar" Page.Snackbar.page
|
||||
|> UIExplorer.nextPage "Item" Page.Item.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.
|
||||
-}
|
||||
type ColumnType a msg
|
||||
type ColumnType a
|
||||
= StringColumn { value : a -> String, toString : String -> String }
|
||||
| IntColumn { value : a -> Int, toString : Int -> String }
|
||||
| FloatColumn { value : a -> Float, toString : Float -> String }
|
||||
| ElementColumn { value : a -> Element msg }
|
||||
| UnsortableColumn (a -> String)
|
||||
|
||||
|
||||
@ -46,22 +45,22 @@ type ColumnType a msg
|
||||
-}
|
||||
type alias SortTable a msg =
|
||||
{ content : List a
|
||||
, columns : List (Column a msg)
|
||||
, columns : List (Column a)
|
||||
, sortBy : String
|
||||
, asc : Bool
|
||||
, onChange : String -> msg
|
||||
}
|
||||
|
||||
|
||||
type Column a msg
|
||||
type Column a
|
||||
= Column
|
||||
{ title : String
|
||||
, content : ColumnType a msg
|
||||
, content : ColumnType a
|
||||
, 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 } =
|
||||
Column
|
||||
{ title = title
|
||||
@ -72,7 +71,7 @@ unsortableColumn { title, toString, width } =
|
||||
|
||||
{-| 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 } =
|
||||
Column
|
||||
{ title = title
|
||||
@ -83,7 +82,7 @@ intColumn { title, value, toString, width } =
|
||||
|
||||
{-| 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 } =
|
||||
Column
|
||||
{ title = title
|
||||
@ -94,7 +93,7 @@ floatColumn { title, value, toString, width } =
|
||||
|
||||
{-| 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 } =
|
||||
Column
|
||||
{ title = title
|
||||
@ -111,7 +110,7 @@ sortTable :
|
||||
-> Element msg
|
||||
sortTable style model =
|
||||
let
|
||||
findTitle : List (Column a msg) -> Maybe (ColumnType a msg)
|
||||
findTitle : List (Column a) -> Maybe (ColumnType a)
|
||||
findTitle list =
|
||||
case list of
|
||||
[] ->
|
||||
@ -141,9 +140,6 @@ sortTable style model =
|
||||
FloatColumn { value } ->
|
||||
Just <| List.sortBy value
|
||||
|
||||
ElementColumn _ ->
|
||||
Nothing
|
||||
|
||||
UnsortableColumn _ ->
|
||||
Nothing
|
||||
)
|
||||
@ -184,20 +180,18 @@ sortTable style model =
|
||||
, view =
|
||||
(case column.content of
|
||||
IntColumn { value, toString } ->
|
||||
value >> toString >> Element.text
|
||||
value >> toString
|
||||
|
||||
FloatColumn { value, toString } ->
|
||||
value >> toString >> Element.text
|
||||
value >> toString
|
||||
|
||||
StringColumn { value, toString } ->
|
||||
value >> toString >> Element.text
|
||||
|
||||
ElementColumn { value } ->
|
||||
value
|
||||
value >> toString
|
||||
|
||||
UnsortableColumn toString ->
|
||||
toString >> Element.text
|
||||
toString
|
||||
)
|
||||
>> Element.text
|
||||
>> List.singleton
|
||||
>> 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
|
||||
, AppBarStyle, menuBar, tabBar
|
||||
, SortTableStyle, SortTable, Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
||||
, SortTableV2, ColumnV2, sortTableV2, floatColumnV2, intColumnV2, stringColumnV2, unsortableColumnV2, customColumnV2
|
||||
, TextInputStyle, TextInput, textInput, usernameInput, emailInput, searchInput, spellCheckedInput
|
||||
, PasswordInputStyle, PasswordInput, newPasswordInputV2, currentPasswordInputV2
|
||||
, 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
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
![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.Select as Select
|
||||
import Internal.SortTable as SortTable
|
||||
import Internal.SortTableV2 as SortTableV2
|
||||
import Internal.Switch as Switch
|
||||
import Internal.Tab as Tab
|
||||
import Internal.TextInput as TextInput
|
||||
@ -1901,15 +1910,15 @@ type alias SortTableStyle msg =
|
||||
|
||||
{-| Column for the Sort Table widget type
|
||||
-}
|
||||
type alias Column a msg =
|
||||
SortTable.Column a msg
|
||||
type alias Column a =
|
||||
SortTable.Column a
|
||||
|
||||
|
||||
{-| Sort Table widget type
|
||||
-}
|
||||
type alias SortTable a msg =
|
||||
{ content : List a
|
||||
, columns : List (Column a msg)
|
||||
, columns : List (Column a)
|
||||
, sortBy : String
|
||||
, asc : Bool
|
||||
, onChange : String -> msg
|
||||
@ -1923,7 +1932,7 @@ unsortableColumn :
|
||||
, toString : a -> String
|
||||
, width : Length
|
||||
}
|
||||
-> Column a msg
|
||||
-> Column a
|
||||
unsortableColumn =
|
||||
SortTable.unsortableColumn
|
||||
|
||||
@ -1936,7 +1945,7 @@ intColumn :
|
||||
, toString : Int -> String
|
||||
, width : Length
|
||||
}
|
||||
-> Column a msg
|
||||
-> Column a
|
||||
intColumn =
|
||||
SortTable.intColumn
|
||||
|
||||
@ -1949,7 +1958,7 @@ floatColumn :
|
||||
, toString : Float -> String
|
||||
, width : Length
|
||||
}
|
||||
-> Column a msg
|
||||
-> Column a
|
||||
floatColumn =
|
||||
SortTable.floatColumn
|
||||
|
||||
@ -1969,7 +1978,7 @@ stringColumn :
|
||||
, toString : String -> String
|
||||
, width : Length
|
||||
}
|
||||
-> Column a msg
|
||||
-> Column a
|
||||
stringColumn =
|
||||
SortTable.stringColumn
|
||||
|
||||
@ -2033,7 +2042,7 @@ sortTable :
|
||||
SortTableStyle msg
|
||||
->
|
||||
{ content : List a
|
||||
, columns : List (Column a msg)
|
||||
, columns : List (Column a)
|
||||
, sortBy : String
|
||||
, asc : Bool
|
||||
, 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
|
||||
----------------------------------------------------------}
|
||||
|
Loading…
Reference in New Issue
Block a user