mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-22 22:33:33 +03:00
Started with Material Design
This commit is contained in:
parent
bc2c86257f
commit
308a049613
8
elm.json
8
elm.json
@ -5,12 +5,10 @@
|
||||
"license": "BSD-3-Clause",
|
||||
"version": "1.0.0",
|
||||
"exposed-modules": [
|
||||
"Widget",
|
||||
"Widget.FilterSelect",
|
||||
"Widget.ValidatedInput",
|
||||
"Widget.Layout",
|
||||
"Widget.Style",
|
||||
"Widget.ScrollingNav",
|
||||
"Widget.Snackbar",
|
||||
"Widget.SortTable"
|
||||
"Widget.Snackbar"
|
||||
],
|
||||
"elm-version": "0.19.0 <= v < 0.20.0",
|
||||
"dependencies": {
|
||||
|
@ -8,6 +8,7 @@
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"Orasund/elm-ui-framework": "1.6.1",
|
||||
"avh4/elm-color": "1.0.0",
|
||||
"elm/browser": "1.0.2",
|
||||
"elm/core": "1.0.5",
|
||||
"elm/html": "1.0.0",
|
||||
@ -17,14 +18,17 @@
|
||||
"feathericons/elm-feather": "1.4.0",
|
||||
"jasonliang512/elm-heroicons": "1.0.2",
|
||||
"mdgriffith/elm-ui": "1.1.5",
|
||||
"noahzgordon/elm-color-extra": "1.0.2",
|
||||
"ryannhg/elm-spa": "4.1.0",
|
||||
"turboMaCk/queue": "1.0.2",
|
||||
"wernerdegroot/listzipper": "4.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/json": "1.1.3",
|
||||
"elm/regex": "1.0.0",
|
||||
"elm/url": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.2"
|
||||
"elm/virtual-dom": "1.0.2",
|
||||
"fredcy/elm-parseint": "2.0.1"
|
||||
}
|
||||
},
|
||||
"test-dependencies": {
|
||||
|
@ -3,10 +3,15 @@ module Data.Example exposing (Model, Msg, init, subscriptions, toCardList, updat
|
||||
import Data.Style exposing (Style)
|
||||
import Element exposing (Element)
|
||||
import Example.Button as Button
|
||||
import Example.Dialog as Dialog
|
||||
import Example.ExpansionPanel as ExpansionPanel
|
||||
import Example.List as List
|
||||
import Example.Modal as Modal
|
||||
import Example.MultiSelect as MultiSelect
|
||||
import Example.Select as Select
|
||||
import Example.SortTable as SortTable
|
||||
import Example.Tab as Tab
|
||||
import Example.TextInput as TextInput
|
||||
import Framework.Grid as Grid
|
||||
import View.Test as Test
|
||||
|
||||
@ -17,6 +22,11 @@ type Msg
|
||||
| MultiSelect MultiSelect.Msg
|
||||
| ExpansionPanel ExpansionPanel.Msg
|
||||
| Tab Tab.Msg
|
||||
| SortTable SortTable.Msg
|
||||
| Modal Modal.Msg
|
||||
| Dialog Dialog.Msg
|
||||
| TextInput TextInput.Msg
|
||||
| List List.Msg
|
||||
|
||||
|
||||
type alias Model =
|
||||
@ -25,6 +35,34 @@ type alias Model =
|
||||
, multiSelect : MultiSelect.Model
|
||||
, expansionPanel : ExpansionPanel.Model
|
||||
, tab : Tab.Model
|
||||
, sortTable : SortTable.Model
|
||||
, modal : Modal.Model
|
||||
, dialog : Dialog.Model
|
||||
, textInput : TextInput.Model
|
||||
, list : List.Model
|
||||
}
|
||||
|
||||
|
||||
type alias UpgradeRecord model msg =
|
||||
{ from : Model -> model
|
||||
, to : Model -> model -> Model
|
||||
, msgMapper : msg -> Msg
|
||||
, updateFun : msg -> model -> ( model, Cmd msg )
|
||||
, subscriptionsFun : model -> Sub msg
|
||||
}
|
||||
|
||||
|
||||
type alias UpgradeCollection =
|
||||
{ button : UpgradeRecord Button.Model Button.Msg
|
||||
, select : UpgradeRecord Select.Model Select.Msg
|
||||
, multiSelect : UpgradeRecord MultiSelect.Model MultiSelect.Msg
|
||||
, expansionPanel : UpgradeRecord ExpansionPanel.Model ExpansionPanel.Msg
|
||||
, tab : UpgradeRecord Tab.Model Tab.Msg
|
||||
, sortTable : UpgradeRecord SortTable.Model SortTable.Msg
|
||||
, modal : UpgradeRecord Modal.Model Modal.Msg
|
||||
, dialog : UpgradeRecord Dialog.Model Dialog.Msg
|
||||
, textInput : UpgradeRecord TextInput.Model TextInput.Msg
|
||||
, list : UpgradeRecord List.Model List.Msg
|
||||
}
|
||||
|
||||
|
||||
@ -45,63 +83,175 @@ init =
|
||||
|
||||
( tabModel, tabMsg ) =
|
||||
Tab.init
|
||||
|
||||
( sortTableModel, sortTableMsg ) =
|
||||
SortTable.init
|
||||
|
||||
( modalModel, modalMsg ) =
|
||||
Modal.init
|
||||
|
||||
( dialogModel, dialogMsg ) =
|
||||
Dialog.init
|
||||
|
||||
( textInputModel, textInputMsg ) =
|
||||
TextInput.init
|
||||
|
||||
( listModel, listMsg ) =
|
||||
List.init
|
||||
in
|
||||
( { button = buttonModel
|
||||
, select = selectModel
|
||||
, multiSelect = multiSelectModel
|
||||
, expansionPanel = expansionPanelModel
|
||||
, tab = tabModel
|
||||
, sortTable = sortTableModel
|
||||
, modal = modalModel
|
||||
, dialog = dialogModel
|
||||
, textInput = textInputModel
|
||||
, list = listModel
|
||||
}
|
||||
, [ Cmd.map Button buttonMsg
|
||||
, Cmd.map Select selectMsg
|
||||
, Cmd.map MultiSelect multiSelectMsg
|
||||
, Cmd.map ExpansionPanel expansionPanelMsg
|
||||
, Cmd.map Tab tabMsg
|
||||
, Cmd.map SortTable sortTableMsg
|
||||
, Cmd.map Modal modalMsg
|
||||
, Cmd.map Dialog dialogMsg
|
||||
, Cmd.map TextInput textInputMsg
|
||||
, Cmd.map List listMsg
|
||||
]
|
||||
|> Cmd.batch
|
||||
)
|
||||
|
||||
|
||||
upgradeRecord : UpgradeCollection
|
||||
upgradeRecord =
|
||||
{ button =
|
||||
{ from = .button
|
||||
, to = \model a -> { model | button = a }
|
||||
, msgMapper = Button
|
||||
, updateFun = Button.update
|
||||
, subscriptionsFun = Button.subscriptions
|
||||
}
|
||||
, select =
|
||||
{ from = .select
|
||||
, to = \model a -> { model | select = a }
|
||||
, msgMapper = Select
|
||||
, updateFun = Select.update
|
||||
, subscriptionsFun = Select.subscriptions
|
||||
}
|
||||
, multiSelect =
|
||||
{ from = .multiSelect
|
||||
, to = \model a -> { model | multiSelect = a }
|
||||
, msgMapper = MultiSelect
|
||||
, updateFun = MultiSelect.update
|
||||
, subscriptionsFun = MultiSelect.subscriptions
|
||||
}
|
||||
, expansionPanel =
|
||||
{ from = .expansionPanel
|
||||
, to = \model a -> { model | expansionPanel = a }
|
||||
, msgMapper = ExpansionPanel
|
||||
, updateFun = ExpansionPanel.update
|
||||
, subscriptionsFun = ExpansionPanel.subscriptions
|
||||
}
|
||||
, tab =
|
||||
{ from = .tab
|
||||
, to = \model a -> { model | tab = a }
|
||||
, msgMapper = Tab
|
||||
, updateFun = Tab.update
|
||||
, subscriptionsFun = Tab.subscriptions
|
||||
}
|
||||
, sortTable =
|
||||
{ from = .sortTable
|
||||
, to = \model a -> { model | sortTable = a }
|
||||
, msgMapper = SortTable
|
||||
, updateFun = SortTable.update
|
||||
, subscriptionsFun = SortTable.subscriptions
|
||||
}
|
||||
, modal =
|
||||
{ from = .modal
|
||||
, to = \model a -> { model | modal = a }
|
||||
, msgMapper = Modal
|
||||
, updateFun = Modal.update
|
||||
, subscriptionsFun = Modal.subscriptions
|
||||
}
|
||||
, dialog =
|
||||
{ from = .dialog
|
||||
, to = \model a -> { model | dialog = a }
|
||||
, msgMapper = Dialog
|
||||
, updateFun = Dialog.update
|
||||
, subscriptionsFun = Dialog.subscriptions
|
||||
}
|
||||
, textInput =
|
||||
{ from = .textInput
|
||||
, to = \model a -> { model | textInput = a }
|
||||
, msgMapper = TextInput
|
||||
, updateFun = TextInput.update
|
||||
, subscriptionsFun = TextInput.subscriptions
|
||||
}
|
||||
, list =
|
||||
{ from = .list
|
||||
, to = \model a -> { model | list = a }
|
||||
, msgMapper = List
|
||||
, updateFun = List.update
|
||||
, subscriptionsFun = List.subscriptions
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
Button buttonMsg ->
|
||||
Button.update buttonMsg model.button
|
||||
|> Tuple.mapBoth
|
||||
(\a -> { model | button = a })
|
||||
(Cmd.map Button)
|
||||
(case msg of
|
||||
Button m ->
|
||||
updateField .button m
|
||||
|
||||
Select selectMsg ->
|
||||
Select.update selectMsg model.select
|
||||
|> Tuple.mapBoth
|
||||
(\a -> { model | select = a })
|
||||
(Cmd.map Select)
|
||||
Select m ->
|
||||
updateField .select m
|
||||
|
||||
MultiSelect multiSelectMsg ->
|
||||
MultiSelect.update multiSelectMsg model.multiSelect
|
||||
|> Tuple.mapBoth
|
||||
(\a -> { model | multiSelect = a })
|
||||
(Cmd.map MultiSelect)
|
||||
MultiSelect m ->
|
||||
updateField .multiSelect m
|
||||
|
||||
ExpansionPanel expansionPanelMsg ->
|
||||
ExpansionPanel.update expansionPanelMsg model.expansionPanel
|
||||
|> Tuple.mapBoth
|
||||
(\a -> { model | expansionPanel = a })
|
||||
(Cmd.map ExpansionPanel)
|
||||
ExpansionPanel m ->
|
||||
updateField .expansionPanel m
|
||||
|
||||
Tab tabMsg ->
|
||||
Tab.update tabMsg model.tab
|
||||
|> Tuple.mapBoth
|
||||
(\a -> { model | tab = a })
|
||||
(Cmd.map Tab)
|
||||
Tab m ->
|
||||
updateField .tab m
|
||||
|
||||
SortTable m ->
|
||||
updateField .sortTable m
|
||||
|
||||
Modal m ->
|
||||
updateField .modal m
|
||||
|
||||
Dialog m ->
|
||||
updateField .dialog m
|
||||
|
||||
TextInput m ->
|
||||
updateField .textInput m
|
||||
|
||||
List m ->
|
||||
updateField .list m
|
||||
)
|
||||
model
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
[ Button.subscriptions model.button |> Sub.map Button
|
||||
, Select.subscriptions model.select |> Sub.map Select
|
||||
, MultiSelect.subscriptions model.multiSelect |> Sub.map MultiSelect
|
||||
, ExpansionPanel.subscriptions model.expansionPanel |> Sub.map ExpansionPanel
|
||||
, Tab.subscriptions model.tab |> Sub.map Tab
|
||||
let
|
||||
subFun { from, msgMapper, subscriptionsFun } =
|
||||
subscriptionsFun (from model) |> Sub.map msgMapper
|
||||
in
|
||||
[ upgradeRecord.button |> subFun
|
||||
, upgradeRecord.select |> subFun
|
||||
, upgradeRecord.multiSelect |> subFun
|
||||
, upgradeRecord.expansionPanel |> subFun
|
||||
, upgradeRecord.tab |> subFun
|
||||
, upgradeRecord.sortTable |> subFun
|
||||
, upgradeRecord.modal |> subFun
|
||||
, upgradeRecord.dialog |> subFun
|
||||
, upgradeRecord.textInput |> subFun
|
||||
, upgradeRecord.list |> subFun
|
||||
]
|
||||
|> Sub.batch
|
||||
|
||||
@ -116,33 +266,33 @@ view :
|
||||
, multiSelect : Element msg
|
||||
, expansionPanel : Element msg
|
||||
, tab : Element msg
|
||||
, sortTable : Element msg
|
||||
, modal : Element msg
|
||||
, dialog : Element msg
|
||||
, textInput : Element msg
|
||||
, list : Element msg
|
||||
}
|
||||
view msgMapper style model =
|
||||
{ button =
|
||||
Button.view
|
||||
(Button >> msgMapper)
|
||||
style
|
||||
model.button
|
||||
Button.view (Button >> msgMapper) style (.button model)
|
||||
, select =
|
||||
Select.view
|
||||
(Select >> msgMapper)
|
||||
style
|
||||
model.select
|
||||
Select.view (Select >> msgMapper) style (.select model)
|
||||
, multiSelect =
|
||||
MultiSelect.view
|
||||
(MultiSelect >> msgMapper)
|
||||
style
|
||||
model.multiSelect
|
||||
MultiSelect.view (MultiSelect >> msgMapper) style (.multiSelect model)
|
||||
, expansionPanel =
|
||||
ExpansionPanel.view
|
||||
(ExpansionPanel >> msgMapper)
|
||||
style
|
||||
model.expansionPanel
|
||||
ExpansionPanel.view (ExpansionPanel >> msgMapper) style (.expansionPanel model)
|
||||
, tab =
|
||||
Tab.view
|
||||
(Tab >> msgMapper)
|
||||
style
|
||||
model.tab
|
||||
Tab.view (Tab >> msgMapper) style (.tab model)
|
||||
, sortTable =
|
||||
SortTable.view (SortTable >> msgMapper) style (.sortTable model)
|
||||
, modal =
|
||||
Modal.view (Modal >> msgMapper) style (.modal model)
|
||||
, dialog =
|
||||
Dialog.view (Dialog >> msgMapper) style (.dialog model)
|
||||
, textInput =
|
||||
TextInput.view (TextInput >> msgMapper) style (.textInput model)
|
||||
, list =
|
||||
List.view (List >> msgMapper) style (.list model)
|
||||
}
|
||||
|
||||
|
||||
@ -154,9 +304,9 @@ toCardList :
|
||||
}
|
||||
-> List ( String, Element msg, Element msg )
|
||||
toCardList { idle, msgMapper, style, model } =
|
||||
[ { title = "Icon Button"
|
||||
[ { title = "Button"
|
||||
, example = .button
|
||||
, test = Test.iconButton
|
||||
, test = Test.button
|
||||
}
|
||||
, { title = "Select"
|
||||
, example = .select
|
||||
@ -174,7 +324,28 @@ toCardList { idle, msgMapper, style, model } =
|
||||
, example = .tab
|
||||
, test = Test.tab
|
||||
}
|
||||
, { title = "Sort Table"
|
||||
, example = .sortTable
|
||||
, test = Test.sortTable
|
||||
}
|
||||
, { title = "Modal"
|
||||
, example = .modal
|
||||
, test = Test.modal
|
||||
}
|
||||
, { title = "Dialog"
|
||||
, example = .dialog
|
||||
, test = Test.dialog
|
||||
}
|
||||
, { title = "Text Input"
|
||||
, example = .textInput
|
||||
, test = Test.textInput
|
||||
}
|
||||
, { title = "List"
|
||||
, example = .list
|
||||
, test = Test.list
|
||||
}
|
||||
]
|
||||
|> List.sortBy .title
|
||||
|> List.map
|
||||
(\{ title, example, test } ->
|
||||
( title
|
||||
@ -182,6 +353,39 @@ toCardList { idle, msgMapper, style, model } =
|
||||
|> view msgMapper style
|
||||
|> example
|
||||
, test idle style
|
||||
|> Element.column Grid.simple
|
||||
|> List.map
|
||||
(\( name, elem ) ->
|
||||
Element.row Grid.spacedEvenly
|
||||
[ name
|
||||
|> Element.text
|
||||
|> List.singleton
|
||||
|> Element.wrappedRow [ Element.width <| Element.shrink ]
|
||||
, elem
|
||||
|> Element.el [ Element.width <| Element.shrink ]
|
||||
]
|
||||
)
|
||||
|> Element.column
|
||||
(Grid.simple
|
||||
++ [ Element.width <| Element.fill ]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------}
|
||||
|
||||
|
||||
updateField :
|
||||
(UpgradeCollection -> UpgradeRecord model msg)
|
||||
-> msg
|
||||
-> Model
|
||||
-> ( Model, Cmd Msg )
|
||||
updateField getter msg model =
|
||||
let
|
||||
{ from, to, msgMapper, updateFun } =
|
||||
getter upgradeRecord
|
||||
in
|
||||
updateFun msg (from model)
|
||||
|> Tuple.mapBoth (to model) (Cmd.map msgMapper)
|
||||
|
@ -1,8 +1,17 @@
|
||||
module Data.Style exposing (Style)
|
||||
|
||||
import Element exposing (Attribute)
|
||||
import Widget.Style exposing (ButtonStyle, DialogStyle, ExpansionPanelStyle,
|
||||
SnackbarStyle ,RowStyle,ColumnStyle,TextInputStyle,TabStyle)
|
||||
import Widget.Style
|
||||
exposing
|
||||
( ButtonStyle
|
||||
, ColumnStyle
|
||||
, DialogStyle
|
||||
, ExpansionPanelStyle
|
||||
, RowStyle
|
||||
, SortTableStyle
|
||||
, TabStyle
|
||||
, TextInputStyle
|
||||
)
|
||||
|
||||
|
||||
type alias Style msg =
|
||||
Widget.Style.Style
|
||||
@ -16,5 +25,6 @@ type alias Style msg =
|
||||
, row : RowStyle msg
|
||||
, column : ColumnStyle msg
|
||||
, cardColumn : ColumnStyle msg
|
||||
, sortTable : SortTableStyle msg
|
||||
}
|
||||
msg
|
@ -1,9 +1,9 @@
|
||||
module Data.Style.ElmUiFramework exposing (style)
|
||||
|
||||
import Element exposing (Attribute)
|
||||
import Data.Style exposing (Style)
|
||||
import Element
|
||||
import Element.Border as Border
|
||||
import Element.Font as Font
|
||||
import Element.Input as Input
|
||||
import Framework
|
||||
import Framework.Button as Button
|
||||
import Framework.Card as Card
|
||||
@ -11,12 +11,21 @@ import Framework.Color as Color
|
||||
import Framework.Grid as Grid
|
||||
import Framework.Group as Group
|
||||
import Framework.Heading as Heading
|
||||
import Framework.Input as Input
|
||||
import Framework.Tag as Tag
|
||||
import Icons
|
||||
import Data.Style exposing (Style)
|
||||
import Widget.Style exposing (ButtonStyle, DialogStyle, ExpansionPanelStyle,
|
||||
SnackbarStyle ,RowStyle,ColumnStyle,TextInputStyle,TabStyle)
|
||||
import Widget.Style
|
||||
exposing
|
||||
( ButtonStyle
|
||||
, ColumnStyle
|
||||
, DialogStyle
|
||||
, ExpansionPanelStyle
|
||||
, RowStyle
|
||||
, SnackbarStyle
|
||||
, SortTableStyle
|
||||
, TabStyle
|
||||
, TextInputStyle
|
||||
)
|
||||
|
||||
|
||||
textButton : ButtonStyle msg
|
||||
textButton =
|
||||
@ -24,6 +33,7 @@ textButton =
|
||||
, labelRow = Grid.simple
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +43,7 @@ simpleButton =
|
||||
, labelRow = Grid.simple
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -57,6 +68,7 @@ menuTabButton =
|
||||
, labelRow = Grid.simple
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = [ Border.color Color.turquoise ]
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -66,6 +78,7 @@ menuButton =
|
||||
, container = Button.simple ++ Group.center ++ Color.dark
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -79,6 +92,7 @@ sheetButton =
|
||||
, labelRow = Grid.simple
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -88,6 +102,7 @@ buttonStyle =
|
||||
, container = Button.simple
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -97,6 +112,7 @@ snackbarButton =
|
||||
, container = Button.simple ++ Color.dark
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
@ -106,8 +122,10 @@ tabButtonStyle =
|
||||
, container = Button.simple ++ Group.top
|
||||
, ifDisabled = Color.disabled
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
textInputStyle : TextInputStyle msg
|
||||
textInputStyle =
|
||||
{ chipButton = chipButtonStyle
|
||||
@ -143,20 +161,21 @@ chipButtonStyle =
|
||||
, ifDisabled = []
|
||||
, labelRow = Grid.simple
|
||||
, ifActive = Color.primary
|
||||
, otherwise = []
|
||||
}
|
||||
|
||||
|
||||
expansionPanelStyle : ExpansionPanelStyle msg
|
||||
expansionPanelStyle =
|
||||
{ containerColumn = Card.simple ++ Grid.simple ++ [Element.height <| Element.shrink]
|
||||
, panelRow = Grid.spacedEvenly ++ [Element.height <| Element.shrink]
|
||||
, labelRow = Grid.simple ++ [Element.height <| Element.shrink]
|
||||
{ containerColumn = Card.simple ++ Grid.simple ++ [ Element.height <| Element.shrink ]
|
||||
, panelRow = Grid.spacedEvenly ++ [ Element.height <| Element.shrink ]
|
||||
, labelRow = Grid.simple ++ [ Element.height <| Element.shrink ]
|
||||
, content = []
|
||||
, expandIcon = Icons.chevronDown |> Element.html |> Element.el []
|
||||
, collapseIcon = Icons.chevronUp |> Element.html |> Element.el []
|
||||
}
|
||||
|
||||
|
||||
|
||||
dialog : DialogStyle msg
|
||||
dialog =
|
||||
{ containerColumn =
|
||||
@ -179,6 +198,7 @@ dialog =
|
||||
, dismissButton = textButton
|
||||
}
|
||||
|
||||
|
||||
snackbar : SnackbarStyle msg
|
||||
snackbar =
|
||||
{ containerRow =
|
||||
@ -192,44 +212,60 @@ snackbar =
|
||||
, text = [ Element.paddingXY 8 0 ]
|
||||
}
|
||||
|
||||
|
||||
tab : TabStyle msg
|
||||
tab =
|
||||
{ button = tabButtonStyle
|
||||
, optionRow = Grid.simple
|
||||
, containerColumn = Grid.compact
|
||||
, content = (Card.small ++ Group.bottom)
|
||||
, content = Card.small ++ Group.bottom
|
||||
}
|
||||
|
||||
|
||||
row : RowStyle msg
|
||||
row =
|
||||
{ containerRow = Grid.compact
|
||||
, element = []
|
||||
, ifFirst = Group.left
|
||||
, ifLast = Group.right
|
||||
, ifCenter = Group.center
|
||||
, otherwise = Group.center
|
||||
}
|
||||
|
||||
|
||||
cardColumn : ColumnStyle msg
|
||||
cardColumn =
|
||||
{ containerColumn = Grid.compact ++ [Element.height <| Element.fill]
|
||||
, element = Card.large ++ [Element.height <| Element.fill]
|
||||
{ containerColumn = Grid.compact ++ [ Element.height <| Element.fill ]
|
||||
, element = Card.large ++ [ Element.height <| Element.fill ]
|
||||
, ifFirst = Group.top
|
||||
, ifLast = Group.bottom
|
||||
, ifCenter = Group.center
|
||||
, otherwise = Group.center
|
||||
}
|
||||
|
||||
|
||||
column : ColumnStyle msg
|
||||
column =
|
||||
{ containerColumn = Grid.compact
|
||||
, element = []
|
||||
, ifFirst = Group.top
|
||||
, ifLast = Group.bottom
|
||||
, ifCenter =Group.center
|
||||
, otherwise = Group.center
|
||||
}
|
||||
|
||||
|
||||
sortTable : SortTableStyle msg
|
||||
sortTable =
|
||||
{ containerTable = Grid.simple
|
||||
, headerButton = tabButtonStyle
|
||||
, ascIcon = Icons.chevronUp |> Element.html |> Element.el []
|
||||
, descIcon = Icons.chevronDown |> Element.html |> Element.el []
|
||||
, defaultIcon = Element.none
|
||||
}
|
||||
|
||||
|
||||
style : Style msg
|
||||
style =
|
||||
{ row = row
|
||||
{ sortTable = sortTable
|
||||
, row = row
|
||||
, cardColumn = cardColumn
|
||||
, column = column
|
||||
, button = buttonStyle
|
||||
|
393
example/src/Data/Style/Material.elm
Normal file
393
example/src/Data/Style/Material.elm
Normal file
@ -0,0 +1,393 @@
|
||||
module Data.Style.Material exposing (Palette, defaultPalette, style)
|
||||
|
||||
import Color exposing (Color)
|
||||
import Color.Accessibility as Accessibility
|
||||
import Color.Convert as Convert
|
||||
import Color.Manipulate as Manipulate
|
||||
import Data.Style exposing (Style)
|
||||
import Element exposing (Attribute, Element)
|
||||
import Element.Background as Background
|
||||
import Element.Border as Border
|
||||
import Element.Font as Font
|
||||
import Html.Attributes as Attributes
|
||||
import Widget.Style
|
||||
exposing
|
||||
( ButtonStyle
|
||||
, ColumnStyle
|
||||
, DialogStyle
|
||||
, ExpansionPanelStyle
|
||||
, RowStyle
|
||||
, SnackbarStyle
|
||||
, SortTableStyle
|
||||
, TabStyle
|
||||
, TextInputStyle
|
||||
)
|
||||
|
||||
|
||||
type alias Palette =
|
||||
{ primary : Color --Color.rgb255 0x62 0x00 0xEE
|
||||
, secondary : Color --Color.rgb255 0x03 0xda 0xc6
|
||||
, background : Color --Color.rgb255 0xFF 0xFF 0xFF
|
||||
, surface : Color --Color.rgb255 0xFF 0xFF 0xFF
|
||||
, error : Color --Color.rgb255 0xB0 0x00 0x20
|
||||
, on :
|
||||
{ primary : Color --Color.rgb255 0xFF 0xFF 0xFF
|
||||
, secondary : Color --Color.rgb255 0x00 0x00 0x00
|
||||
, background : Color --Color.rgb255 0x00 0x00 0x00
|
||||
, surface : Color --Color.rgb255 0x00 0x00 0x00
|
||||
, error : Color --Color.rgb255 0xFF 0xFF 0xFF
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
defaultPalette : Palette
|
||||
defaultPalette =
|
||||
{ primary = Color.rgb255 0x62 0x00 0xEE
|
||||
, secondary = Color.rgb255 0x03 0xDA 0xC6
|
||||
, background = Color.rgb255 0xFF 0xFF 0xFF
|
||||
, surface = Color.rgb255 0xFF 0xFF 0xFF
|
||||
, error = Color.rgb255 0xB0 0x00 0x20
|
||||
, on =
|
||||
{ primary = Color.rgb255 0xFF 0xFF 0xFF
|
||||
, secondary = Color.rgb255 0x00 0x00 0x00
|
||||
, background = Color.rgb255 0x00 0x00 0x00
|
||||
, surface = Color.rgb255 0x00 0x00 0x00
|
||||
, error = Color.rgb255 0xFF 0xFF 0xFF
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
accessibleTextColor : Color -> Color
|
||||
accessibleTextColor color =
|
||||
if (0.05 / (Accessibility.luminance color + 0.05)) < 7 then
|
||||
Color.rgb 255 255 255
|
||||
|
||||
else
|
||||
Color.rgb 0 0 0
|
||||
|
||||
|
||||
{-| using noahzgordon/elm-color-extra for colors
|
||||
-}
|
||||
withShade : Color -> Float -> Color -> Color
|
||||
withShade c2 amount c1 =
|
||||
let
|
||||
alpha = c1
|
||||
|> Color.toRgba |> .alpha
|
||||
|
||||
|
||||
toCIELCH =
|
||||
Convert.colorToLab
|
||||
>> (\{ l, a, b } ->
|
||||
{ l = l
|
||||
, c = sqrt (a * a + b * b)
|
||||
, h = atan2 b a
|
||||
}
|
||||
)
|
||||
|
||||
fromCIELCH =
|
||||
(\{ l, c, h } ->
|
||||
{ l = l
|
||||
, a = c * cos h
|
||||
, b = c * sin h
|
||||
}
|
||||
)
|
||||
>> Convert.labToColor
|
||||
|
||||
fun a b =
|
||||
{ l = (a.l * (1 - amount) + b.l * amount) / 1
|
||||
, c = (a.c * (1 - amount) + b.c * amount) / 1
|
||||
, h = (a.h * (1 - amount) + b.h * amount) / 1
|
||||
}
|
||||
in
|
||||
fun (toCIELCH c1) (toCIELCH c2)
|
||||
|> fromCIELCH
|
||||
|> Color.toRgba
|
||||
|> (\color -> { color | alpha = alpha })
|
||||
|> Color.fromRgba
|
||||
|
||||
scaleOpacity : Float -> Color -> Color
|
||||
scaleOpacity opacity =
|
||||
Color.toRgba
|
||||
>> (\color -> { color | alpha = color.alpha * opacity})
|
||||
>> Color.fromRgba
|
||||
|
||||
{-| hsl 265 100 47 (0% onColor)
|
||||
rgb 98 0 238
|
||||
-}
|
||||
primaryColor : Palette -> Color
|
||||
primaryColor { primary } =
|
||||
primary
|
||||
|
||||
|
||||
{-| hsl 265 75 59 (24% onColor)
|
||||
rgb 136 61 242
|
||||
-}
|
||||
primaryColorFocused : Palette -> Color
|
||||
primaryColorFocused {primary, on } =
|
||||
primary |> withShade on.primary 0.24
|
||||
|
||||
|
||||
|
||||
--Color.rgb255 0x87 0x3D 0xF2
|
||||
|
||||
|
||||
{-| hsl 265 92 51 (08% onColor)
|
||||
-}
|
||||
primaryColorHover : Palette -> Color
|
||||
primaryColorHover {primary, on } =
|
||||
primary |> withShade on.primary 0.08
|
||||
|
||||
|
||||
|
||||
--Color.rgb255 0x6E 0x14 0xEF
|
||||
|
||||
|
||||
{-| hsl 265 66 64 (32% onColor)
|
||||
-}
|
||||
primaryColorPressed : Palette -> Color
|
||||
primaryColorPressed {primary, on } =
|
||||
primary |> withShade on.primary 0.32
|
||||
|
||||
|
||||
|
||||
--Color.rgb255 0x94 0x52 0xF3
|
||||
|
||||
|
||||
primaryColorDisabled : Palette ->Color
|
||||
primaryColorDisabled {primary,on}=
|
||||
Color.rgb255 0x77 0x77 0x77 |> scaleOpacity 0.38
|
||||
|
||||
disabledFontColor : Color
|
||||
disabledFontColor =
|
||||
Color.rgb255 0x77 0x77 0x77--0x85 0x85 0x85
|
||||
|
||||
|
||||
shadow :
|
||||
Float
|
||||
->
|
||||
{ offset : ( Float, Float )
|
||||
, size : Float
|
||||
, blur : Float
|
||||
, color : Element.Color
|
||||
}
|
||||
shadow float =
|
||||
{ color = Element.rgba255 0x00 0x00 0x00 0.2
|
||||
, offset = ( 0, float )
|
||||
, size = 0
|
||||
, blur = float
|
||||
}
|
||||
|
||||
|
||||
primaryButton : Palette -> ButtonStyle msg
|
||||
primaryButton palette =
|
||||
{ container =
|
||||
[ Element.height <| Element.px 36
|
||||
, Element.width <| Element.minimum 64 <| Element.shrink
|
||||
, Border.rounded <| 4
|
||||
, Border.shadow <| shadow 2
|
||||
, Font.size 14
|
||||
, Font.medium
|
||||
, Font.letterSpacing 1.25
|
||||
, Element.htmlAttribute <| Attributes.style "text-transform" "uppercase"
|
||||
, Element.paddingXY 16 8
|
||||
, Element.mouseDown
|
||||
[ Background.color <| Element.fromRgb <| Color.toRgba <| primaryColorPressed palette
|
||||
, Font.color <| Element.fromRgb <| Color.toRgba <| accessibleTextColor <| primaryColorPressed palette
|
||||
, Border.shadow <| shadow 12
|
||||
]
|
||||
, Element.mouseOver
|
||||
[ Background.color <| Element.fromRgb <| Color.toRgba <| primaryColorHover palette
|
||||
, Font.color <| Element.fromRgb <| Color.toRgba <| accessibleTextColor <| primaryColorHover palette
|
||||
, Border.shadow <| shadow 6
|
||||
]
|
||||
, Element.focused
|
||||
[ Background.color <| Element.fromRgb <| Color.toRgba <| primaryColorFocused palette
|
||||
, Font.color <| Element.fromRgb <| Color.toRgba <| accessibleTextColor <| primaryColorFocused palette
|
||||
, Border.shadow <| shadow 6
|
||||
]
|
||||
]
|
||||
, labelRow =
|
||||
[ Element.spacing <| 8
|
||||
]
|
||||
, ifDisabled =
|
||||
[ Background.color <| Element.fromRgb <| Color.toRgba <| primaryColorDisabled palette
|
||||
, Font.color <| Element.fromRgb <| Color.toRgba <| disabledFontColor
|
||||
, Element.htmlAttribute <| Attributes.style "cursor" "not-allowed"
|
||||
, Element.mouseDown []
|
||||
, Element.mouseOver []
|
||||
, Element.focused []
|
||||
, Border.shadow <| shadow 0
|
||||
]
|
||||
, ifActive =
|
||||
[ Background.color <| Element.fromRgb <| Color.toRgba <| primaryColorFocused palette
|
||||
, Font.color <| Element.fromRgb <| Color.toRgba <| accessibleTextColor <| primaryColorHover palette
|
||||
]
|
||||
, otherwise =
|
||||
[ Background.color <| Element.fromRgb <| Color.toRgba <| primaryColor palette
|
||||
, Font.color <| Element.fromRgb <| Color.toRgba <| accessibleTextColor <| primaryColor palette
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
- Template
|
||||
-------------------------------------------------------------------------------}
|
||||
|
||||
|
||||
fontSize : Int
|
||||
fontSize =
|
||||
10
|
||||
|
||||
|
||||
box : String -> List (Attribute msg)
|
||||
box string =
|
||||
[ Border.width 1
|
||||
, Background.color <| Element.rgba 1 1 1 0.5
|
||||
, Element.padding 10
|
||||
, Element.spacing 10
|
||||
, Element.above <|
|
||||
Element.el [ Font.size <| fontSize ] <|
|
||||
Element.text string
|
||||
]
|
||||
|
||||
|
||||
decoration : String -> List (Attribute msg)
|
||||
decoration string =
|
||||
[ Element.below <|
|
||||
Element.el [ Font.size <| fontSize ] <|
|
||||
Element.text string
|
||||
, Background.color <| Element.rgb 0.66 0.66 0.66
|
||||
]
|
||||
|
||||
|
||||
icon : String -> Element msg
|
||||
icon string =
|
||||
Element.none
|
||||
|> Element.el
|
||||
[ Element.width <| Element.px 12
|
||||
, Element.height <| Element.px 12
|
||||
, Border.rounded 6
|
||||
, Border.width 1
|
||||
, Element.above <|
|
||||
Element.el [ Font.size <| fontSize ] <|
|
||||
Element.text string
|
||||
]
|
||||
|
||||
|
||||
button : String -> ButtonStyle msg
|
||||
button string =
|
||||
{ container = box <| string ++ ":container"
|
||||
, labelRow = box <| string ++ ":labelRow"
|
||||
, ifDisabled = decoration <| string ++ ":ifDisabled"
|
||||
, ifActive = decoration <| string ++ ":ifActive"
|
||||
, otherwise = box <| string ++ ":otherwise"
|
||||
}
|
||||
|
||||
|
||||
snackbar : String -> SnackbarStyle msg
|
||||
snackbar string =
|
||||
{ containerRow = box <| string ++ ":containerRow"
|
||||
, button = button <| string ++ ":button"
|
||||
, text = box <| string ++ ":text"
|
||||
}
|
||||
|
||||
|
||||
dialog : String -> DialogStyle msg
|
||||
dialog string =
|
||||
{ containerColumn = box <| string ++ ":containerColumn"
|
||||
, title = box <| string ++ ":title"
|
||||
, buttonRow = box <| string ++ ":buttonRow"
|
||||
, acceptButton = button <| string ++ ":acceptButton"
|
||||
, dismissButton = button <| string ++ ":dismissButton"
|
||||
}
|
||||
|
||||
|
||||
expansionPanel : String -> ExpansionPanelStyle msg
|
||||
expansionPanel string =
|
||||
{ containerColumn = box <| string ++ ":containerColumn"
|
||||
, panelRow = box <| string ++ ":panelRow"
|
||||
, labelRow = box <| string ++ ":labelRow"
|
||||
, content = box <| string ++ ":content"
|
||||
, expandIcon = icon <| string ++ ":expandIcon"
|
||||
, collapseIcon = icon <| string ++ ":collapseIcon"
|
||||
}
|
||||
|
||||
|
||||
textInput : String -> TextInputStyle msg
|
||||
textInput string =
|
||||
{ chipButton = button <| string ++ ":chipButton"
|
||||
, chipsRow = box <| string ++ ":chipsRow"
|
||||
, containerRow = box <| string ++ ":containerRow"
|
||||
, input = box <| string ++ ":input"
|
||||
}
|
||||
|
||||
|
||||
tab : String -> TabStyle msg
|
||||
tab string =
|
||||
{ button = button <| string ++ ":button"
|
||||
, optionRow = box <| string ++ ":optionRow"
|
||||
, containerColumn = box <| string ++ ":containerColumn"
|
||||
, content = box <| string ++ ":content"
|
||||
}
|
||||
|
||||
|
||||
row : String -> RowStyle msg
|
||||
row string =
|
||||
{ containerRow = box <| string ++ ":containerRow"
|
||||
, element = box <| string ++ ":element"
|
||||
, ifFirst = box <| string ++ ":ifFirst"
|
||||
, ifLast = box <| string ++ ":ifLast"
|
||||
, otherwise = box <| string ++ ":otherwise"
|
||||
}
|
||||
|
||||
|
||||
column : String -> ColumnStyle msg
|
||||
column string =
|
||||
{ containerColumn = box <| string ++ ":containerColumn"
|
||||
, element = box <| string ++ ":element"
|
||||
, ifFirst = box <| string ++ ":ifFirst"
|
||||
, ifLast = box <| string ++ ":ifLast"
|
||||
, otherwise = box <| string ++ ":otherwise"
|
||||
}
|
||||
|
||||
|
||||
sortTable : String -> SortTableStyle msg
|
||||
sortTable string =
|
||||
{ containerTable = box <| string ++ ":containerTable"
|
||||
, headerButton = button <| string ++ ":headerButton"
|
||||
, ascIcon = icon <| string ++ ":ascIcon"
|
||||
, descIcon = icon <| string ++ ":descIcon"
|
||||
, defaultIcon = icon <| string ++ ":defaultIcon"
|
||||
}
|
||||
|
||||
|
||||
style : Palette -> Style msg
|
||||
style palette =
|
||||
{ sortTable = sortTable <| "sortTable"
|
||||
, row = row <| "row"
|
||||
, cardColumn = column <| "cardRow"
|
||||
, column = column <| "column"
|
||||
, button = button <| "button"
|
||||
, primaryButton = primaryButton palette
|
||||
, tab = tab <| "tab"
|
||||
, textInput = textInput <| "textInput"
|
||||
, chipButton = button <| "chipButton"
|
||||
, expansionPanel = expansionPanel "expansionPanel"
|
||||
, dialog = dialog "dialog"
|
||||
, snackbar = snackbar "snackbar"
|
||||
, layout = Element.layout
|
||||
, header = box "header"
|
||||
, menuButton = button "menuButton"
|
||||
, sheetButton = button "sheetButton"
|
||||
, menuTabButton = button "menuTabButton"
|
||||
, sheet = box "sheet"
|
||||
, menuIcon = icon "menuIcon"
|
||||
, moreVerticalIcon = icon "moreVerticalIcon"
|
||||
, spacing = 8
|
||||
, title = box "title"
|
||||
, searchIcon = icon "searchIcon"
|
||||
, search = box "search"
|
||||
, searchFill = box "searchFill"
|
||||
}
|
@ -1,16 +1,28 @@
|
||||
module Data.Style.Template exposing (style)
|
||||
|
||||
import Data.Style exposing (Style)
|
||||
import Element exposing (Attribute,Element)
|
||||
import Element exposing (Attribute, Element)
|
||||
import Element.Background as Background
|
||||
import Element.Border as Border
|
||||
import Element.Font as Font
|
||||
import Element.Background as Background
|
||||
import Widget.Style exposing (ButtonStyle, DialogStyle, ExpansionPanelStyle,
|
||||
SnackbarStyle ,TextInputStyle,TabStyle,ColumnStyle,RowStyle)
|
||||
import Widget.Style
|
||||
exposing
|
||||
( ButtonStyle
|
||||
, ColumnStyle
|
||||
, DialogStyle
|
||||
, ExpansionPanelStyle
|
||||
, RowStyle
|
||||
, SnackbarStyle
|
||||
, TabStyle
|
||||
, TextInputStyle
|
||||
,SortTableStyle
|
||||
)
|
||||
|
||||
|
||||
fontSize : Int
|
||||
fontSize = 10
|
||||
fontSize =
|
||||
10
|
||||
|
||||
|
||||
box : String -> List (Attribute msg)
|
||||
box string =
|
||||
@ -19,14 +31,15 @@ box string =
|
||||
, Element.padding 10
|
||||
, Element.spacing 10
|
||||
, Element.above <|
|
||||
Element.el [Font.size <| fontSize] <|
|
||||
Element.el [ Font.size <| fontSize ] <|
|
||||
Element.text string
|
||||
]
|
||||
|
||||
|
||||
decoration : String -> List (Attribute msg)
|
||||
decoration string =
|
||||
[ Element.below <|
|
||||
Element.el [Font.size <| fontSize] <|
|
||||
Element.el [ Font.size <| fontSize ] <|
|
||||
Element.text string
|
||||
, Background.color <| Element.rgb 0.66 0.66 0.66
|
||||
]
|
||||
@ -41,18 +54,21 @@ icon string =
|
||||
, Border.rounded 6
|
||||
, Border.width 1
|
||||
, Element.above <|
|
||||
Element.el [Font.size <| fontSize] <|
|
||||
Element.el [ Font.size <| fontSize ] <|
|
||||
Element.text string
|
||||
]
|
||||
|
||||
|
||||
button : String -> ButtonStyle msg
|
||||
button string =
|
||||
{ container = box <| string ++ ":container"
|
||||
, labelRow = box <| string ++ ":labelRow"
|
||||
, ifDisabled = decoration <| string ++ ":ifDisabled"
|
||||
, ifActive = decoration <| string ++ ":ifActive"
|
||||
, otherwise = decoration <| string ++ ":otherwise"
|
||||
}
|
||||
|
||||
|
||||
snackbar : String -> SnackbarStyle msg
|
||||
snackbar string =
|
||||
{ containerRow = box <| string ++ ":containerRow"
|
||||
@ -60,6 +76,7 @@ snackbar string =
|
||||
, text = box <| string ++ ":text"
|
||||
}
|
||||
|
||||
|
||||
dialog : String -> DialogStyle msg
|
||||
dialog string =
|
||||
{ containerColumn = box <| string ++ ":containerColumn"
|
||||
@ -69,6 +86,7 @@ dialog string =
|
||||
, dismissButton = button <| string ++ ":dismissButton"
|
||||
}
|
||||
|
||||
|
||||
expansionPanel : String -> ExpansionPanelStyle msg
|
||||
expansionPanel string =
|
||||
{ containerColumn = box <| string ++ ":containerColumn"
|
||||
@ -79,6 +97,7 @@ expansionPanel string =
|
||||
, collapseIcon = icon <| string ++ ":collapseIcon"
|
||||
}
|
||||
|
||||
|
||||
textInput : String -> TextInputStyle msg
|
||||
textInput string =
|
||||
{ chipButton = button <| string ++ ":chipButton"
|
||||
@ -87,6 +106,7 @@ textInput string =
|
||||
, input = box <| string ++ ":input"
|
||||
}
|
||||
|
||||
|
||||
tab : String -> TabStyle msg
|
||||
tab string =
|
||||
{ button = button <| string ++ ":button"
|
||||
@ -95,27 +115,41 @@ tab string =
|
||||
, content = box <| string ++ ":content"
|
||||
}
|
||||
|
||||
|
||||
row : String -> RowStyle msg
|
||||
row string =
|
||||
{ containerRow = box <| string ++ ":containerRow"
|
||||
, element = box <| string ++ ":element"
|
||||
, ifFirst = box <| string ++ ":ifFirst"
|
||||
, ifLast = box <| string ++ ":ifLast"
|
||||
, ifCenter = box <| string ++ ":ifCenter"
|
||||
, otherwise = box <| string ++ ":otherwise"
|
||||
}
|
||||
|
||||
|
||||
column : String -> ColumnStyle msg
|
||||
column string =
|
||||
{ containerColumn = box <| string ++ ":containerColumn"
|
||||
, element = box <| string ++ ":element"
|
||||
, ifFirst = box <| string ++ ":ifFirst"
|
||||
, ifLast = box <| string ++ ":ifLast"
|
||||
, ifCenter = box <| string ++ ":ifCenter"
|
||||
, otherwise = box <| string ++ ":otherwise"
|
||||
}
|
||||
|
||||
style :Style msg
|
||||
|
||||
sortTable : String -> SortTableStyle msg
|
||||
sortTable string =
|
||||
{ containerTable = box <| string ++ ":containerTable"
|
||||
, headerButton = button <| string ++ ":headerButton"
|
||||
, ascIcon = icon <| string ++ ":ascIcon"
|
||||
, descIcon = icon <| string ++ ":descIcon"
|
||||
, defaultIcon = icon <| string ++ ":defaultIcon"
|
||||
}
|
||||
|
||||
|
||||
style : Style msg
|
||||
style =
|
||||
{ row = row <| "row"
|
||||
{ sortTable = sortTable <| "sortTable"
|
||||
, row = row <| "row"
|
||||
, cardColumn = column <| "cardRow"
|
||||
, column = column <| "column"
|
||||
, button = button <| "button"
|
||||
|
@ -1,17 +1,25 @@
|
||||
module Data.Theme exposing (Theme(..),toStyle)
|
||||
module Data.Theme exposing (Theme(..), toStyle)
|
||||
|
||||
import Data.Style exposing (Style)
|
||||
import Data.Style.ElmUiFramework
|
||||
import Data.Style.Material
|
||||
import Data.Style.Template
|
||||
|
||||
type Theme =
|
||||
ElmUiFramework
|
||||
|
||||
type Theme
|
||||
= ElmUiFramework
|
||||
| Template
|
||||
| Material
|
||||
|
||||
|
||||
toStyle : Theme -> Style msg
|
||||
toStyle theme =
|
||||
case theme of
|
||||
ElmUiFramework ->
|
||||
Data.Style.ElmUiFramework.style
|
||||
|
||||
Template ->
|
||||
Data.Style.Template.style
|
||||
|
||||
Material ->
|
||||
Data.Style.Material.style Data.Style.Material.defaultPalette
|
||||
|
@ -3,19 +3,19 @@ module Example.Button exposing (Model, Msg, init, subscriptions, update, view)
|
||||
import Element exposing (Element)
|
||||
import FeatherIcons
|
||||
import Widget
|
||||
import Widget.Style exposing (ButtonStyle)
|
||||
import Widget.Style exposing (ButtonStyle, RowStyle)
|
||||
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| primaryButton : ButtonStyle msg
|
||||
, button : ButtonStyle msg
|
||||
, row : RowStyle msg
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ isButtonEnabled : Bool
|
||||
}
|
||||
type Model
|
||||
= IsButtonEnabled Bool
|
||||
|
||||
|
||||
type Msg
|
||||
@ -24,17 +24,16 @@ type Msg
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { isButtonEnabled = True
|
||||
}
|
||||
( IsButtonEnabled True
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
update msg _ =
|
||||
case msg of
|
||||
ChangedButtonStatus bool ->
|
||||
( { model | isButtonEnabled = bool }
|
||||
( IsButtonEnabled bool
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@ -45,7 +44,7 @@ subscriptions _ =
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
view msgMapper style (IsButtonEnabled isButtonEnabled) =
|
||||
[ Widget.button style.primaryButton
|
||||
{ text = "disable me"
|
||||
, icon =
|
||||
@ -55,7 +54,7 @@ view msgMapper style model =
|
||||
|> Element.html
|
||||
|> Element.el []
|
||||
, onPress =
|
||||
if model.isButtonEnabled then
|
||||
if isButtonEnabled then
|
||||
ChangedButtonStatus False
|
||||
|> msgMapper
|
||||
|> Just
|
||||
@ -77,7 +76,4 @@ view msgMapper style model =
|
||||
|> Just
|
||||
}
|
||||
]
|
||||
|> Element.row
|
||||
[ Element.spaceEvenly
|
||||
, Element.width <| Element.fill
|
||||
]
|
||||
|> Widget.row style.row
|
||||
|
93
example/src/Example/Dialog.elm
Normal file
93
example/src/Example/Dialog.elm
Normal file
@ -0,0 +1,93 @@
|
||||
module Example.Dialog exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import FeatherIcons
|
||||
import Widget
|
||||
import Widget.Style exposing (ButtonStyle, DialogStyle)
|
||||
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| dialog : DialogStyle msg
|
||||
, primaryButton : ButtonStyle msg
|
||||
}
|
||||
|
||||
|
||||
type Model =
|
||||
IsOpen Bool
|
||||
|
||||
|
||||
type Msg
|
||||
= OpenDialog Bool
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( IsOpen True
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg _ =
|
||||
case msg of
|
||||
OpenDialog bool ->
|
||||
( IsOpen bool
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style (IsOpen isOpen) =
|
||||
Widget.button style.primaryButton
|
||||
{ text = "show Dialog"
|
||||
, icon =
|
||||
FeatherIcons.eye
|
||||
|> FeatherIcons.withSize 16
|
||||
|> FeatherIcons.toHtml []
|
||||
|> Element.html
|
||||
|> Element.el []
|
||||
, onPress =
|
||||
OpenDialog True
|
||||
|> msgMapper
|
||||
|> Just
|
||||
}
|
||||
|> Element.el
|
||||
([ Element.height <| Element.minimum 200 <| Element.fill
|
||||
, Element.width <| Element.minimum 400 <| Element.fill
|
||||
]
|
||||
++ (if isOpen then
|
||||
{ body =
|
||||
"This is a dialog window"
|
||||
|> Element.text
|
||||
|> List.singleton
|
||||
|> Element.paragraph []
|
||||
, title = Just "Dialog"
|
||||
, accept =
|
||||
Just
|
||||
{ text = "Ok"
|
||||
, onPress =
|
||||
Just <|
|
||||
msgMapper <|
|
||||
OpenDialog False
|
||||
}
|
||||
, dismiss =
|
||||
Just
|
||||
{ text = "Dismiss"
|
||||
, onPress =
|
||||
Just <|
|
||||
msgMapper <|
|
||||
OpenDialog False
|
||||
}
|
||||
}
|
||||
|> Widget.dialog style.dialog
|
||||
|
||||
else
|
||||
[]
|
||||
)
|
||||
)
|
@ -11,8 +11,8 @@ type alias Style style msg =
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ isExpanded : Bool }
|
||||
type Model
|
||||
= IsExpanded Bool
|
||||
|
||||
|
||||
type Msg
|
||||
@ -21,18 +21,16 @@ type Msg
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { isExpanded = False }
|
||||
( IsExpanded False
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
update msg _ =
|
||||
case msg of
|
||||
ToggleCollapsable bool ->
|
||||
( { model
|
||||
| isExpanded = bool
|
||||
}
|
||||
( IsExpanded bool
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@ -43,9 +41,9 @@ subscriptions _ =
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
view msgMapper style (IsExpanded isExpanded) =
|
||||
{ onToggle = ToggleCollapsable >> msgMapper
|
||||
, isExpanded = model.isExpanded
|
||||
, isExpanded = isExpanded
|
||||
, icon = Element.none
|
||||
, text = "Title"
|
||||
, content = Element.text <| "Hello World"
|
||||
|
47
example/src/Example/List.elm
Normal file
47
example/src/Example/List.elm
Normal file
@ -0,0 +1,47 @@
|
||||
module Example.List exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import Widget
|
||||
import Widget.Style exposing (ColumnStyle)
|
||||
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| cardColumn : ColumnStyle msg
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
()
|
||||
|
||||
|
||||
type alias Msg =
|
||||
Never
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( ()
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update _ () =
|
||||
( ()
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions () =
|
||||
Sub.none
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view _ style () =
|
||||
[ Element.text <| "A"
|
||||
, Element.text <| "B"
|
||||
, Element.text <| "C"
|
||||
]
|
||||
|> Widget.column style.cardColumn
|
88
example/src/Example/Modal.elm
Normal file
88
example/src/Example/Modal.elm
Normal file
@ -0,0 +1,88 @@
|
||||
module Example.Modal exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import FeatherIcons
|
||||
import Widget
|
||||
import Widget.Style exposing (ButtonStyle, ColumnStyle)
|
||||
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| cardColumn : ColumnStyle msg
|
||||
, primaryButton : ButtonStyle msg
|
||||
}
|
||||
|
||||
|
||||
type Model
|
||||
= IsEnabled Bool
|
||||
|
||||
|
||||
type Msg
|
||||
= ToggleModal Bool
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( IsEnabled True
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg _ =
|
||||
case msg of
|
||||
ToggleModal bool ->
|
||||
( IsEnabled bool
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style (IsEnabled isEnabled) =
|
||||
Widget.button style.primaryButton
|
||||
{ text = "show Modal"
|
||||
, icon =
|
||||
FeatherIcons.eye
|
||||
|> FeatherIcons.withSize 16
|
||||
|> FeatherIcons.toHtml []
|
||||
|> Element.html
|
||||
|> Element.el []
|
||||
, onPress =
|
||||
ToggleModal True
|
||||
|> msgMapper
|
||||
|> Just
|
||||
}
|
||||
|> Element.el
|
||||
([ Element.height <| Element.minimum 200 <| Element.fill
|
||||
, Element.width <| Element.minimum 400 <| Element.fill
|
||||
]
|
||||
++ (if isEnabled then
|
||||
Widget.modal
|
||||
{ onDismiss =
|
||||
ToggleModal False
|
||||
|> msgMapper
|
||||
|> Just
|
||||
, content =
|
||||
"Click on the area around this box to close it."
|
||||
|> Element.text
|
||||
|> List.singleton
|
||||
|> Element.paragraph []
|
||||
|> List.singleton
|
||||
|> Widget.column style.cardColumn
|
||||
|> Element.el
|
||||
[ Element.height <| Element.px 100
|
||||
, Element.width <| Element.px 250
|
||||
, Element.centerX
|
||||
, Element.centerY
|
||||
]
|
||||
}
|
||||
|
||||
else
|
||||
[]
|
||||
)
|
||||
)
|
@ -13,9 +13,8 @@ type alias Style style msg =
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ selected : Set Int
|
||||
}
|
||||
type Model
|
||||
= Selected (Set Int)
|
||||
|
||||
|
||||
type Msg
|
||||
@ -24,25 +23,23 @@ type Msg
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { selected = Set.empty }
|
||||
( Selected <| Set.empty
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
update msg (Selected selected) =
|
||||
case msg of
|
||||
ChangedSelected int ->
|
||||
( { model
|
||||
| selected =
|
||||
model.selected
|
||||
|> (if model.selected |> Set.member int then
|
||||
( selected
|
||||
|> (if selected |> Set.member int then
|
||||
Set.remove int
|
||||
|
||||
else
|
||||
Set.insert int
|
||||
)
|
||||
}
|
||||
|> Selected
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@ -53,8 +50,8 @@ subscriptions _ =
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
{ selected = model.selected
|
||||
view msgMapper style (Selected selected) =
|
||||
{ selected = selected
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
|> List.map
|
||||
|
@ -1,7 +1,6 @@
|
||||
module Example.Select exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Attribute, Element)
|
||||
import FeatherIcons
|
||||
import Element exposing (Element)
|
||||
import Widget
|
||||
import Widget.Style exposing (ButtonStyle, RowStyle)
|
||||
|
||||
@ -13,8 +12,8 @@ type alias Style style msg =
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ selected : Maybe Int }
|
||||
type Model
|
||||
= Selected (Maybe Int)
|
||||
|
||||
|
||||
type Msg
|
||||
@ -23,18 +22,16 @@ type Msg
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { selected = Nothing }
|
||||
( Selected Nothing
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
update msg _ =
|
||||
case msg of
|
||||
ChangedSelected int ->
|
||||
( { model
|
||||
| selected = Just int
|
||||
}
|
||||
( Selected <| Just int
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@ -45,8 +42,8 @@ subscriptions _ =
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
{ selected = model.selected
|
||||
view msgMapper style (Selected selected) =
|
||||
{ selected = selected
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
|> List.map
|
||||
|
89
example/src/Example/SortTable.elm
Normal file
89
example/src/Example/SortTable.elm
Normal file
@ -0,0 +1,89 @@
|
||||
module Example.SortTable exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import Widget
|
||||
import Widget.Style exposing (SortTableStyle)
|
||||
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| sortTable : SortTableStyle msg
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ title : String
|
||||
, asc : Bool
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ChangedSorting 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
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
Widget.sortTable style.sortTable
|
||||
{ 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.intColumn
|
||||
{ title = "Id"
|
||||
, value = .id
|
||||
, toString = \int -> "#" ++ String.fromInt int
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.stringColumn
|
||||
{ title = "Name"
|
||||
, value = .name
|
||||
, toString = identity
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.floatColumn
|
||||
{ title = "Rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.unsortableColumn
|
||||
{ title = "Hash"
|
||||
, toString = .hash >> Maybe.withDefault "None"
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = model.asc
|
||||
, sortBy = model.title
|
||||
, onChange = ChangedSorting >> msgMapper
|
||||
}
|
@ -11,9 +11,8 @@ type alias Style style msg =
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ selected : Maybe Int
|
||||
}
|
||||
type Model
|
||||
= Selected (Maybe Int)
|
||||
|
||||
|
||||
type Msg
|
||||
@ -22,17 +21,16 @@ type Msg
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { selected = Nothing
|
||||
}
|
||||
( Selected Nothing
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
update msg _ =
|
||||
case msg of
|
||||
ChangedTab int ->
|
||||
( { model | selected = Just int }
|
||||
( Selected <| Just int
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@ -43,10 +41,10 @@ subscriptions _ =
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
view msgMapper style (Selected selected) =
|
||||
Widget.tab style.tab
|
||||
{ tabs =
|
||||
{ selected = model.selected
|
||||
{ selected = selected
|
||||
, options =
|
||||
[ 1, 2, 3 ]
|
||||
|> List.map
|
||||
@ -58,8 +56,8 @@ view msgMapper style model =
|
||||
, onSelect = ChangedTab >> msgMapper >> Just
|
||||
}
|
||||
, content =
|
||||
\selected ->
|
||||
(case selected of
|
||||
\s ->
|
||||
(case s of
|
||||
Just 0 ->
|
||||
"This is Tab 1"
|
||||
|
||||
|
104
example/src/Example/TextInput.elm
Normal file
104
example/src/Example/TextInput.elm
Normal file
@ -0,0 +1,104 @@
|
||||
module Example.TextInput exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import Set exposing (Set)
|
||||
import Widget
|
||||
import Widget.Style exposing (ColumnStyle, TextInputStyle)
|
||||
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| textInput : TextInputStyle msg
|
||||
, column : ColumnStyle msg
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ chipTextInput : Set String
|
||||
, textInput : String
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ToggleTextInputChip String
|
||||
| SetTextInput String
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { chipTextInput = Set.empty
|
||||
, textInput = ""
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
ToggleTextInputChip string ->
|
||||
( { model
|
||||
| chipTextInput =
|
||||
model.chipTextInput
|
||||
|> (if model.chipTextInput |> Set.member string then
|
||||
Set.remove string
|
||||
|
||||
else
|
||||
Set.insert string
|
||||
)
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SetTextInput string ->
|
||||
( { model | textInput = string }, Cmd.none )
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
[ { chips =
|
||||
model.chipTextInput
|
||||
|> Set.toList
|
||||
|> List.map
|
||||
(\string ->
|
||||
{ icon = Element.none
|
||||
, text = string
|
||||
, onPress =
|
||||
string
|
||||
|> ToggleTextInputChip
|
||||
|> msgMapper
|
||||
|> Just
|
||||
}
|
||||
)
|
||||
, text = model.textInput
|
||||
, placeholder = Nothing
|
||||
, label = "Chips"
|
||||
, onChange = SetTextInput >> msgMapper
|
||||
}
|
||||
|> Widget.textInput style.textInput
|
||||
, model.chipTextInput
|
||||
|> Set.diff
|
||||
([ "A", "B", "C" ]
|
||||
|> Set.fromList
|
||||
)
|
||||
|> Set.toList
|
||||
|> List.map
|
||||
(\string ->
|
||||
Widget.button style.textInput.chipButton
|
||||
{ onPress =
|
||||
string
|
||||
|> ToggleTextInputChip
|
||||
|> msgMapper
|
||||
|> Just
|
||||
, text = string
|
||||
, icon = Element.none
|
||||
}
|
||||
)
|
||||
|> Element.wrappedRow [ Element.spacing 10 ]
|
||||
]
|
||||
|> Widget.column style.column
|
@ -3,148 +3,205 @@ module Icons exposing
|
||||
, chevronDown
|
||||
, chevronLeft
|
||||
, chevronRight
|
||||
, chevronUp
|
||||
, circle
|
||||
, github
|
||||
, menu
|
||||
, moreVertical
|
||||
, penTool
|
||||
, repeat
|
||||
, search
|
||||
, slash
|
||||
, square
|
||||
, triangle
|
||||
, chevronUp
|
||||
, penTool
|
||||
)
|
||||
|
||||
import Html exposing (Html)
|
||||
import Svg exposing (Svg, svg)
|
||||
import Svg.Attributes exposing (..)
|
||||
import Svg.Attributes as Attributes
|
||||
|
||||
|
||||
svgFeatherIcon : String -> List (Svg msg) -> Html msg
|
||||
svgFeatherIcon className =
|
||||
svg
|
||||
[ class <| "feather feather-" ++ className
|
||||
, fill "none"
|
||||
, height "16"
|
||||
, stroke "currentColor"
|
||||
, strokeLinecap "round"
|
||||
, strokeLinejoin "round"
|
||||
, strokeWidth "2"
|
||||
, viewBox "0 0 24 24"
|
||||
, width "16"
|
||||
[ Attributes.class <| "feather feather-" ++ className
|
||||
, Attributes.fill "none"
|
||||
, Attributes.height "16"
|
||||
, Attributes.stroke "currentColor"
|
||||
, Attributes.strokeLinecap "round"
|
||||
, Attributes.strokeLinejoin "round"
|
||||
, Attributes.strokeWidth "2"
|
||||
, Attributes.viewBox "0 0 24 24"
|
||||
, Attributes.width "16"
|
||||
]
|
||||
|
||||
|
||||
chevronDown : Html msg
|
||||
chevronDown =
|
||||
svgFeatherIcon "chevron-down"
|
||||
[ Svg.polyline [ points "6 9 12 15 18 9" ] []
|
||||
[ Svg.polyline [ Attributes.points "6 9 12 15 18 9" ] []
|
||||
]
|
||||
|
||||
|
||||
chevronRight : Html msg
|
||||
chevronRight =
|
||||
svgFeatherIcon "chevron-right"
|
||||
[ Svg.polyline [ points "9 18 15 12 9 6" ] []
|
||||
[ Svg.polyline [ Attributes.points "9 18 15 12 9 6" ] []
|
||||
]
|
||||
|
||||
|
||||
chevronLeft : Html msg
|
||||
chevronLeft =
|
||||
svgFeatherIcon "chevron-left"
|
||||
[ Svg.polyline [ points "15 18 9 12 15 6" ] []
|
||||
[ Svg.polyline [ Attributes.points "15 18 9 12 15 6" ] []
|
||||
]
|
||||
|
||||
|
||||
chevronUp : Html msg
|
||||
chevronUp =
|
||||
svgFeatherIcon "chevron-up"
|
||||
[ Svg.polyline [ points "18 15 12 9 6 15" ] []
|
||||
[ Svg.polyline [ Attributes.points "18 15 12 9 6 15" ] []
|
||||
]
|
||||
|
||||
|
||||
repeat : Html msg
|
||||
repeat =
|
||||
svgFeatherIcon "repeat"
|
||||
[ Svg.polyline [ points "17 1 21 5 17 9" ] []
|
||||
, Svg.path [ d "M3 11V9a4 4 0 0 1 4-4h14" ] []
|
||||
, Svg.polyline [ points "7 23 3 19 7 15" ] []
|
||||
, Svg.path [ d "M21 13v2a4 4 0 0 1-4 4H3" ] []
|
||||
[ Svg.polyline [ Attributes.points "17 1 21 5 17 9" ] []
|
||||
, Svg.path [ Attributes.d "M3 11V9a4 4 0 0 1 4-4h14" ] []
|
||||
, Svg.polyline [ Attributes.points "7 23 3 19 7 15" ] []
|
||||
, Svg.path [ Attributes.d "M21 13v2a4 4 0 0 1-4 4H3" ] []
|
||||
]
|
||||
|
||||
|
||||
penTool : Html msg
|
||||
penTool =
|
||||
svgFeatherIcon "pen-tool"
|
||||
[ Svg.path [ d "M12 19l7-7 3 3-7 7-3-3z" ] []
|
||||
, Svg.path [ d "M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z" ] []
|
||||
, Svg.path [ d "M2 2l7.586 7.586" ] []
|
||||
, Svg.circle [ cx "11", cy "11", r "2" ] []
|
||||
[ Svg.path [ Attributes.d "M12 19l7-7 3 3-7 7-3-3z" ] []
|
||||
, Svg.path [ Attributes.d "M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z" ] []
|
||||
, Svg.path [ Attributes.d "M2 2l7.586 7.586" ] []
|
||||
, Svg.circle
|
||||
[ Attributes.cx "11"
|
||||
, Attributes.cy "11"
|
||||
, Attributes.r "2"
|
||||
]
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
book : Html msg
|
||||
book =
|
||||
svgFeatherIcon "book"
|
||||
[ Svg.path [ d "M4 19.5A2.5 2.5 0 0 1 6.5 17H20" ] []
|
||||
, Svg.path [ d "M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" ] []
|
||||
[ Svg.path [ Attributes.d "M4 19.5A2.5 2.5 0 0 1 6.5 17H20" ] []
|
||||
, Svg.path [ Attributes.d "M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" ] []
|
||||
]
|
||||
|
||||
|
||||
github : Html msg
|
||||
github =
|
||||
svgFeatherIcon "github"
|
||||
[ Svg.path [ d "M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" ] []
|
||||
[ Svg.path [ Attributes.d "M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" ] []
|
||||
]
|
||||
|
||||
|
||||
menu : Html msg
|
||||
menu =
|
||||
svgFeatherIcon "menu"
|
||||
[ Svg.line [ x1 "3", y1 "12", x2 "21", y2 "12" ] []
|
||||
, Svg.line [ x1 "3", y1 "6", x2 "21", y2 "6" ] []
|
||||
, Svg.line [ x1 "3", y1 "18", x2 "21", y2 "18" ] []
|
||||
[ Svg.line
|
||||
[ Attributes.x1 "3"
|
||||
, Attributes.y1 "12"
|
||||
, Attributes.x2 "21"
|
||||
, Attributes.y2 "12"
|
||||
]
|
||||
[]
|
||||
, Svg.line
|
||||
[ Attributes.x1 "3"
|
||||
, Attributes.y1 "6"
|
||||
, Attributes.x2 "21"
|
||||
, Attributes.y2 "6"
|
||||
]
|
||||
[]
|
||||
, Svg.line
|
||||
[ Attributes.x1 "3"
|
||||
, Attributes.y1 "18"
|
||||
, Attributes.x2 "21"
|
||||
, Attributes.y2 "18"
|
||||
]
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
moreVertical : Html msg
|
||||
moreVertical =
|
||||
svgFeatherIcon "more-vertical"
|
||||
[ Svg.circle [ cx "12", cy "12", r "1" ] []
|
||||
, Svg.circle [ cx "12", cy "5", r "1" ] []
|
||||
, Svg.circle [ cx "12", cy "19", r "1" ] []
|
||||
[ Svg.circle [ Attributes.cx "12", Attributes.cy "12", Attributes.r "1" ] []
|
||||
, Svg.circle [ Attributes.cx "12", Attributes.cy "5", Attributes.r "1" ] []
|
||||
, Svg.circle [ Attributes.cx "12", Attributes.cy "19", Attributes.r "1" ] []
|
||||
]
|
||||
|
||||
|
||||
circle : Html msg
|
||||
circle =
|
||||
svgFeatherIcon "circle"
|
||||
[ Svg.circle [ cx "12", cy "12", r "10" ] []
|
||||
[ Svg.circle [ Attributes.cx "12", Attributes.cy "12", Attributes.r "10" ] []
|
||||
]
|
||||
|
||||
|
||||
slash : Html msg
|
||||
slash =
|
||||
svgFeatherIcon "slash"
|
||||
[ Svg.circle [ cx "12", cy "12", r "10" ] []
|
||||
, Svg.line [ x1 "4.93", y1 "4.93", x2 "19.07", y2 "19.07" ] []
|
||||
[ Svg.circle
|
||||
[ Attributes.cx "12"
|
||||
, Attributes.cy "12"
|
||||
, Attributes.r "10"
|
||||
]
|
||||
[]
|
||||
, Svg.line
|
||||
[ Attributes.x1 "4.93"
|
||||
, Attributes.y1 "4.93"
|
||||
, Attributes.x2 "19.07"
|
||||
, Attributes.y2 "19.07"
|
||||
]
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
triangle : Html msg
|
||||
triangle =
|
||||
svgFeatherIcon "triangle"
|
||||
[ Svg.path [ d "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" ] []
|
||||
[ Svg.path [ Attributes.d "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" ] []
|
||||
]
|
||||
|
||||
|
||||
square : Html msg
|
||||
square =
|
||||
svgFeatherIcon "square"
|
||||
[ Svg.rect [ Svg.Attributes.x "3", y "3", width "18", height "18", rx "2", ry "2" ] []
|
||||
[ Svg.rect
|
||||
[ Attributes.x "3"
|
||||
, Attributes.y "3"
|
||||
, Attributes.width "18"
|
||||
, Attributes.height "18"
|
||||
, Attributes.rx "2"
|
||||
, Attributes.ry "2"
|
||||
]
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
search : Html msg
|
||||
search =
|
||||
svgFeatherIcon "search"
|
||||
[ Svg.circle [ cx "11", cy "11", r "8" ] []
|
||||
, Svg.line [ x1 "21", y1 "21", x2 "16.65", y2 "16.65" ] []
|
||||
[ Svg.circle
|
||||
[ Attributes.cx "11"
|
||||
, Attributes.cy "11"
|
||||
, Attributes.r "8"
|
||||
]
|
||||
[]
|
||||
, Svg.line
|
||||
[ Attributes.x1 "21"
|
||||
, Attributes.y1 "21"
|
||||
, Attributes.x2 "16.65"
|
||||
, Attributes.y2 "16.65"
|
||||
]
|
||||
[]
|
||||
]
|
||||
|
@ -6,34 +6,21 @@ import Browser.Dom as Dom exposing (Viewport)
|
||||
import Browser.Events as Events
|
||||
import Browser.Navigation as Navigation
|
||||
import Data.Section as Section exposing (Section(..))
|
||||
import Data.Style as Style exposing (Style)
|
||||
import Data.Style exposing (Style)
|
||||
import Data.Theme as Theme exposing (Theme(..))
|
||||
import Element exposing (Attribute, DeviceClass(..), Element)
|
||||
import Element.Border as Border
|
||||
import Element.Font as Font
|
||||
import Element.Input as Input
|
||||
import Element exposing (DeviceClass(..))
|
||||
import Framework
|
||||
import Framework.Button as Button
|
||||
import Framework.Card as Card
|
||||
import Framework.Color as Color
|
||||
import Framework.Grid as Grid
|
||||
import Framework.Group as Group
|
||||
import Framework.Heading as Heading
|
||||
import Framework.Input as Input
|
||||
import Framework.Tag as Tag
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes as Attributes
|
||||
import Icons
|
||||
import Layout exposing (Layout, Part)
|
||||
import Reusable
|
||||
import Set exposing (Set)
|
||||
import Stateless
|
||||
import Task
|
||||
import Time
|
||||
import Widget
|
||||
import Widget.Layout as Layout exposing (Layout, Part)
|
||||
import Widget.ScrollingNav as ScrollingNav
|
||||
import Widget.Snackbar as Snackbar
|
||||
import Widget.Style exposing (ButtonStyle)
|
||||
|
||||
|
||||
type alias LoadedModel =
|
||||
@ -41,7 +28,10 @@ type alias LoadedModel =
|
||||
, scrollingNav : ScrollingNav.Model Section
|
||||
, layout : Layout LoadedMsg
|
||||
, displayDialog : Bool
|
||||
, window : { height : Int, width : Int }
|
||||
, window :
|
||||
{ height : Int
|
||||
, width : Int
|
||||
}
|
||||
, search :
|
||||
{ raw : String
|
||||
, current : String
|
||||
@ -110,7 +100,7 @@ initialModel { viewport } =
|
||||
, current = ""
|
||||
, remaining = 0
|
||||
}
|
||||
, theme = ElmUiFramework
|
||||
, theme = Material
|
||||
}
|
||||
, [ cmd
|
||||
, statelessCmd |> Cmd.map StatelessSpecific
|
||||
@ -171,17 +161,17 @@ view model =
|
||||
(\section ->
|
||||
(case section of
|
||||
ReusableViews ->
|
||||
Reusable.view m.theme
|
||||
{ addSnackbar = AddSnackbar
|
||||
Reusable.view
|
||||
{ theme = m.theme
|
||||
, addSnackbar = AddSnackbar
|
||||
}
|
||||
|
||||
StatelessViews ->
|
||||
Stateless.view m.theme
|
||||
{ msgMapper = StatelessSpecific
|
||||
, showDialog = ToggleDialog True
|
||||
, changedSheet = ChangedSidebar
|
||||
Stateless.view
|
||||
{ theme = m.theme
|
||||
, msgMapper = StatelessSpecific
|
||||
, model = m.stateless
|
||||
}
|
||||
m.stateless
|
||||
)
|
||||
|> (\{ title, description, items } ->
|
||||
[ Element.el Heading.h2 <| Element.text <| title
|
||||
@ -213,12 +203,17 @@ view model =
|
||||
]
|
||||
|> Element.column Grid.simple
|
||||
, more
|
||||
|> Element.el [ Element.height <| Element.fill ]
|
||||
|> Element.el
|
||||
[ Element.width <| Element.fill
|
||||
]
|
||||
]
|
||||
|> Widget.column style.cardColumn
|
||||
)
|
||||
|> Element.wrappedRow
|
||||
(Grid.simple ++ [ Element.height <| Element.shrink ])
|
||||
(Grid.simple
|
||||
++ [ Element.height <| Element.shrink
|
||||
]
|
||||
)
|
||||
]
|
||||
|> Element.column (Grid.section ++ [ Element.centerX ])
|
||||
)
|
||||
@ -266,6 +261,15 @@ view model =
|
||||
, text = "Template Theme"
|
||||
, icon = Icons.penTool |> Element.html |> Element.el []
|
||||
}
|
||||
, { onPress =
|
||||
if m.theme /= Material then
|
||||
Just <| SetTheme <| Material
|
||||
|
||||
else
|
||||
Nothing
|
||||
, text = "Material Theme"
|
||||
, icon = Icons.penTool |> Element.html |> Element.el []
|
||||
}
|
||||
, { onPress = Nothing
|
||||
, text = "Placeholder"
|
||||
, icon = Icons.circle |> Element.html |> Element.el []
|
||||
@ -428,7 +432,7 @@ update msg model =
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
subscriptions _ =
|
||||
Sub.batch
|
||||
[ Time.every 50 (always (TimePassed 50))
|
||||
, Events.onResize (\h w -> Resized { height = h, width = w })
|
||||
|
@ -1,40 +1,13 @@
|
||||
module Reusable exposing ( view)
|
||||
module Reusable exposing (view)
|
||||
|
||||
import Browser
|
||||
import Element exposing (Color, Element)
|
||||
import Element.Background as Background
|
||||
import Element.Font as Font
|
||||
import Element.Input as Input
|
||||
import Framework
|
||||
import Framework.Button as Button
|
||||
import Framework.Card as Card
|
||||
import Framework.Color as Color
|
||||
import Framework.Grid as Grid
|
||||
import Framework.Group as Group
|
||||
import Framework.Heading as Heading
|
||||
import Framework.Input as Input
|
||||
import Framework.Tag as Tag
|
||||
import Heroicons.Solid as Heroicons
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes as Attributes
|
||||
import Set exposing (Set)
|
||||
import Time
|
||||
import Widget
|
||||
import Widget.ScrollingNav as ScrollingNav
|
||||
import Widget.Snackbar as Snackbar
|
||||
import Data.Style exposing (Style)
|
||||
import Data.Theme as Theme exposing (Theme)
|
||||
import Element exposing (Element)
|
||||
import Framework.Grid as Grid
|
||||
import Widget
|
||||
|
||||
|
||||
type alias Item =
|
||||
{ name : String
|
||||
, amount : Int
|
||||
, price : Float
|
||||
}
|
||||
|
||||
|
||||
|
||||
snackbar : Style msg -> (( String, Bool ) -> msg) -> ( String, Element msg,Element msg )
|
||||
snackbar : Style msg -> (( String, Bool ) -> msg) -> ( String, Element msg, Element msg )
|
||||
snackbar style addSnackbar =
|
||||
( "Snackbar"
|
||||
, [ Widget.button style.button
|
||||
@ -45,7 +18,7 @@ snackbar style addSnackbar =
|
||||
, False
|
||||
)
|
||||
, text = "Add Notification"
|
||||
, icon =Element.none
|
||||
, icon = Element.none
|
||||
}
|
||||
, Widget.button style.button
|
||||
{ onPress =
|
||||
@ -63,11 +36,8 @@ snackbar style addSnackbar =
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
scrollingNavCard : Style msg -> ( String, Element msg, Element msg )
|
||||
scrollingNavCard style =
|
||||
scrollingNavCard _ =
|
||||
( "Scrolling Nav"
|
||||
, Element.text "Resize the screen and open the side-menu. Then start scrolling to see the scrolling navigation in action."
|
||||
|> List.singleton
|
||||
@ -76,23 +46,35 @@ scrollingNavCard style =
|
||||
)
|
||||
|
||||
|
||||
layout : Style msg -> ( String, Element msg, Element msg )
|
||||
layout _ =
|
||||
( "Layout"
|
||||
, Element.text "The layout combines the menu bar, both side bar, the dialog window and the snackbar. Try using all of them and also try resizing the window to see how they interact with each other."
|
||||
|> List.singleton
|
||||
|> Element.paragraph []
|
||||
, Element.none
|
||||
)
|
||||
|
||||
|
||||
view :
|
||||
Theme ->
|
||||
{ addSnackbar : ( String, Bool ) -> msg
|
||||
{ theme : Theme
|
||||
, addSnackbar : ( String, Bool ) -> msg
|
||||
}
|
||||
->
|
||||
{ title : String
|
||||
, description : String
|
||||
, items : List ( String, Element msg,Element msg )
|
||||
, items : List ( String, Element msg, Element msg )
|
||||
}
|
||||
view theme { addSnackbar } =
|
||||
view { theme, addSnackbar } =
|
||||
let
|
||||
style = Theme.toStyle theme
|
||||
style =
|
||||
Theme.toStyle theme
|
||||
in
|
||||
{ title = "Reusable Views"
|
||||
, description = "Reusable views have an internal state but no update function. You will need to do some wiring, but nothing complicated."
|
||||
, items =
|
||||
[ snackbar style addSnackbar
|
||||
, scrollingNavCard style
|
||||
, layout style
|
||||
]
|
||||
}
|
||||
|
@ -1,37 +1,19 @@
|
||||
module Stateless exposing (Model, Msg, init, update, view)
|
||||
|
||||
import Array
|
||||
import Data.Example as Example
|
||||
import Data.Style exposing (Style)
|
||||
import Data.Theme as Theme exposing (Theme)
|
||||
import Element exposing (Element)
|
||||
import Element.Background as Background
|
||||
import Framework.Card as Card
|
||||
import Framework.Color as Color
|
||||
import Framework.Grid as Grid
|
||||
import Heroicons.Solid as Heroicons
|
||||
import Html.Attributes as Attributes
|
||||
import Icons
|
||||
import Layout exposing (Part(..))
|
||||
import Set exposing (Set)
|
||||
import Widget
|
||||
import Widget.Layout exposing (Part(..))
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ chipTextInput : Set String
|
||||
, carousel : Int
|
||||
, textInput : String
|
||||
, table : { title : String, asc : Bool }
|
||||
{ carousel : Int
|
||||
, example : Example.Model
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ToggleTextInputChip String
|
||||
| SetCarousel Int
|
||||
| SetTextInput String
|
||||
| ChangedSorting String
|
||||
| ExampleSpecific Example.Msg
|
||||
= ExampleSpecific Example.Msg
|
||||
| Idle
|
||||
|
||||
|
||||
@ -41,10 +23,7 @@ init =
|
||||
( example, cmd ) =
|
||||
Example.init
|
||||
in
|
||||
( { chipTextInput = Set.empty
|
||||
, carousel = 0
|
||||
, textInput = ""
|
||||
, table = { title = "Name", asc = True }
|
||||
( { carousel = 0
|
||||
, example = example
|
||||
}
|
||||
, cmd |> Cmd.map ExampleSpecific
|
||||
@ -63,310 +42,24 @@ update msg model =
|
||||
, exampleCmd |> Cmd.map ExampleSpecific
|
||||
)
|
||||
|
||||
ToggleTextInputChip string ->
|
||||
( { model
|
||||
| chipTextInput =
|
||||
model.chipTextInput
|
||||
|> (if model.chipTextInput |> Set.member string then
|
||||
Set.remove string
|
||||
|
||||
else
|
||||
Set.insert string
|
||||
)
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SetCarousel int ->
|
||||
( if (int < 0) || (int > 3) then
|
||||
model
|
||||
|
||||
else
|
||||
{ model
|
||||
| carousel = int
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SetTextInput string ->
|
||||
( { model | textInput = string }, Cmd.none )
|
||||
|
||||
ChangedSorting string ->
|
||||
( { model
|
||||
| table =
|
||||
{ title = string
|
||||
, asc =
|
||||
if model.table.title == string then
|
||||
not model.table.asc
|
||||
|
||||
else
|
||||
True
|
||||
}
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
Idle ->
|
||||
( model, Cmd.none )
|
||||
|
||||
|
||||
modal : Style msg -> (Maybe Part -> msg) -> Model -> ( String, Element msg, Element msg )
|
||||
modal style changedSheet _ =
|
||||
( "Modal"
|
||||
, [ Widget.button style.button
|
||||
{ onPress = Just <| changedSheet <| Just LeftSheet
|
||||
, text = "show left sheet"
|
||||
, icon = Element.none
|
||||
}
|
||||
, Widget.button style.button
|
||||
{ onPress = Just <| changedSheet <| Just RightSheet
|
||||
, text = "show right sheet"
|
||||
, icon = Element.none
|
||||
}
|
||||
]
|
||||
|> Element.column Grid.simple
|
||||
, Element.none
|
||||
)
|
||||
|
||||
|
||||
dialog : Style msg -> msg -> Model -> ( String, Element msg, Element msg )
|
||||
dialog style showDialog _ =
|
||||
( "Dialog"
|
||||
, Widget.button style.button
|
||||
{ onPress = Just showDialog
|
||||
, text = "Show dialog"
|
||||
, icon = Element.none
|
||||
}
|
||||
, Element.none
|
||||
)
|
||||
|
||||
|
||||
carousel : Style Msg -> Model -> ( String, Element Msg, Element Msg )
|
||||
carousel style model =
|
||||
( "Carousel"
|
||||
, Widget.carousel
|
||||
{ content = ( Color.cyan, [ Color.yellow, Color.green, Color.red ] |> Array.fromList )
|
||||
, current = model.carousel
|
||||
, label =
|
||||
\c ->
|
||||
[ Element.el [ Element.centerY ] <|
|
||||
Widget.iconButton style.button
|
||||
{ onPress =
|
||||
model.carousel
|
||||
- 1
|
||||
|> (\i ->
|
||||
if i < 0 then
|
||||
Nothing
|
||||
|
||||
else
|
||||
SetCarousel i
|
||||
|> Just
|
||||
)
|
||||
, icon =
|
||||
Icons.chevronLeft
|
||||
|> Element.html
|
||||
|> Element.el []
|
||||
, text = "Previous"
|
||||
}
|
||||
, Element.el
|
||||
(Card.simple
|
||||
++ [ Background.color <| c
|
||||
, Element.height <| Element.px <| 100
|
||||
, Element.width <| Element.px <| 100
|
||||
]
|
||||
)
|
||||
<|
|
||||
Element.none
|
||||
, Element.el [ Element.centerY ] <|
|
||||
Widget.iconButton style.button
|
||||
{ onPress =
|
||||
model.carousel
|
||||
+ 1
|
||||
|> (\i ->
|
||||
if i >= 4 then
|
||||
Nothing
|
||||
|
||||
else
|
||||
SetCarousel i
|
||||
|> Just
|
||||
)
|
||||
, icon =
|
||||
Icons.chevronRight
|
||||
|> Element.html
|
||||
|> Element.el []
|
||||
, text = "Next"
|
||||
}
|
||||
]
|
||||
|> Element.row (Grid.simple ++ [ Element.centerX, Element.width <| Element.shrink ])
|
||||
}
|
||||
, Element.none
|
||||
)
|
||||
|
||||
|
||||
textInput : Style Msg -> Model -> ( String, Element Msg, Element Msg )
|
||||
textInput style model =
|
||||
( "Chip Text Input"
|
||||
, [ { chips =
|
||||
model.chipTextInput
|
||||
|> Set.toList
|
||||
|> List.map
|
||||
(\string ->
|
||||
{ icon = Element.none
|
||||
, text = string
|
||||
, onPress =
|
||||
string
|
||||
|> ToggleTextInputChip
|
||||
|> Just
|
||||
}
|
||||
)
|
||||
, text = model.textInput
|
||||
, placeholder = Nothing
|
||||
, label = "Chips"
|
||||
, onChange = SetTextInput
|
||||
}
|
||||
|> Widget.textInput style.textInput
|
||||
, model.chipTextInput
|
||||
|> Set.diff
|
||||
([ "A", "B", "C" ]
|
||||
|> Set.fromList
|
||||
)
|
||||
|> Set.toList
|
||||
|> List.map
|
||||
(\string ->
|
||||
Widget.button style.textInput.chipButton
|
||||
{ onPress =
|
||||
string
|
||||
|> ToggleTextInputChip
|
||||
|> Just
|
||||
, text = string
|
||||
, icon = Element.none
|
||||
}
|
||||
)
|
||||
|> Element.wrappedRow [ Element.spacing 10 ]
|
||||
]
|
||||
|> Element.column Grid.simple
|
||||
, [ Element.row Grid.spacedEvenly
|
||||
[ "Nothing Selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
, { chips = []
|
||||
, text = ""
|
||||
, placeholder = Nothing
|
||||
, label = "Label"
|
||||
, onChange = always Idle
|
||||
}
|
||||
|> Widget.textInput style.textInput
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Some chips"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
, { chips =
|
||||
[ { icon = Icons.triangle |> Element.html |> Element.el []
|
||||
, text = "A"
|
||||
, onPress = Just Idle
|
||||
}
|
||||
, { icon = Icons.circle |> Element.html |> Element.el []
|
||||
, text = "B"
|
||||
, onPress = Just Idle
|
||||
}
|
||||
]
|
||||
, text = ""
|
||||
, placeholder = Nothing
|
||||
, label = "Label"
|
||||
, onChange = always Idle
|
||||
}
|
||||
|> Widget.textInput style.textInput
|
||||
]
|
||||
]
|
||||
|> Element.column Grid.simple
|
||||
)
|
||||
|
||||
|
||||
list : Style Msg -> Model -> ( String, Element Msg, Element Msg )
|
||||
list style _ =
|
||||
( "List"
|
||||
, [ Element.text <| "A"
|
||||
, Element.text <| "B"
|
||||
, Element.text <| "C"
|
||||
]
|
||||
|> Widget.column style.cardColumn
|
||||
, Element.none
|
||||
)
|
||||
|
||||
|
||||
sortTable : Style Msg -> Model -> ( String, Element Msg, Element Msg )
|
||||
sortTable _ model =
|
||||
( "Sort Table"
|
||||
, Widget.sortTable
|
||||
{ containerTable = Grid.simple
|
||||
, headerButton =
|
||||
{ container = []
|
||||
, labelRow = []
|
||||
, ifDisabled = []
|
||||
, ifActive = []
|
||||
}
|
||||
, ascIcon = Heroicons.cheveronUp [ Attributes.width 16 ] |> Element.html
|
||||
, descIcon = Heroicons.cheveronDown [ Attributes.width 16 ] |> Element.html
|
||||
, defaultIcon = Element.none
|
||||
}
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456 }
|
||||
, { id = 2, name = "Ana", rating = 1.34 }
|
||||
, { id = 3, name = "Alfred", rating = 4.22 }
|
||||
, { id = 4, name = "Thomas", rating = 3 }
|
||||
]
|
||||
, columns =
|
||||
[ Widget.intColumn
|
||||
{ title = "Id"
|
||||
, value = .id
|
||||
, toString = \int -> "#" ++ String.fromInt int
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.stringColumn
|
||||
{ title = "Name"
|
||||
, value = .name
|
||||
, toString = identity
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.floatColumn
|
||||
{ title = "rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = model.table.asc
|
||||
, sortBy = model.table.title
|
||||
, onChange = ChangedSorting
|
||||
}
|
||||
, Element.none
|
||||
)
|
||||
|
||||
|
||||
view :
|
||||
Theme
|
||||
->
|
||||
{ msgMapper : Msg -> msg
|
||||
, showDialog : msg
|
||||
, changedSheet : Maybe Part -> msg
|
||||
{ theme : Theme
|
||||
, msgMapper : Msg -> msg
|
||||
, model : Model
|
||||
}
|
||||
-> Model
|
||||
->
|
||||
{ title : String
|
||||
, description : String
|
||||
, items : List ( String, Element msg, Element msg )
|
||||
}
|
||||
view theme { msgMapper, showDialog, changedSheet } model =
|
||||
view { theme, msgMapper, model } =
|
||||
let
|
||||
style =
|
||||
Theme.toStyle theme
|
||||
|
||||
map ( a, b, c ) =
|
||||
( a
|
||||
, b |> Element.map msgMapper
|
||||
, c |> Element.map msgMapper
|
||||
)
|
||||
in
|
||||
{ title = "Stateless Views"
|
||||
, description = "Stateless views are simple functions that view some content. No wiring required."
|
||||
@ -377,11 +70,4 @@ view theme { msgMapper, showDialog, changedSheet } model =
|
||||
, style = style
|
||||
, model = model.example
|
||||
}
|
||||
++ [ modal style changedSheet model
|
||||
, carousel style model |> map
|
||||
, dialog style showDialog model
|
||||
, textInput style model |> map
|
||||
, list style model |> map
|
||||
, sortTable style model |> map
|
||||
]
|
||||
}
|
||||
|
@ -1,61 +1,43 @@
|
||||
module View.Test exposing (expansionPanel, iconButton, multiSelect, select, tab)
|
||||
module View.Test exposing (button, dialog, expansionPanel, list, modal, multiSelect, select, sortTable, tab, textInput)
|
||||
|
||||
import Array
|
||||
import Data.Style exposing (Style)
|
||||
import Data.Theme as Theme exposing (Theme)
|
||||
import Element exposing (Element)
|
||||
import Element.Background as Background
|
||||
import Framework.Card as Card
|
||||
import Framework.Color as Color
|
||||
import Framework.Grid as Grid
|
||||
import Heroicons.Solid as Heroicons
|
||||
import Html.Attributes as Attributes
|
||||
import Icons
|
||||
import Layout exposing (Part(..))
|
||||
import Set exposing (Set)
|
||||
import Set
|
||||
import Widget
|
||||
import Widget.Layout exposing (Part(..))
|
||||
|
||||
|
||||
iconButton : msg -> Style msg -> List (Element msg)
|
||||
iconButton idle style =
|
||||
[ Element.row Grid.spacedEvenly
|
||||
[ "Button"
|
||||
|> Element.text
|
||||
button : msg -> Style msg -> List ( String, Element msg )
|
||||
button idle style =
|
||||
[ ( "Button"
|
||||
, Widget.button style.button
|
||||
{ text = "Button"
|
||||
, icon = Icons.triangle |> Element.html |> Element.el []
|
||||
, onPress = Just idle
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Text button"
|
||||
|> Element.text
|
||||
)
|
||||
, ( "Text button"
|
||||
, Widget.textButton style.button
|
||||
{ text = "Button"
|
||||
, onPress = Just idle
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Icon button"
|
||||
|> Element.text
|
||||
)
|
||||
, ( "Icon button"
|
||||
, Widget.iconButton style.button
|
||||
{ text = "Button"
|
||||
, icon = Icons.triangle |> Element.html |> Element.el []
|
||||
, onPress = Just idle
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Disabled button"
|
||||
|> Element.text
|
||||
)
|
||||
, ( "Disabled button"
|
||||
, Widget.button style.button
|
||||
{ text = "Button"
|
||||
, icon = Icons.triangle |> Element.html |> Element.el []
|
||||
, onPress = Nothing
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Inactive Select button"
|
||||
|> Element.text
|
||||
)
|
||||
, ( "Inactive Select button"
|
||||
, Widget.selectButton style.button
|
||||
( False
|
||||
, { text = "Button"
|
||||
@ -63,10 +45,8 @@ iconButton idle style =
|
||||
, onPress = Just idle
|
||||
}
|
||||
)
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Active Select button"
|
||||
|> Element.text
|
||||
)
|
||||
, ( "Active Select button"
|
||||
, Widget.selectButton style.button
|
||||
( True
|
||||
, { text = "Button"
|
||||
@ -74,16 +54,13 @@ iconButton idle style =
|
||||
, onPress = Just idle
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
select : msg -> Style msg -> List (Element msg)
|
||||
select : msg -> Style msg -> List ( String, Element msg )
|
||||
select idle style =
|
||||
[ Element.row Grid.spacedEvenly
|
||||
[ "First selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
[ ( "First selected"
|
||||
, { selected = Just 0
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -100,11 +77,8 @@ select idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Nothing selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Nothing selected"
|
||||
, { selected = Nothing
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -121,11 +95,8 @@ select idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Invalid selection"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Invalid selection"
|
||||
, { selected = Just -1
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -142,11 +113,8 @@ select idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Disabled selection"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Disabled selection"
|
||||
, { selected = Just 0
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -163,11 +131,8 @@ select idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Empty Options"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Empty Options"
|
||||
, { selected = Nothing
|
||||
, options =
|
||||
[]
|
||||
@ -184,16 +149,13 @@ select idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
multiSelect : msg -> Style msg -> List (Element msg)
|
||||
multiSelect : msg -> Style msg -> List ( String, Element msg )
|
||||
multiSelect idle style =
|
||||
[ Element.row Grid.spacedEvenly
|
||||
[ "Some selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
[ ( "Some selected"
|
||||
, { selected = Set.fromList [ 0, 1 ]
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -210,11 +172,8 @@ multiSelect idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Nothing selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Nothing selected"
|
||||
, { selected = Set.empty
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -231,11 +190,8 @@ multiSelect idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Invalid selection"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Invalid selection"
|
||||
, { selected = Set.singleton -1
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -252,11 +208,8 @@ multiSelect idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Disabled selection"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Disabled selection"
|
||||
, { selected = Set.singleton 0
|
||||
, options =
|
||||
[ 1, 2, 42 ]
|
||||
@ -273,11 +226,8 @@ multiSelect idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Empty Options"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Empty Options"
|
||||
, { selected = Set.empty
|
||||
, options =
|
||||
[]
|
||||
@ -294,16 +244,13 @@ multiSelect idle style =
|
||||
{ list = style.row
|
||||
, button = style.button
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
expansionPanel : msg -> Style msg -> List (Element msg)
|
||||
expansionPanel : msg -> Style msg -> List ( String, Element msg )
|
||||
expansionPanel idle style =
|
||||
[ Element.row Grid.spacedEvenly
|
||||
[ "Collapsed"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
[ ( "Collapsed"
|
||||
, { onToggle = always idle
|
||||
, isExpanded = False
|
||||
, icon = Icons.triangle |> Element.html |> Element.el []
|
||||
@ -311,11 +258,8 @@ expansionPanel idle style =
|
||||
, content = Element.text <| "Hidden Message"
|
||||
}
|
||||
|> Widget.expansionPanel style.expansionPanel
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Expanded"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Expanded"
|
||||
, { onToggle = always idle
|
||||
, isExpanded = True
|
||||
, icon = Icons.triangle |> Element.html |> Element.el []
|
||||
@ -323,16 +267,13 @@ expansionPanel idle style =
|
||||
, content = Element.text <| "Hidden Message"
|
||||
}
|
||||
|> Widget.expansionPanel style.expansionPanel
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
tab : msg -> Style msg -> List (Element msg)
|
||||
tab : msg -> Style msg -> List ( String, Element msg )
|
||||
tab idle style =
|
||||
[ Element.row Grid.spacedEvenly
|
||||
[ "Nothing selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
[ ( "Nothing selected"
|
||||
, Widget.tab style.tab
|
||||
{ tabs =
|
||||
{ selected = Nothing
|
||||
@ -357,11 +298,8 @@ tab idle style =
|
||||
)
|
||||
|> Element.text
|
||||
}
|
||||
]
|
||||
, Element.row Grid.spacedEvenly
|
||||
[ "Tab selected"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
)
|
||||
, ( "Tab selected"
|
||||
, Widget.tab style.tab
|
||||
{ tabs =
|
||||
{ selected = Just 0
|
||||
@ -386,5 +324,190 @@ tab idle style =
|
||||
)
|
||||
|> Element.text
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
sortTable : msg -> Style msg -> List ( String, Element msg )
|
||||
sortTable idle style =
|
||||
[ ( "Int column"
|
||||
, Widget.sortTable style.sortTable
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
]
|
||||
, columns =
|
||||
[ Widget.intColumn
|
||||
{ title = "Id"
|
||||
, value = .id
|
||||
, toString = \int -> "#" ++ String.fromInt int
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.stringColumn
|
||||
{ title = "Name"
|
||||
, value = .name
|
||||
, toString = identity
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = True
|
||||
, sortBy = "Id"
|
||||
, onChange = always idle
|
||||
}
|
||||
)
|
||||
, ( "Name column"
|
||||
, Widget.sortTable style.sortTable
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
]
|
||||
, columns =
|
||||
[ Widget.stringColumn
|
||||
{ title = "Name"
|
||||
, value = .name
|
||||
, toString = identity
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.floatColumn
|
||||
{ title = "Rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = True
|
||||
, sortBy = "Name"
|
||||
, onChange = always idle
|
||||
}
|
||||
)
|
||||
, ( "Float column"
|
||||
, Widget.sortTable style.sortTable
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
]
|
||||
, columns =
|
||||
[ Widget.floatColumn
|
||||
{ title = "Rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.unsortableColumn
|
||||
{ title = "Hash"
|
||||
, toString = .hash >> Maybe.withDefault "None"
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = False
|
||||
, sortBy = "Rating"
|
||||
, onChange = always idle
|
||||
}
|
||||
)
|
||||
, ( "Unsortable column"
|
||||
, Widget.sortTable style.sortTable
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
]
|
||||
, columns =
|
||||
[ Widget.floatColumn
|
||||
{ title = "Rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.unsortableColumn
|
||||
{ title = "Hash"
|
||||
, toString = .hash >> Maybe.withDefault "None"
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = True
|
||||
, sortBy = "Hash"
|
||||
, onChange = always idle
|
||||
}
|
||||
)
|
||||
, ( "Empty Table"
|
||||
, Widget.sortTable style.sortTable
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
]
|
||||
, columns = []
|
||||
, asc = True
|
||||
, sortBy = ""
|
||||
, onChange = always idle
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
modal : msg -> Style msg -> List ( String, Element msg )
|
||||
modal _ _ =
|
||||
[]
|
||||
|
||||
|
||||
dialog : msg -> Style msg -> List ( String, Element msg )
|
||||
dialog _ _ =
|
||||
[]
|
||||
|
||||
|
||||
textInput : msg -> Style msg -> List ( String, Element msg )
|
||||
textInput idle style =
|
||||
[ ( "Nothing Selected"
|
||||
, { chips = []
|
||||
, text = ""
|
||||
, placeholder = Nothing
|
||||
, label = "Label"
|
||||
, onChange = always idle
|
||||
}
|
||||
|> Widget.textInput style.textInput
|
||||
)
|
||||
, ( "Some chips"
|
||||
, { chips =
|
||||
[ { icon = Icons.triangle |> Element.html |> Element.el []
|
||||
, text = "A"
|
||||
, onPress = Just idle
|
||||
}
|
||||
, { icon = Icons.circle |> Element.html |> Element.el []
|
||||
, text = "B"
|
||||
, onPress = Just idle
|
||||
}
|
||||
]
|
||||
, text = ""
|
||||
, placeholder = Nothing
|
||||
, label = "Label"
|
||||
, onChange = always idle
|
||||
}
|
||||
|> Widget.textInput style.textInput
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
list : msg -> Style msg -> List ( String, Element msg )
|
||||
list _ style =
|
||||
[ ( "Row"
|
||||
, [ Element.text "A"
|
||||
, Element.text "B"
|
||||
, Element.text "C"
|
||||
]
|
||||
|> Widget.row style.row
|
||||
)
|
||||
, ( "Column"
|
||||
, [ Element.text "A"
|
||||
, Element.text "B"
|
||||
, Element.text "C"
|
||||
]
|
||||
|> Widget.column style.cardColumn
|
||||
)
|
||||
, ( "Singleton List"
|
||||
, [ Element.text "A"
|
||||
]
|
||||
|> Widget.column style.cardColumn
|
||||
)
|
||||
, ( "Empty List"
|
||||
, []
|
||||
|> Widget.column style.cardColumn
|
||||
)
|
||||
]
|
||||
|
@ -33,7 +33,7 @@ iconButton style { onPress, text, icon } =
|
||||
style.ifDisabled
|
||||
|
||||
else
|
||||
[]
|
||||
style.otherwise
|
||||
)
|
||||
++ [ Region.description text ]
|
||||
)
|
||||
@ -63,7 +63,7 @@ button style { onPress, text, icon } =
|
||||
style.ifDisabled
|
||||
|
||||
else
|
||||
[]
|
||||
style.otherwise
|
||||
)
|
||||
)
|
||||
{ onPress = onPress
|
||||
|
@ -11,7 +11,7 @@ internal :
|
||||
| element : List (Attribute msg)
|
||||
, ifFirst : List (Attribute msg)
|
||||
, ifLast : List (Attribute msg)
|
||||
, ifCenter : List (Attribute msg)
|
||||
, otherwise : List (Attribute msg)
|
||||
}
|
||||
-> List (Element msg)
|
||||
-> List (Element msg)
|
||||
@ -31,7 +31,7 @@ internal style list =
|
||||
style.ifLast
|
||||
|
||||
else
|
||||
style.ifCenter
|
||||
style.otherwise
|
||||
)
|
||||
)
|
||||
|
||||
@ -52,7 +52,7 @@ internalButton :
|
||||
| element : List (Attribute msg)
|
||||
, ifFirst : List (Attribute msg)
|
||||
, ifLast : List (Attribute msg)
|
||||
, ifCenter : List (Attribute msg)
|
||||
, otherwise : List (Attribute msg)
|
||||
}
|
||||
, button : ButtonStyle msg
|
||||
}
|
||||
@ -76,7 +76,7 @@ internalButton style list =
|
||||
style.list.ifLast
|
||||
|
||||
else
|
||||
style.list.ifCenter
|
||||
style.list.otherwise
|
||||
)
|
||||
, labelRow =
|
||||
style.button.labelRow
|
||||
@ -84,6 +84,8 @@ internalButton style list =
|
||||
style.button.ifDisabled
|
||||
, ifActive =
|
||||
style.button.ifActive
|
||||
, otherwise =
|
||||
style.button.otherwise
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -5,8 +5,8 @@ module Widget exposing
|
||||
, ExpansionPanel, expansionPanel
|
||||
, row, column, buttonRow, buttonColumn
|
||||
, ColumnType, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
||||
, TextInputStyle, textInput, carousel, tab
|
||||
, Tab
|
||||
, TextInputStyle, textInput
|
||||
, Tab, tab
|
||||
)
|
||||
|
||||
{-| This module contains functions for displaying data.
|
||||
@ -27,7 +27,7 @@ module Widget exposing
|
||||
@docs Dialog, modal, dialog
|
||||
|
||||
|
||||
# ExpansionPanel
|
||||
# Expansion Panel
|
||||
|
||||
@docs ExpansionPanel, expansionPanel
|
||||
|
||||
@ -37,18 +37,22 @@ module Widget exposing
|
||||
@docs row, column, buttonRow, buttonColumn
|
||||
|
||||
|
||||
# SortTable
|
||||
# Sort Table
|
||||
|
||||
@docs ColumnType, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
|
||||
|
||||
|
||||
# Other Widgets
|
||||
# Text Input
|
||||
|
||||
@docs TextInputStyle, textInput, carousel, tab
|
||||
@docs TextInputStyle, textInput
|
||||
|
||||
|
||||
# Tab
|
||||
|
||||
@docs Tab, tab
|
||||
|
||||
-}
|
||||
|
||||
import Array exposing (Array)
|
||||
import Element exposing (Attribute, Element, Length)
|
||||
import Element.Input exposing (Placeholder)
|
||||
import Internal.Button as Button
|
||||
@ -57,6 +61,7 @@ import Internal.ExpansionPanel as ExpansionPanel
|
||||
import Internal.List as List
|
||||
import Internal.Select as Select
|
||||
import Internal.SortTable as SortTable
|
||||
import Internal.Tab as Tab
|
||||
import Internal.TextInput as TextInput
|
||||
import Set exposing (Set)
|
||||
import Widget.Style exposing (ButtonStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, RowStyle, SortTableStyle, TabStyle)
|
||||
@ -417,7 +422,7 @@ sortTable =
|
||||
|
||||
|
||||
{----------------------------------------------------------
|
||||
- OTHER STATELESS WIDGETS
|
||||
- TAB
|
||||
----------------------------------------------------------}
|
||||
|
||||
|
||||
@ -436,42 +441,5 @@ tab :
|
||||
, content : Maybe Int -> Element msg
|
||||
}
|
||||
-> Element msg
|
||||
tab style { tabs, content } =
|
||||
[ tabs
|
||||
|> select
|
||||
|> List.map (selectButton style.button)
|
||||
|> Element.row style.optionRow
|
||||
, tabs.selected
|
||||
|> content
|
||||
|> Element.el style.content
|
||||
]
|
||||
|> Element.column style.containerColumn
|
||||
|
||||
|
||||
{-| A Carousel circles through a non empty list of contents.
|
||||
-}
|
||||
carousel :
|
||||
{ content : ( a, Array a )
|
||||
, current : Int
|
||||
, label : a -> Element msg
|
||||
}
|
||||
-> Element msg
|
||||
carousel { content, current, label } =
|
||||
let
|
||||
( head, tail ) =
|
||||
content
|
||||
in
|
||||
(if current <= 0 then
|
||||
head
|
||||
|
||||
else if current > Array.length tail then
|
||||
tail
|
||||
|> Array.get (Array.length tail - 1)
|
||||
|> Maybe.withDefault head
|
||||
|
||||
else
|
||||
tail
|
||||
|> Array.get (current - 1)
|
||||
|> Maybe.withDefault head
|
||||
)
|
||||
|> label
|
||||
tab =
|
||||
Tab.tab
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Layout exposing (Layout, Part(..), activate, init, queueMessage, timePassed, view)
|
||||
module Widget.Layout exposing (Layout, Part(..), activate, init, queueMessage, timePassed, view)
|
||||
|
||||
import Array
|
||||
import Element exposing (Attribute, DeviceClass(..), Element)
|
@ -9,6 +9,7 @@ type alias ButtonStyle msg =
|
||||
, labelRow : List (Attribute msg)
|
||||
, ifDisabled : List (Attribute msg)
|
||||
, ifActive : List (Attribute msg)
|
||||
, otherwise : List (Attribute msg)
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +60,7 @@ type alias RowStyle msg =
|
||||
, element : List (Attribute msg)
|
||||
, ifFirst : List (Attribute msg)
|
||||
, ifLast : List (Attribute msg)
|
||||
, ifCenter : List (Attribute msg)
|
||||
, otherwise : List (Attribute msg)
|
||||
}
|
||||
|
||||
|
||||
@ -68,7 +69,7 @@ type alias ColumnStyle msg =
|
||||
, element : List (Attribute msg)
|
||||
, ifFirst : List (Attribute msg)
|
||||
, ifLast : List (Attribute msg)
|
||||
, ifCenter : List (Attribute msg)
|
||||
, otherwise : List (Attribute msg)
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user