mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-09-11 06:25:32 +03:00
Removed Example (replace with Explorer)
This commit is contained in:
parent
66df2aa7a5
commit
6b7b8bddc0
@ -1,51 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "application",
|
|
||||||
"source-directories": [
|
|
||||||
"src",
|
|
||||||
"../src"
|
|
||||||
],
|
|
||||||
"elm-version": "0.19.1",
|
|
||||||
"dependencies": {
|
|
||||||
"direct": {
|
|
||||||
"Orasund/elm-ui-framework": "1.6.1",
|
|
||||||
"avh4/elm-color": "1.0.0",
|
|
||||||
"capitalist/elm-octicons": "2.3.0",
|
|
||||||
"danmarcab/material-icons": "1.0.0",
|
|
||||||
"elm/browser": "1.0.2",
|
|
||||||
"elm/core": "1.0.5",
|
|
||||||
"elm/html": "1.0.0",
|
|
||||||
"elm/svg": "1.0.1",
|
|
||||||
"elm/time": "1.0.0",
|
|
||||||
"elm-community/intdict": "3.0.0",
|
|
||||||
"feathericons/elm-feather": "1.4.0",
|
|
||||||
"icidasset/elm-material-icons": "5.0.0",
|
|
||||||
"j-panasiuk/elm-ionicons": "2.0.0",
|
|
||||||
"jasonliang-dev/elm-heroicons": "1.0.1",
|
|
||||||
"lattyware/elm-fontawesome": "5.0.0",
|
|
||||||
"lemol/ant-design-icons-elm": "2.0.0",
|
|
||||||
"mdgriffith/elm-ui": "1.1.7",
|
|
||||||
"noahzgordon/elm-color-extra": "1.0.2",
|
|
||||||
"pehota/elm-zondicons": "1.0.1",
|
|
||||||
"ryannhg/elm-spa": "4.1.0",
|
|
||||||
"turboMaCk/any-set": "1.4.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",
|
|
||||||
"fredcy/elm-parseint": "2.0.1",
|
|
||||||
"turboMaCk/any-dict": "2.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test-dependencies": {
|
|
||||||
"direct": {
|
|
||||||
"elm-explorations/test": "1.2.2"
|
|
||||||
},
|
|
||||||
"indirect": {
|
|
||||||
"elm/random": "1.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
23956
example/index.html
23956
example/index.html
File diff suppressed because it is too large
Load Diff
@ -1,74 +0,0 @@
|
|||||||
|
|
||||||
import Http exposing (Error)
|
|
||||||
import Parser
|
|
||||||
|
|
||||||
url : String
|
|
||||||
url name =
|
|
||||||
"https://raw.githubusercontent.com/Orasund/elm-ui-widget/master/example/src/Example/" ++ name ++ ".elm"
|
|
||||||
|
|
||||||
get : String -> (Result Error String -> msg) -> Cmd msg
|
|
||||||
get name msg =
|
|
||||||
Http.get
|
|
||||||
{ url = url name
|
|
||||||
, expect =
|
|
||||||
Http.expectString msg
|
|
||||||
}
|
|
||||||
|
|
||||||
toAscii : String -> String
|
|
||||||
toAscii =
|
|
||||||
String.foldr
|
|
||||||
(\char ->
|
|
||||||
(case char of
|
|
||||||
' ' -> "%20"
|
|
||||||
'!' -> "%21"
|
|
||||||
'"' -> "%22"
|
|
||||||
'#' -> "%23"
|
|
||||||
'$' -> "%24"
|
|
||||||
'%' -> "%25"
|
|
||||||
'&' -> "%26"
|
|
||||||
'\'' -> "%27"
|
|
||||||
'(' -> "%28"
|
|
||||||
')' -> "%29"
|
|
||||||
'*' -> "%2A"
|
|
||||||
'+' -> "%2B"
|
|
||||||
',' -> "%2C"
|
|
||||||
'-' -> "%2D"
|
|
||||||
'.' -> "%2E"
|
|
||||||
'/' -> "%2F"
|
|
||||||
':' -> "%3A"
|
|
||||||
';' -> "%3B"
|
|
||||||
'<' -> "%3C"
|
|
||||||
'=' -> "%3D"
|
|
||||||
'>' -> "%3E"
|
|
||||||
'?' -> "%3F"
|
|
||||||
'@' -> "%40"
|
|
||||||
'[' -> "%5B"
|
|
||||||
'\\' -> "%5C"
|
|
||||||
']' -> "%5D"
|
|
||||||
'{' -> "%7B"
|
|
||||||
'|' -> "%7C"
|
|
||||||
'}' -> "%7D"
|
|
||||||
_ -> String.fromChar char
|
|
||||||
)
|
|
||||||
|> String.append
|
|
||||||
)
|
|
||||||
|
|
||||||
replaceModuleName : String -> String
|
|
||||||
replaceModuleName =
|
|
||||||
case String.split "\n" of
|
|
||||||
head :: tail ->
|
|
||||||
toAscii "module Main exposing (main)" :: tail
|
|
||||||
|> String.join "\n"
|
|
||||||
[] -> ""
|
|
||||||
|
|
||||||
generateLink :
|
|
||||||
{ title : String
|
|
||||||
, html : String
|
|
||||||
, packages : List (String,String)
|
|
||||||
, elmVersion : String
|
|
||||||
} -> String -> String
|
|
||||||
generateLink {title,html,packages,elmVersion} elmCode =
|
|
||||||
"https://ellie-app.com/a/example/v1?"
|
|
||||||
++ "title=" ++ toAscii title
|
|
||||||
++ "&elmcode=" ++ toAscii elmCode
|
|
||||||
++ "&packages=" ++ toAscii
|
|
@ -1,792 +0,0 @@
|
|||||||
module Data.Example exposing (Example, Model, Msg, asList, fromString, init, subscriptions, toCardList, toString, update, view)
|
|
||||||
|
|
||||||
import Data.Style exposing (Style)
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Example.AppBar as AppBar
|
|
||||||
import Example.Button as Button
|
|
||||||
import Example.Dialog as Dialog
|
|
||||||
import Example.Icon as Icon
|
|
||||||
import Example.Layout as Layout
|
|
||||||
import Example.List as List
|
|
||||||
import Example.Modal as Modal
|
|
||||||
import Example.MultiSelect as MultiSelect
|
|
||||||
import Example.PasswordInput as PasswordInput
|
|
||||||
import Example.ProgressIndicator as ProgressIndicator
|
|
||||||
import Example.Select as Select
|
|
||||||
import Example.Sheet as Sheet
|
|
||||||
import Example.Snackbar as Snackbar
|
|
||||||
import Example.SortTable as SortTable
|
|
||||||
import Example.Switch as Switch
|
|
||||||
import Example.Tab as Tab
|
|
||||||
import Example.TextInput as TextInput
|
|
||||||
import Framework.Grid as Grid
|
|
||||||
import View.States as States
|
|
||||||
|
|
||||||
|
|
||||||
type Example
|
|
||||||
= ButtonExample
|
|
||||||
| SwitchExample
|
|
||||||
| SelectExample
|
|
||||||
| MultiSelectExample
|
|
||||||
| TabExample
|
|
||||||
| SortTableExample
|
|
||||||
| ModalExample
|
|
||||||
| DialogExample
|
|
||||||
| TextInputExample
|
|
||||||
| PasswordInputExample
|
|
||||||
| ListExample
|
|
||||||
| ProgressIndicatorExample
|
|
||||||
| IconExample
|
|
||||||
| SheetExample
|
|
||||||
| AppBarExample
|
|
||||||
| LayoutExample
|
|
||||||
| SnackbarExample
|
|
||||||
|
|
||||||
|
|
||||||
asList : List Example
|
|
||||||
asList =
|
|
||||||
[ ButtonExample
|
|
||||||
, SwitchExample
|
|
||||||
, SelectExample
|
|
||||||
, MultiSelectExample
|
|
||||||
, TabExample
|
|
||||||
, SortTableExample
|
|
||||||
, ModalExample
|
|
||||||
, DialogExample
|
|
||||||
, TextInputExample
|
|
||||||
, PasswordInputExample
|
|
||||||
, ListExample
|
|
||||||
, ProgressIndicatorExample
|
|
||||||
, IconExample
|
|
||||||
, SheetExample
|
|
||||||
, AppBarExample
|
|
||||||
, LayoutExample
|
|
||||||
, SnackbarExample
|
|
||||||
]
|
|
||||||
|> List.sortBy toString
|
|
||||||
|
|
||||||
|
|
||||||
toString : Example -> String
|
|
||||||
toString example =
|
|
||||||
case example of
|
|
||||||
ButtonExample ->
|
|
||||||
"Button"
|
|
||||||
|
|
||||||
SwitchExample ->
|
|
||||||
"Switch"
|
|
||||||
|
|
||||||
SelectExample ->
|
|
||||||
"Select"
|
|
||||||
|
|
||||||
MultiSelectExample ->
|
|
||||||
"Multi Select"
|
|
||||||
|
|
||||||
TabExample ->
|
|
||||||
"Tab"
|
|
||||||
|
|
||||||
SortTableExample ->
|
|
||||||
"SortTable"
|
|
||||||
|
|
||||||
ModalExample ->
|
|
||||||
"Modal"
|
|
||||||
|
|
||||||
DialogExample ->
|
|
||||||
"Dialog"
|
|
||||||
|
|
||||||
TextInputExample ->
|
|
||||||
"TextInput"
|
|
||||||
|
|
||||||
PasswordInputExample ->
|
|
||||||
"PasswordInput"
|
|
||||||
|
|
||||||
ListExample ->
|
|
||||||
"List"
|
|
||||||
|
|
||||||
ProgressIndicatorExample ->
|
|
||||||
"Progress Indicator"
|
|
||||||
|
|
||||||
IconExample ->
|
|
||||||
"Icon"
|
|
||||||
|
|
||||||
SheetExample ->
|
|
||||||
"Sheet"
|
|
||||||
|
|
||||||
AppBarExample ->
|
|
||||||
"App Bar"
|
|
||||||
|
|
||||||
LayoutExample ->
|
|
||||||
"Layout"
|
|
||||||
|
|
||||||
SnackbarExample ->
|
|
||||||
"Snackbar"
|
|
||||||
|
|
||||||
|
|
||||||
fromString : String -> Maybe Example
|
|
||||||
fromString string =
|
|
||||||
case string of
|
|
||||||
"Button" ->
|
|
||||||
Just ButtonExample
|
|
||||||
|
|
||||||
"Switch" ->
|
|
||||||
Just SwitchExample
|
|
||||||
|
|
||||||
"Select" ->
|
|
||||||
Just SelectExample
|
|
||||||
|
|
||||||
"Multi Select" ->
|
|
||||||
Just MultiSelectExample
|
|
||||||
|
|
||||||
"Tab" ->
|
|
||||||
Just TabExample
|
|
||||||
|
|
||||||
"SortTable" ->
|
|
||||||
Just SortTableExample
|
|
||||||
|
|
||||||
"Modal" ->
|
|
||||||
Just ModalExample
|
|
||||||
|
|
||||||
"Dialog" ->
|
|
||||||
Just DialogExample
|
|
||||||
|
|
||||||
"TextInput" ->
|
|
||||||
Just TextInputExample
|
|
||||||
|
|
||||||
"PasswordInput" ->
|
|
||||||
Just PasswordInputExample
|
|
||||||
|
|
||||||
"List" ->
|
|
||||||
Just ListExample
|
|
||||||
|
|
||||||
"Progress Indicator" ->
|
|
||||||
Just ProgressIndicatorExample
|
|
||||||
|
|
||||||
"Icon" ->
|
|
||||||
Just IconExample
|
|
||||||
|
|
||||||
"Sheet" ->
|
|
||||||
Just SheetExample
|
|
||||||
|
|
||||||
"App Bar" ->
|
|
||||||
Just AppBarExample
|
|
||||||
|
|
||||||
"Layout" ->
|
|
||||||
Just LayoutExample
|
|
||||||
|
|
||||||
"Snackbar" ->
|
|
||||||
Just SnackbarExample
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
Nothing
|
|
||||||
|
|
||||||
|
|
||||||
get : Example -> ExampleView msg -> Element msg
|
|
||||||
get example =
|
|
||||||
case example of
|
|
||||||
ButtonExample ->
|
|
||||||
.button
|
|
||||||
|
|
||||||
SwitchExample ->
|
|
||||||
.switch
|
|
||||||
|
|
||||||
SelectExample ->
|
|
||||||
.select
|
|
||||||
|
|
||||||
MultiSelectExample ->
|
|
||||||
.multiSelect
|
|
||||||
|
|
||||||
TabExample ->
|
|
||||||
.tab
|
|
||||||
|
|
||||||
SortTableExample ->
|
|
||||||
.sortTable
|
|
||||||
|
|
||||||
ModalExample ->
|
|
||||||
.modal
|
|
||||||
|
|
||||||
DialogExample ->
|
|
||||||
.dialog
|
|
||||||
|
|
||||||
TextInputExample ->
|
|
||||||
.textInput
|
|
||||||
|
|
||||||
PasswordInputExample ->
|
|
||||||
.passwordInput
|
|
||||||
|
|
||||||
ListExample ->
|
|
||||||
.list
|
|
||||||
|
|
||||||
ProgressIndicatorExample ->
|
|
||||||
.progressIndicator
|
|
||||||
|
|
||||||
IconExample ->
|
|
||||||
.icon
|
|
||||||
|
|
||||||
SheetExample ->
|
|
||||||
.sheet
|
|
||||||
|
|
||||||
AppBarExample ->
|
|
||||||
.appBar
|
|
||||||
|
|
||||||
LayoutExample ->
|
|
||||||
.layout
|
|
||||||
|
|
||||||
SnackbarExample ->
|
|
||||||
.snackbar
|
|
||||||
|
|
||||||
|
|
||||||
toTests : Example -> msg -> Style msg -> List ( String, Element msg )
|
|
||||||
toTests example =
|
|
||||||
case example of
|
|
||||||
ButtonExample ->
|
|
||||||
States.button
|
|
||||||
|
|
||||||
SwitchExample ->
|
|
||||||
States.switch
|
|
||||||
|
|
||||||
SelectExample ->
|
|
||||||
States.select
|
|
||||||
|
|
||||||
MultiSelectExample ->
|
|
||||||
States.multiSelect
|
|
||||||
|
|
||||||
TabExample ->
|
|
||||||
States.tab
|
|
||||||
|
|
||||||
SortTableExample ->
|
|
||||||
States.sortTable
|
|
||||||
|
|
||||||
ModalExample ->
|
|
||||||
States.modal
|
|
||||||
|
|
||||||
DialogExample ->
|
|
||||||
States.dialog
|
|
||||||
|
|
||||||
TextInputExample ->
|
|
||||||
States.textInput
|
|
||||||
|
|
||||||
PasswordInputExample ->
|
|
||||||
States.passwordInput
|
|
||||||
|
|
||||||
ListExample ->
|
|
||||||
States.list
|
|
||||||
|
|
||||||
ProgressIndicatorExample ->
|
|
||||||
States.progressIndicator
|
|
||||||
|
|
||||||
IconExample ->
|
|
||||||
States.icon
|
|
||||||
|
|
||||||
SheetExample ->
|
|
||||||
States.sheet
|
|
||||||
|
|
||||||
AppBarExample ->
|
|
||||||
States.appBar
|
|
||||||
|
|
||||||
LayoutExample ->
|
|
||||||
States.layout
|
|
||||||
|
|
||||||
SnackbarExample ->
|
|
||||||
States.snackbar
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= Button Button.Msg
|
|
||||||
| Switch Switch.Msg
|
|
||||||
| Select Select.Msg
|
|
||||||
| MultiSelect MultiSelect.Msg
|
|
||||||
| Tab Tab.Msg
|
|
||||||
| SortTable SortTable.Msg
|
|
||||||
| Modal Modal.Msg
|
|
||||||
| Dialog Dialog.Msg
|
|
||||||
| TextInput TextInput.Msg
|
|
||||||
| PasswordInput PasswordInput.Msg
|
|
||||||
| List List.Msg
|
|
||||||
| ProgressIndicator ProgressIndicator.Msg
|
|
||||||
| Icon Icon.Msg
|
|
||||||
| Sheet Sheet.Msg
|
|
||||||
| AppBar AppBar.Msg
|
|
||||||
| Layout Layout.Msg
|
|
||||||
| Snackbar Snackbar.Msg
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ button : Button.Model
|
|
||||||
, switch : Switch.Model
|
|
||||||
, select : Select.Model
|
|
||||||
, multiSelect : MultiSelect.Model
|
|
||||||
, tab : Tab.Model
|
|
||||||
, sortTable : SortTable.Model
|
|
||||||
, modal : Modal.Model
|
|
||||||
, dialog : Dialog.Model
|
|
||||||
, textInput : TextInput.Model
|
|
||||||
, passwordInput : PasswordInput.Model
|
|
||||||
, list : List.Model
|
|
||||||
, progressIndicator : ProgressIndicator.Model
|
|
||||||
, icon : Icon.Model
|
|
||||||
, sheet : Sheet.Model
|
|
||||||
, appBar : AppBar.Model
|
|
||||||
, layout : Layout.Model
|
|
||||||
, snackbar : Snackbar.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
|
|
||||||
, switch : UpgradeRecord Switch.Model Switch.Msg
|
|
||||||
, select : UpgradeRecord Select.Model Select.Msg
|
|
||||||
, multiSelect : UpgradeRecord MultiSelect.Model MultiSelect.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
|
|
||||||
, passwordInput : UpgradeRecord PasswordInput.Model PasswordInput.Msg
|
|
||||||
, list : UpgradeRecord List.Model List.Msg
|
|
||||||
, progressIndicator : UpgradeRecord ProgressIndicator.Model ProgressIndicator.Msg
|
|
||||||
, icon : UpgradeRecord Icon.Model Icon.Msg
|
|
||||||
, sheet : UpgradeRecord Sheet.Model Sheet.Msg
|
|
||||||
, appBar : UpgradeRecord AppBar.Model AppBar.Msg
|
|
||||||
, layout : UpgradeRecord Layout.Model Layout.Msg
|
|
||||||
, snackbar : UpgradeRecord Snackbar.Model Snackbar.Msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias ExampleView msg =
|
|
||||||
{ button : Element msg
|
|
||||||
, switch : Element msg
|
|
||||||
, select : Element msg
|
|
||||||
, multiSelect : Element msg
|
|
||||||
, tab : Element msg
|
|
||||||
, sortTable : Element msg
|
|
||||||
, modal : Element msg
|
|
||||||
, dialog : Element msg
|
|
||||||
, textInput : Element msg
|
|
||||||
, passwordInput : Element msg
|
|
||||||
, list : Element msg
|
|
||||||
, progressIndicator : Element msg
|
|
||||||
, icon : Element msg
|
|
||||||
, sheet : Element msg
|
|
||||||
, appBar : Element msg
|
|
||||||
, layout : Element msg
|
|
||||||
, snackbar : Element msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
let
|
|
||||||
( buttonModel, buttonMsg ) =
|
|
||||||
Button.init
|
|
||||||
|
|
||||||
( switchModel, switchMsg ) =
|
|
||||||
Switch.init
|
|
||||||
|
|
||||||
( selectModel, selectMsg ) =
|
|
||||||
Select.init
|
|
||||||
|
|
||||||
( multiSelectModel, multiSelectMsg ) =
|
|
||||||
MultiSelect.init
|
|
||||||
|
|
||||||
( tabModel, tabMsg ) =
|
|
||||||
Tab.init
|
|
||||||
|
|
||||||
( sortTableModel, sortTableMsg ) =
|
|
||||||
SortTable.init
|
|
||||||
|
|
||||||
( modalModel, modalMsg ) =
|
|
||||||
Modal.init
|
|
||||||
|
|
||||||
( dialogModel, dialogMsg ) =
|
|
||||||
Dialog.init
|
|
||||||
|
|
||||||
( textInputModel, textInputMsg ) =
|
|
||||||
TextInput.init
|
|
||||||
|
|
||||||
( passwordInputModel, passwordInputMsg ) =
|
|
||||||
PasswordInput.init
|
|
||||||
|
|
||||||
( listModel, listMsg ) =
|
|
||||||
List.init
|
|
||||||
|
|
||||||
( progressIndicatorModel, progressIndicatorMsg ) =
|
|
||||||
ProgressIndicator.init
|
|
||||||
|
|
||||||
( iconModel, iconMsg ) =
|
|
||||||
Icon.init
|
|
||||||
|
|
||||||
( sheetModel, sheetMsg ) =
|
|
||||||
Sheet.init
|
|
||||||
|
|
||||||
( appBarModel, appBarMsg ) =
|
|
||||||
AppBar.init
|
|
||||||
|
|
||||||
( layoutModel, layoutMsg ) =
|
|
||||||
Layout.init
|
|
||||||
|
|
||||||
( snackbarModel, snackbarMsg ) =
|
|
||||||
Snackbar.init
|
|
||||||
in
|
|
||||||
( { button = buttonModel
|
|
||||||
, switch = switchModel
|
|
||||||
, select = selectModel
|
|
||||||
, multiSelect = multiSelectModel
|
|
||||||
, tab = tabModel
|
|
||||||
, sortTable = sortTableModel
|
|
||||||
, modal = modalModel
|
|
||||||
, dialog = dialogModel
|
|
||||||
, textInput = textInputModel
|
|
||||||
, passwordInput = passwordInputModel
|
|
||||||
, list = listModel
|
|
||||||
, progressIndicator = progressIndicatorModel
|
|
||||||
, icon = iconModel
|
|
||||||
, sheet = sheetModel
|
|
||||||
, appBar = appBarModel
|
|
||||||
, layout = layoutModel
|
|
||||||
, snackbar = snackbarModel
|
|
||||||
}
|
|
||||||
, [ Cmd.map Button buttonMsg
|
|
||||||
, Cmd.map Switch switchMsg
|
|
||||||
, Cmd.map Select selectMsg
|
|
||||||
, Cmd.map MultiSelect multiSelectMsg
|
|
||||||
, Cmd.map Tab tabMsg
|
|
||||||
, Cmd.map SortTable sortTableMsg
|
|
||||||
, Cmd.map Modal modalMsg
|
|
||||||
, Cmd.map Dialog dialogMsg
|
|
||||||
, Cmd.map TextInput textInputMsg
|
|
||||||
, Cmd.map PasswordInput passwordInputMsg
|
|
||||||
, Cmd.map List listMsg
|
|
||||||
, Cmd.map ProgressIndicator progressIndicatorMsg
|
|
||||||
, Cmd.map Icon iconMsg
|
|
||||||
, Cmd.map Sheet sheetMsg
|
|
||||||
, Cmd.map AppBar appBarMsg
|
|
||||||
, Cmd.map Layout layoutMsg
|
|
||||||
, Cmd.map Snackbar snackbarMsg
|
|
||||||
]
|
|
||||||
|> Cmd.batch
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
upgradeRecord : UpgradeCollection
|
|
||||||
upgradeRecord =
|
|
||||||
{ button =
|
|
||||||
{ from = .button
|
|
||||||
, to = \model a -> { model | button = a }
|
|
||||||
, msgMapper = Button
|
|
||||||
, updateFun = Button.update
|
|
||||||
, subscriptionsFun = Button.subscriptions
|
|
||||||
}
|
|
||||||
, switch =
|
|
||||||
{ from = .switch
|
|
||||||
, to = \model a -> { model | switch = a }
|
|
||||||
, msgMapper = Switch
|
|
||||||
, updateFun = Switch.update
|
|
||||||
, subscriptionsFun = Switch.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
|
|
||||||
}
|
|
||||||
, 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
|
|
||||||
}
|
|
||||||
, passwordInput =
|
|
||||||
{ from = .passwordInput
|
|
||||||
, to = \model a -> { model | passwordInput = a }
|
|
||||||
, msgMapper = PasswordInput
|
|
||||||
, updateFun = PasswordInput.update
|
|
||||||
, subscriptionsFun = PasswordInput.subscriptions
|
|
||||||
}
|
|
||||||
, list =
|
|
||||||
{ from = .list
|
|
||||||
, to = \model a -> { model | list = a }
|
|
||||||
, msgMapper = List
|
|
||||||
, updateFun = List.update
|
|
||||||
, subscriptionsFun = List.subscriptions
|
|
||||||
}
|
|
||||||
, progressIndicator =
|
|
||||||
{ from = .progressIndicator
|
|
||||||
, to = \model a -> { model | progressIndicator = a }
|
|
||||||
, msgMapper = ProgressIndicator
|
|
||||||
, updateFun = ProgressIndicator.update
|
|
||||||
, subscriptionsFun = ProgressIndicator.subscriptions
|
|
||||||
}
|
|
||||||
, icon =
|
|
||||||
{ from = .icon
|
|
||||||
, to = \model a -> { model | icon = a }
|
|
||||||
, msgMapper = Icon
|
|
||||||
, updateFun = Icon.update
|
|
||||||
, subscriptionsFun = Icon.subscriptions
|
|
||||||
}
|
|
||||||
, sheet =
|
|
||||||
{ from = .sheet
|
|
||||||
, to = \model a -> { model | sheet = a }
|
|
||||||
, msgMapper = Sheet
|
|
||||||
, updateFun = Sheet.update
|
|
||||||
, subscriptionsFun = Sheet.subscriptions
|
|
||||||
}
|
|
||||||
, appBar =
|
|
||||||
{ from = .appBar
|
|
||||||
, to = \model a -> { model | appBar = a }
|
|
||||||
, msgMapper = AppBar
|
|
||||||
, updateFun = AppBar.update
|
|
||||||
, subscriptionsFun = AppBar.subscriptions
|
|
||||||
}
|
|
||||||
, layout =
|
|
||||||
{ from = .layout
|
|
||||||
, to = \model a -> { model | layout = a }
|
|
||||||
, msgMapper = Layout
|
|
||||||
, updateFun = Layout.update
|
|
||||||
, subscriptionsFun = Layout.subscriptions
|
|
||||||
}
|
|
||||||
, snackbar =
|
|
||||||
{ from = .snackbar
|
|
||||||
, to = \model a -> { model | snackbar = a }
|
|
||||||
, msgMapper = Snackbar
|
|
||||||
, updateFun = Snackbar.update
|
|
||||||
, subscriptionsFun = Snackbar.subscriptions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
(case msg of
|
|
||||||
Button m ->
|
|
||||||
updateField .button m
|
|
||||||
|
|
||||||
Switch m ->
|
|
||||||
updateField .switch m
|
|
||||||
|
|
||||||
Select m ->
|
|
||||||
updateField .select m
|
|
||||||
|
|
||||||
MultiSelect m ->
|
|
||||||
updateField .multiSelect m
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
PasswordInput m ->
|
|
||||||
updateField .passwordInput m
|
|
||||||
|
|
||||||
List m ->
|
|
||||||
updateField .list m
|
|
||||||
|
|
||||||
ProgressIndicator m ->
|
|
||||||
updateField .progressIndicator m
|
|
||||||
|
|
||||||
Icon m ->
|
|
||||||
updateField .icon m
|
|
||||||
|
|
||||||
Sheet m ->
|
|
||||||
updateField .sheet m
|
|
||||||
|
|
||||||
AppBar m ->
|
|
||||||
updateField .appBar m
|
|
||||||
|
|
||||||
Layout m ->
|
|
||||||
updateField .layout m
|
|
||||||
|
|
||||||
Snackbar m ->
|
|
||||||
updateField .snackbar m
|
|
||||||
)
|
|
||||||
model
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions model =
|
|
||||||
let
|
|
||||||
subFun { from, msgMapper, subscriptionsFun } =
|
|
||||||
subscriptionsFun (from model) |> Sub.map msgMapper
|
|
||||||
in
|
|
||||||
[ upgradeRecord.button |> subFun
|
|
||||||
, upgradeRecord.switch |> subFun
|
|
||||||
, upgradeRecord.select |> subFun
|
|
||||||
, upgradeRecord.multiSelect |> subFun
|
|
||||||
, upgradeRecord.tab |> subFun
|
|
||||||
, upgradeRecord.sortTable |> subFun
|
|
||||||
, upgradeRecord.modal |> subFun
|
|
||||||
, upgradeRecord.dialog |> subFun
|
|
||||||
, upgradeRecord.textInput |> subFun
|
|
||||||
, upgradeRecord.passwordInput |> subFun
|
|
||||||
, upgradeRecord.list |> subFun
|
|
||||||
, upgradeRecord.progressIndicator |> subFun
|
|
||||||
, upgradeRecord.icon |> subFun
|
|
||||||
, upgradeRecord.sheet |> subFun
|
|
||||||
, upgradeRecord.appBar |> subFun
|
|
||||||
, upgradeRecord.layout |> subFun
|
|
||||||
, upgradeRecord.snackbar |> subFun
|
|
||||||
]
|
|
||||||
|> Sub.batch
|
|
||||||
|
|
||||||
|
|
||||||
view :
|
|
||||||
(Msg -> msg)
|
|
||||||
-> Style msg
|
|
||||||
-> Model
|
|
||||||
-> ExampleView msg
|
|
||||||
view msgMapper style model =
|
|
||||||
{ button =
|
|
||||||
Button.view (Button >> msgMapper) style (.button model)
|
|
||||||
, switch =
|
|
||||||
Switch.view (Switch >> msgMapper) style (.switch model)
|
|
||||||
, select =
|
|
||||||
Select.view (Select >> msgMapper) style (.select model)
|
|
||||||
, multiSelect =
|
|
||||||
MultiSelect.view (MultiSelect >> msgMapper) style (.multiSelect 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)
|
|
||||||
, passwordInput =
|
|
||||||
PasswordInput.view (PasswordInput >> msgMapper) style (.passwordInput model)
|
|
||||||
, list =
|
|
||||||
List.view (List >> msgMapper) style (.list model)
|
|
||||||
, progressIndicator =
|
|
||||||
ProgressIndicator.view (ProgressIndicator >> msgMapper) style (.progressIndicator model)
|
|
||||||
, icon =
|
|
||||||
Icon.view (Icon >> msgMapper) style (.icon model)
|
|
||||||
, sheet =
|
|
||||||
Sheet.view (Sheet >> msgMapper) style (.sheet model)
|
|
||||||
, appBar =
|
|
||||||
AppBar.view (AppBar >> msgMapper) style (.appBar model)
|
|
||||||
, layout =
|
|
||||||
Layout.view (Layout >> msgMapper) style (.layout model)
|
|
||||||
, snackbar =
|
|
||||||
Snackbar.view (Snackbar >> msgMapper) style (.snackbar model)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
-- DO NOT CHANGE ANYTHING AFTER THIS
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
toCardList :
|
|
||||||
{ idle : msg
|
|
||||||
, msgMapper : Msg -> msg
|
|
||||||
, style : Style msg
|
|
||||||
, model : Model
|
|
||||||
}
|
|
||||||
-> List ( String, Element msg, List (Element msg) )
|
|
||||||
toCardList { idle, msgMapper, style, model } =
|
|
||||||
asList
|
|
||||||
|> List.map
|
|
||||||
(\example ->
|
|
||||||
{ title = example |> toString
|
|
||||||
, example = example |> get
|
|
||||||
, test = example |> toTests
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> List.map
|
|
||||||
(\{ title, example, test } ->
|
|
||||||
( title
|
|
||||||
, model
|
|
||||||
|> view msgMapper style
|
|
||||||
|> example
|
|
||||||
, test idle style
|
|
||||||
|> List.map
|
|
||||||
(\( name, elem ) ->
|
|
||||||
Element.row Grid.spacedEvenly
|
|
||||||
[ name
|
|
||||||
|> Element.text
|
|
||||||
|> List.singleton
|
|
||||||
|> Element.wrappedRow [ Element.width <| Element.shrink ]
|
|
||||||
, elem
|
|
||||||
|> Element.el
|
|
||||||
[ Element.paddingEach
|
|
||||||
{ top = 0
|
|
||||||
, right = 0
|
|
||||||
, bottom = 0
|
|
||||||
, left = 8
|
|
||||||
}
|
|
||||||
, Element.width <| Element.shrink
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
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,34 +0,0 @@
|
|||||||
module Data.Section exposing (Section(..), asList, fromString, toString)
|
|
||||||
|
|
||||||
|
|
||||||
type Section
|
|
||||||
= ReusableViews
|
|
||||||
| StatelessViews
|
|
||||||
|
|
||||||
|
|
||||||
asList : List Section
|
|
||||||
asList =
|
|
||||||
[ StatelessViews, ReusableViews ]
|
|
||||||
|
|
||||||
|
|
||||||
toString : Section -> String
|
|
||||||
toString section =
|
|
||||||
case section of
|
|
||||||
ReusableViews ->
|
|
||||||
"Reusable"
|
|
||||||
|
|
||||||
StatelessViews ->
|
|
||||||
"Stateless"
|
|
||||||
|
|
||||||
|
|
||||||
fromString : String -> Maybe Section
|
|
||||||
fromString string =
|
|
||||||
case string of
|
|
||||||
"Reusable" ->
|
|
||||||
Just ReusableViews
|
|
||||||
|
|
||||||
"Stateless" ->
|
|
||||||
Just StatelessViews
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
Nothing
|
|
@ -1,154 +0,0 @@
|
|||||||
module Data.Style exposing (Style, style)
|
|
||||||
|
|
||||||
import Element exposing (Attribute)
|
|
||||||
import Element.Border as Border
|
|
||||||
import Element.Font as Font
|
|
||||||
import Widget
|
|
||||||
exposing
|
|
||||||
( AppBarStyle
|
|
||||||
, ButtonStyle
|
|
||||||
, ColumnStyle
|
|
||||||
, DialogStyle
|
|
||||||
, DividerStyle
|
|
||||||
, ExpansionItemStyle
|
|
||||||
, FullBleedItemStyle
|
|
||||||
, HeaderStyle
|
|
||||||
, ImageItemStyle
|
|
||||||
, InsetItemStyle
|
|
||||||
, ItemStyle
|
|
||||||
, MultiLineItemStyle
|
|
||||||
, PasswordInputStyle
|
|
||||||
, ProgressIndicatorStyle
|
|
||||||
, RowStyle
|
|
||||||
, SortTableStyle
|
|
||||||
, SwitchStyle
|
|
||||||
, TabStyle
|
|
||||||
, TextInputStyle
|
|
||||||
)
|
|
||||||
import Widget.Icon exposing (Icon)
|
|
||||||
import Widget.Material as Material exposing (Palette)
|
|
||||||
import Widget.Material.Color as MaterialColor
|
|
||||||
import Widget.Snackbar exposing (SnackbarStyle)
|
|
||||||
|
|
||||||
|
|
||||||
style : Palette -> Style msg
|
|
||||||
style palette =
|
|
||||||
{ container =
|
|
||||||
(Material.defaultPalette.background |> MaterialColor.textAndBackground)
|
|
||||||
++ [ Font.family
|
|
||||||
[ Font.typeface "Roboto"
|
|
||||||
, Font.sansSerif
|
|
||||||
]
|
|
||||||
, Font.size 16
|
|
||||||
, Font.letterSpacing 0.5
|
|
||||||
]
|
|
||||||
, containedButton = Material.containedButton Material.defaultPalette
|
|
||||||
, outlinedButton = Material.outlinedButton Material.defaultPalette
|
|
||||||
, textButton = Material.textButton Material.defaultPalette
|
|
||||||
, iconButton = Material.iconButton Material.defaultPalette
|
|
||||||
, sortTable = Material.sortTable palette
|
|
||||||
, row = Material.row
|
|
||||||
, buttonRow = Material.buttonRow
|
|
||||||
, cardColumn = Material.cardColumn palette
|
|
||||||
, column = Material.column
|
|
||||||
, button = Material.outlinedButton palette
|
|
||||||
, primaryButton = Material.containedButton palette
|
|
||||||
, selectButton = Material.toggleButton palette
|
|
||||||
, tab = Material.tab palette
|
|
||||||
, textInput = Material.textInput palette
|
|
||||||
, passwordInput = Material.passwordInput palette
|
|
||||||
, chipButton = Material.chip palette
|
|
||||||
, dialog = Material.alertDialog palette
|
|
||||||
, progressIndicator = Material.progressIndicator palette
|
|
||||||
, switch = Material.switch palette
|
|
||||||
, fullBleedDivider = Material.fullBleedDivider palette
|
|
||||||
, insetDivider = Material.insetDivider palette
|
|
||||||
, middleDivider = Material.middleDivider palette
|
|
||||||
, insetHeader = Material.insetHeader palette
|
|
||||||
, fullBleedHeader = Material.fullBleedHeader palette
|
|
||||||
, insetItem = Material.insetItem palette
|
|
||||||
, multiLineItem = Material.multiLineItem palette
|
|
||||||
, imageItem = Material.imageItem palette
|
|
||||||
, expansionItem = Material.expansionItem palette
|
|
||||||
, sideSheet = Material.sideSheet palette
|
|
||||||
, fullBleedItem = Material.fullBleedItem Material.defaultPalette
|
|
||||||
, selectItem = Material.selectItem Material.defaultPalette
|
|
||||||
, menuBar = Material.menuBar Material.defaultPalette
|
|
||||||
, tabBar = Material.tabBar Material.defaultPalette
|
|
||||||
, sheetButton = Material.selectItem Material.defaultPalette
|
|
||||||
, searchFill =
|
|
||||||
{ elementRow =
|
|
||||||
(Material.defaultPalette.surface
|
|
||||||
|> MaterialColor.textAndBackground
|
|
||||||
)
|
|
||||||
++ [ Element.height <| Element.px 56 ]
|
|
||||||
, content =
|
|
||||||
{ chips =
|
|
||||||
{ elementRow = [ Element.spacing 8 ]
|
|
||||||
, content = Material.chip Material.defaultPalette
|
|
||||||
}
|
|
||||||
, text =
|
|
||||||
{ elementTextInput =
|
|
||||||
(Material.defaultPalette.surface
|
|
||||||
|> MaterialColor.textAndBackground
|
|
||||||
)
|
|
||||||
++ [ Border.width 0
|
|
||||||
, Element.mouseOver []
|
|
||||||
, Element.focused []
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, snackbar = Material.snackbar Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style msg =
|
|
||||||
{ container : List (Attribute msg)
|
|
||||||
, containedButton : ButtonStyle msg
|
|
||||||
, outlinedButton : ButtonStyle msg
|
|
||||||
, textButton : ButtonStyle msg
|
|
||||||
, iconButton : ButtonStyle msg
|
|
||||||
, dialog : DialogStyle msg
|
|
||||||
, button : ButtonStyle msg
|
|
||||||
, switch : SwitchStyle msg
|
|
||||||
, primaryButton : ButtonStyle msg
|
|
||||||
, tab : TabStyle msg
|
|
||||||
, textInput : TextInputStyle msg
|
|
||||||
, passwordInput : PasswordInputStyle msg
|
|
||||||
, chipButton : ButtonStyle msg
|
|
||||||
, row : RowStyle msg
|
|
||||||
, buttonRow : RowStyle msg
|
|
||||||
, column : ColumnStyle msg
|
|
||||||
, cardColumn : ColumnStyle msg
|
|
||||||
, sortTable : SortTableStyle msg
|
|
||||||
, selectButton : ButtonStyle msg
|
|
||||||
, progressIndicator : ProgressIndicatorStyle msg
|
|
||||||
, insetDivider : ItemStyle (DividerStyle msg) msg
|
|
||||||
, middleDivider : ItemStyle (DividerStyle msg) msg
|
|
||||||
, fullBleedDivider : ItemStyle (DividerStyle msg) msg
|
|
||||||
, insetHeader : ItemStyle (HeaderStyle msg) msg
|
|
||||||
, fullBleedHeader : ItemStyle (HeaderStyle msg) msg
|
|
||||||
, insetItem : ItemStyle (InsetItemStyle msg) msg
|
|
||||||
, multiLineItem : ItemStyle (MultiLineItemStyle msg) msg
|
|
||||||
, imageItem : ItemStyle (ImageItemStyle msg) msg
|
|
||||||
, expansionItem : ExpansionItemStyle msg
|
|
||||||
, sideSheet : ColumnStyle msg
|
|
||||||
, fullBleedItem : ItemStyle (FullBleedItemStyle msg) msg
|
|
||||||
, selectItem : ItemStyle (ButtonStyle msg) msg
|
|
||||||
, menuBar :
|
|
||||||
AppBarStyle
|
|
||||||
{ menuIcon : Icon msg
|
|
||||||
, title : List (Attribute msg)
|
|
||||||
}
|
|
||||||
msg
|
|
||||||
, tabBar :
|
|
||||||
AppBarStyle
|
|
||||||
{ menuTabButton : ButtonStyle msg
|
|
||||||
, title : List (Attribute msg)
|
|
||||||
}
|
|
||||||
msg
|
|
||||||
, sheetButton : ItemStyle (ButtonStyle msg) msg
|
|
||||||
, searchFill : TextInputStyle msg
|
|
||||||
, snackbar : SnackbarStyle msg
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
module Data.Theme exposing (Theme(..), toStyle)
|
|
||||||
|
|
||||||
import Data.Style as Style exposing (Style)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type Theme
|
|
||||||
= Material
|
|
||||||
| DarkMaterial
|
|
||||||
|
|
||||||
|
|
||||||
toStyle : Theme -> Style msg
|
|
||||||
toStyle theme =
|
|
||||||
case theme of
|
|
||||||
Material ->
|
|
||||||
Style.style Material.defaultPalette
|
|
||||||
|
|
||||||
DarkMaterial ->
|
|
||||||
Style.style Material.darkPalette
|
|
@ -1,155 +0,0 @@
|
|||||||
module Example.AppBar exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Attribute, DeviceClass(..), Element)
|
|
||||||
import Material.Icons
|
|
||||||
import Material.Icons.Types exposing (Coloring(..))
|
|
||||||
import Widget exposing (AppBarStyle, ButtonStyle)
|
|
||||||
import Widget.Icon as Icon exposing (Icon)
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Widget.Material.Typography as Typography
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| menuBar :
|
|
||||||
AppBarStyle
|
|
||||||
{ menuIcon : Icon msg
|
|
||||||
, title : List (Attribute msg)
|
|
||||||
}
|
|
||||||
msg
|
|
||||||
, tabBar :
|
|
||||||
AppBarStyle
|
|
||||||
{ menuTabButton : ButtonStyle msg
|
|
||||||
, title : List (Attribute msg)
|
|
||||||
}
|
|
||||||
msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ menuBar = Material.menuBar Material.defaultPalette
|
|
||||||
, tabBar = Material.tabBar Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ isMenuBar : Bool
|
|
||||||
, selected : Int
|
|
||||||
, search : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= SetDesign Bool
|
|
||||||
| SetSelected Int
|
|
||||||
| SetSearch String
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( { isMenuBar = True
|
|
||||||
, selected = 0
|
|
||||||
, search = ""
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg menu =
|
|
||||||
case msg of
|
|
||||||
SetDesign bool ->
|
|
||||||
( { menu | isMenuBar = bool }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
SetSelected int ->
|
|
||||||
( { menu | selected = int }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
SetSearch string ->
|
|
||||||
( { menu | search = string }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style model =
|
|
||||||
let
|
|
||||||
primaryActions =
|
|
||||||
[ { icon =
|
|
||||||
Material.Icons.change_history
|
|
||||||
|> Icon.elmMaterialIcons Color
|
|
||||||
, text = "Action"
|
|
||||||
, onPress = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
search =
|
|
||||||
{ chips = []
|
|
||||||
, text = model.search
|
|
||||||
, placeholder = Nothing
|
|
||||||
, label = "Search"
|
|
||||||
, onChange = SetSearch >> msgMapper
|
|
||||||
}
|
|
||||||
in
|
|
||||||
(if model.isMenuBar then
|
|
||||||
Widget.menuBar style.menuBar
|
|
||||||
{ title =
|
|
||||||
"Title"
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el Typography.h6
|
|
||||||
, deviceClass = Tablet
|
|
||||||
, openLeftSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
|
||||||
, openRightSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
|
||||||
, openTopSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
|
||||||
, primaryActions = primaryActions
|
|
||||||
, search = Just search
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
Widget.tabBar style.tabBar
|
|
||||||
{ title =
|
|
||||||
"Title"
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el Typography.h6
|
|
||||||
, menu =
|
|
||||||
{ selected = Just model.selected
|
|
||||||
, options =
|
|
||||||
[ "Home", "About" ]
|
|
||||||
|> List.map
|
|
||||||
(\string ->
|
|
||||||
{ text = string
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = SetSelected >> msgMapper >> Just
|
|
||||||
}
|
|
||||||
, deviceClass = Phone
|
|
||||||
, openRightSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
|
||||||
, openTopSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
|
||||||
, primaryActions = primaryActions
|
|
||||||
, search = Just search
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Element.el [ Element.width <| Element.minimum 400 <| Element.fill ]
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,182 +0,0 @@
|
|||||||
module Example.Button exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Element.Background as Background
|
|
||||||
import Material.Icons as MaterialIcons
|
|
||||||
import Material.Icons.Types exposing (Coloring(..))
|
|
||||||
import Widget exposing (ButtonStyle, ColumnStyle, RowStyle)
|
|
||||||
import Widget.Customize as Customize
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Widget.Material.Color as MaterialColor
|
|
||||||
import Widget.Material.Typography as Typography
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| containedButton : ButtonStyle msg
|
|
||||||
, outlinedButton : ButtonStyle msg
|
|
||||||
, textButton : ButtonStyle msg
|
|
||||||
, iconButton : ButtonStyle msg
|
|
||||||
, row : RowStyle msg
|
|
||||||
, column : ColumnStyle msg
|
|
||||||
, cardColumn : ColumnStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ containedButton = Material.containedButton Material.defaultPalette
|
|
||||||
, outlinedButton = Material.outlinedButton Material.defaultPalette
|
|
||||||
, textButton = Material.textButton Material.defaultPalette
|
|
||||||
, iconButton = Material.iconButton Material.defaultPalette
|
|
||||||
, row = Material.row
|
|
||||||
, column = Material.column
|
|
||||||
, cardColumn = Material.cardColumn Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
Int
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= Increase Int
|
|
||||||
| Decrease Int
|
|
||||||
| Reset
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( 0
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
case msg of
|
|
||||||
Increase int ->
|
|
||||||
( model + int
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Decrease int ->
|
|
||||||
( if (model - int) >= 0 then
|
|
||||||
model - int
|
|
||||||
|
|
||||||
else
|
|
||||||
model
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Reset ->
|
|
||||||
( 0
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style model =
|
|
||||||
[ model
|
|
||||||
|> String.fromInt
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el
|
|
||||||
(Typography.h4
|
|
||||||
++ [ Element.centerX, Element.centerY ]
|
|
||||||
)
|
|
||||||
|> List.singleton
|
|
||||||
|> Widget.column
|
|
||||||
(style.cardColumn
|
|
||||||
|> Customize.elementColumn
|
|
||||||
[ Element.centerX
|
|
||||||
, Element.width <| Element.px 128
|
|
||||||
, Element.height <| Element.px 128
|
|
||||||
, Widget.iconButton style.iconButton
|
|
||||||
{ text = "+2"
|
|
||||||
, icon =
|
|
||||||
MaterialIcons.exposure_plus_2
|
|
||||||
|> Icon.elmMaterialIcons Color
|
|
||||||
, onPress =
|
|
||||||
Increase 2
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
|> Element.el [ Element.alignRight ]
|
|
||||||
|> Element.inFront
|
|
||||||
]
|
|
||||||
|> Customize.mapContent
|
|
||||||
(Customize.element
|
|
||||||
[ Element.width <| Element.px 128
|
|
||||||
, Element.height <| Element.px 128
|
|
||||||
, Material.defaultPalette.secondary
|
|
||||||
|> MaterialColor.fromColor
|
|
||||||
|> Background.color
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
, [ [ Widget.textButton style.textButton
|
|
||||||
{ text = "Reset"
|
|
||||||
, onPress =
|
|
||||||
Reset
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
, Widget.button style.outlinedButton
|
|
||||||
{ text = "Decrease"
|
|
||||||
, icon =
|
|
||||||
MaterialIcons.remove
|
|
||||||
|> Icon.elmMaterialIcons Color
|
|
||||||
, onPress =
|
|
||||||
if model > 0 then
|
|
||||||
Decrease 1
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Widget.row (style.row |> Customize.elementRow [ Element.alignRight ])
|
|
||||||
, [ Widget.button style.containedButton
|
|
||||||
{ text = "Increase"
|
|
||||||
, icon =
|
|
||||||
MaterialIcons.add
|
|
||||||
|> Icon.elmMaterialIcons Color
|
|
||||||
, onPress =
|
|
||||||
Increase 1
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Widget.row (style.row |> Customize.elementRow [ Element.alignLeft ])
|
|
||||||
]
|
|
||||||
|> Widget.row
|
|
||||||
(style.row
|
|
||||||
|> Customize.elementRow [ Element.width <| Element.fill ]
|
|
||||||
|> Customize.mapContent (Customize.element [ Element.width <| Element.fill ])
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|> Widget.column
|
|
||||||
(style.column
|
|
||||||
|> Customize.elementColumn [ Element.width <| Element.fill ]
|
|
||||||
|> Customize.mapContent (Customize.element [ Element.width <| Element.fill ])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
module Example.Dialog exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import FeatherIcons
|
|
||||||
import Widget exposing (ButtonStyle, DialogStyle)
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| dialog : DialogStyle msg
|
|
||||||
, primaryButton : ButtonStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ dialog = Material.alertDialog Material.defaultPalette
|
|
||||||
, primaryButton = Material.containedButton Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (IsOpen isOpen) =
|
|
||||||
Widget.button style.primaryButton
|
|
||||||
{ text = "Show Dialog"
|
|
||||||
, icon =
|
|
||||||
FeatherIcons.eye
|
|
||||||
|> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress =
|
|
||||||
OpenDialog True
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
|> Element.el
|
|
||||||
([ Element.height <| Element.minimum 200 <| Element.fill
|
|
||||||
, Element.width <| Element.minimum 400 <| Element.fill
|
|
||||||
]
|
|
||||||
++ (if isOpen then
|
|
||||||
{ text = "This is a dialog window"
|
|
||||||
, 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
|
|
||||||
|> List.singleton
|
|
||||||
|> Widget.singleModal
|
|
||||||
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
module Example.Icon exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Ant.Icons.Svg
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import FeatherIcons
|
|
||||||
import FontAwesome.Solid
|
|
||||||
import FontAwesome.Svg
|
|
||||||
import Heroicons.Solid
|
|
||||||
import Ionicon
|
|
||||||
import Material.Icons
|
|
||||||
import Material.Icons.Action
|
|
||||||
import Material.Icons.Types exposing (Coloring(..))
|
|
||||||
import Octicons
|
|
||||||
import Widget exposing (ButtonStyle, RowStyle)
|
|
||||||
import Widget.Icon
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Zondicons
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| primaryButton : ButtonStyle msg
|
|
||||||
, button : ButtonStyle msg
|
|
||||||
, row : RowStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ primaryButton = Material.containedButton Material.defaultPalette
|
|
||||||
, button = Material.outlinedButton Material.defaultPalette
|
|
||||||
, row = Material.row
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
()
|
|
||||||
|
|
||||||
|
|
||||||
type alias Msg =
|
|
||||||
()
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( ()
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg _ =
|
|
||||||
case msg of
|
|
||||||
() ->
|
|
||||||
( ()
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style () =
|
|
||||||
[ "Every icon package on elm-packages is supported."
|
|
||||||
|> Element.text
|
|
||||||
|> List.singleton
|
|
||||||
|> Element.paragraph []
|
|
||||||
, [ ( Material.Icons.done
|
|
||||||
|> Widget.Icon.elmMaterialIcons Color
|
|
||||||
, "elm-material-icons"
|
|
||||||
)
|
|
||||||
, ( Material.Icons.Action.done
|
|
||||||
|> Widget.Icon.materialIcons
|
|
||||||
, "material-icons"
|
|
||||||
)
|
|
||||||
, ( FeatherIcons.check
|
|
||||||
|> Widget.Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, "elm-feather"
|
|
||||||
)
|
|
||||||
, ( FontAwesome.Solid.check
|
|
||||||
|> Widget.Icon.elmFontawesome FontAwesome.Svg.viewIcon
|
|
||||||
, "elm-fontawesome"
|
|
||||||
)
|
|
||||||
, ( Ionicon.checkmark
|
|
||||||
|> Widget.Icon.elmIonicons
|
|
||||||
, "elm-ionicons"
|
|
||||||
)
|
|
||||||
, ( Octicons.check
|
|
||||||
|> Widget.Icon.elmOcticons
|
|
||||||
{ withSize = Octicons.size
|
|
||||||
, withColor = Octicons.color
|
|
||||||
, defaultOptions = Octicons.defaultOptions
|
|
||||||
}
|
|
||||||
, "elm-octicons"
|
|
||||||
)
|
|
||||||
, ( Heroicons.Solid.check
|
|
||||||
|> Widget.Icon.elmHeroicons
|
|
||||||
, "elm-heroicons"
|
|
||||||
)
|
|
||||||
, ( Ant.Icons.Svg.checkOutlined
|
|
||||||
|> Widget.Icon.antDesignIconsElm
|
|
||||||
, "ant-design-icons-elm"
|
|
||||||
)
|
|
||||||
, ( Zondicons.checkmark
|
|
||||||
|> Widget.Icon.elmZondicons
|
|
||||||
, "elm-zondicons"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|> List.map
|
|
||||||
(\( icon, text ) ->
|
|
||||||
Widget.button style.primaryButton
|
|
||||||
{ text = text
|
|
||||||
, icon = icon
|
|
||||||
, onPress = Just <| msgMapper <| ()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Element.wrappedRow [ Element.spacing 10 ]
|
|
||||||
]
|
|
||||||
|> Element.column [ Element.spacing 10 ]
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,402 +0,0 @@
|
|||||||
module Example.Layout exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Browser.Events as Events
|
|
||||||
import Element exposing (Attribute, DeviceClass(..), Element)
|
|
||||||
import Element.Border as Border
|
|
||||||
import Element.Font as Font
|
|
||||||
import Material.Icons
|
|
||||||
import Material.Icons.Types exposing (Coloring(..))
|
|
||||||
import Time
|
|
||||||
import Widget
|
|
||||||
exposing
|
|
||||||
( AppBarStyle
|
|
||||||
, ButtonStyle
|
|
||||||
, ColumnStyle
|
|
||||||
, DialogStyle
|
|
||||||
, InsetItemStyle
|
|
||||||
, ItemStyle
|
|
||||||
, Modal
|
|
||||||
, TextInput
|
|
||||||
, TextInputStyle
|
|
||||||
)
|
|
||||||
import Widget.Icon as Icon exposing (Icon)
|
|
||||||
import Widget.Layout as Layout
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Widget.Material.Color as MaterialColor
|
|
||||||
import Widget.Material.Typography as Typography
|
|
||||||
import Widget.Snackbar as Snackbar exposing (Snackbar, SnackbarStyle)
|
|
||||||
|
|
||||||
|
|
||||||
type Part
|
|
||||||
= LeftSheet
|
|
||||||
| RightSheet
|
|
||||||
| Search
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| container : List (Attribute msg)
|
|
||||||
, snackbar : SnackbarStyle msg
|
|
||||||
, sideSheet : ColumnStyle msg
|
|
||||||
, sheetButton : ItemStyle (ButtonStyle msg) msg
|
|
||||||
, searchFill : TextInputStyle msg
|
|
||||||
, insetItem : ItemStyle (InsetItemStyle msg) msg
|
|
||||||
, menuBar :
|
|
||||||
AppBarStyle
|
|
||||||
{ menuIcon : Icon msg
|
|
||||||
, title : List (Attribute msg)
|
|
||||||
}
|
|
||||||
msg
|
|
||||||
, tabBar :
|
|
||||||
AppBarStyle
|
|
||||||
{ menuTabButton : ButtonStyle msg
|
|
||||||
, title : List (Attribute msg)
|
|
||||||
}
|
|
||||||
msg
|
|
||||||
, dialog : DialogStyle msg
|
|
||||||
, containedButton : ButtonStyle msg
|
|
||||||
, column : ColumnStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ container =
|
|
||||||
(Material.defaultPalette.background |> MaterialColor.textAndBackground)
|
|
||||||
++ [ Font.family
|
|
||||||
[ Font.typeface "Roboto"
|
|
||||||
, Font.sansSerif
|
|
||||||
]
|
|
||||||
, Font.size 16
|
|
||||||
, Font.letterSpacing 0.5
|
|
||||||
]
|
|
||||||
, menuBar = Material.menuBar Material.defaultPalette
|
|
||||||
, tabBar = Material.tabBar Material.defaultPalette
|
|
||||||
, snackbar = Material.snackbar Material.defaultPalette
|
|
||||||
, sheetButton = Material.selectItem Material.defaultPalette
|
|
||||||
, sideSheet = Material.sideSheet Material.defaultPalette
|
|
||||||
, searchFill =
|
|
||||||
{ elementRow =
|
|
||||||
(Material.defaultPalette.surface
|
|
||||||
|> MaterialColor.textAndBackground
|
|
||||||
)
|
|
||||||
++ [ Element.height <| Element.px 56 ]
|
|
||||||
, content =
|
|
||||||
{ chips =
|
|
||||||
{ elementRow = [ Element.spacing 8 ]
|
|
||||||
, content = Material.chip Material.defaultPalette
|
|
||||||
}
|
|
||||||
, text =
|
|
||||||
{ elementTextInput =
|
|
||||||
(Material.defaultPalette.surface
|
|
||||||
|> MaterialColor.textAndBackground
|
|
||||||
)
|
|
||||||
++ [ Border.width 0
|
|
||||||
, Element.mouseOver []
|
|
||||||
, Element.focused []
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, insetItem = Material.insetItem Material.defaultPalette
|
|
||||||
, dialog = Material.alertDialog Material.defaultPalette
|
|
||||||
, containedButton = Material.containedButton Material.defaultPalette
|
|
||||||
, column = Material.column
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ window :
|
|
||||||
{ height : Int
|
|
||||||
, width : Int
|
|
||||||
}
|
|
||||||
, showDialog : Bool
|
|
||||||
, snackbar : Snackbar String
|
|
||||||
, active : Maybe Part
|
|
||||||
, selected : Int
|
|
||||||
, searchText : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ChangedSidebar (Maybe Part)
|
|
||||||
| Resized { width : Int, height : Int }
|
|
||||||
| SetSelected Int
|
|
||||||
| AddSnackbar
|
|
||||||
| ShowDialog Bool
|
|
||||||
| SetSearchText String
|
|
||||||
| TimePassed Int
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( { window = { height = 200, width = 400 }
|
|
||||||
, showDialog = False
|
|
||||||
, snackbar = Snackbar.init
|
|
||||||
, active = Just RightSheet
|
|
||||||
, selected = 0
|
|
||||||
, searchText = ""
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
case msg of
|
|
||||||
ChangedSidebar maybePart ->
|
|
||||||
( { model | active = maybePart }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Resized window ->
|
|
||||||
( { model | window = window }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
SetSelected int ->
|
|
||||||
( { model | selected = int }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
AddSnackbar ->
|
|
||||||
( { model | snackbar = model.snackbar |> Snackbar.insert "This is a message" }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ShowDialog bool ->
|
|
||||||
( { model | showDialog = bool }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
SetSearchText maybeString ->
|
|
||||||
( { model | searchText = maybeString }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
TimePassed sec ->
|
|
||||||
( case model.active of
|
|
||||||
Just LeftSheet ->
|
|
||||||
model
|
|
||||||
|
|
||||||
Just RightSheet ->
|
|
||||||
model
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
{ model
|
|
||||||
| snackbar = model.snackbar |> Snackbar.timePassed sec
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.batch
|
|
||||||
[ Events.onResize (\h w -> Resized { height = h, width = w })
|
|
||||||
, Time.every 50 (always (TimePassed 50))
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style { snackbar, searchText, selected, showDialog, active } =
|
|
||||||
let
|
|
||||||
deviceClass : DeviceClass
|
|
||||||
deviceClass =
|
|
||||||
Phone
|
|
||||||
|
|
||||||
--Replace this line to make the layout responsive
|
|
||||||
--Layout.getDeviceClass window
|
|
||||||
dialog : Maybe (Modal msg)
|
|
||||||
dialog =
|
|
||||||
if showDialog then
|
|
||||||
{ text = "This is a dialog window"
|
|
||||||
, title = Just "Dialog"
|
|
||||||
, accept = Nothing
|
|
||||||
, dismiss =
|
|
||||||
Just
|
|
||||||
{ text = "Accept"
|
|
||||||
, onPress =
|
|
||||||
Just <|
|
|
||||||
msgMapper <|
|
|
||||||
ShowDialog False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> Widget.dialog style.dialog
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
|
|
||||||
onChangedSidebar =
|
|
||||||
ChangedSidebar
|
|
||||||
|
|
||||||
menu =
|
|
||||||
{ selected = Just selected
|
|
||||||
, options =
|
|
||||||
[ "Home", "About" ]
|
|
||||||
|> List.map
|
|
||||||
(\string ->
|
|
||||||
{ text = string
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = SetSelected >> msgMapper >> Just
|
|
||||||
}
|
|
||||||
|
|
||||||
actions =
|
|
||||||
{ icon =
|
|
||||||
Material.Icons.change_history
|
|
||||||
|> Icon.elmMaterialIcons Color
|
|
||||||
, text = "Action"
|
|
||||||
, onPress = Nothing
|
|
||||||
}
|
|
||||||
|> List.repeat 5
|
|
||||||
|
|
||||||
{ primaryActions, moreActions } =
|
|
||||||
Layout.partitionActions actions
|
|
||||||
|
|
||||||
title =
|
|
||||||
"Title"
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el (Typography.h6 ++ [ Element.paddingXY 8 0 ])
|
|
||||||
|
|
||||||
search : TextInput msg
|
|
||||||
search =
|
|
||||||
{ chips = []
|
|
||||||
, text = searchText
|
|
||||||
, placeholder = Nothing
|
|
||||||
, label = "Search"
|
|
||||||
, onChange = SetSearchText >> msgMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
nav : Element msg
|
|
||||||
nav =
|
|
||||||
if
|
|
||||||
(deviceClass == Phone)
|
|
||||||
|| (deviceClass == Tablet)
|
|
||||||
|| (menu.options |> List.length)
|
|
||||||
> 5
|
|
||||||
then
|
|
||||||
Widget.menuBar style.menuBar
|
|
||||||
{ title = title
|
|
||||||
, deviceClass = deviceClass
|
|
||||||
, openLeftSheet = Just <| msgMapper <| ChangedSidebar <| Just LeftSheet
|
|
||||||
, openRightSheet = Just <| msgMapper <| ChangedSidebar <| Just RightSheet
|
|
||||||
, openTopSheet = Just <| msgMapper <| ChangedSidebar <| Just Search
|
|
||||||
, primaryActions = primaryActions
|
|
||||||
, search = Just search
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
Widget.tabBar style.tabBar
|
|
||||||
{ title = title
|
|
||||||
, menu = menu
|
|
||||||
, deviceClass = deviceClass
|
|
||||||
, openRightSheet = Just <| msgMapper <| ChangedSidebar <| Just RightSheet
|
|
||||||
, openTopSheet = Nothing
|
|
||||||
, primaryActions = primaryActions
|
|
||||||
, search = Just search
|
|
||||||
}
|
|
||||||
|
|
||||||
snackbarElem : Element msg
|
|
||||||
snackbarElem =
|
|
||||||
snackbar
|
|
||||||
|> Snackbar.view style.snackbar
|
|
||||||
(\text ->
|
|
||||||
{ text = text
|
|
||||||
, button = Nothing
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Maybe.map
|
|
||||||
(Element.el
|
|
||||||
[ Element.padding 8
|
|
||||||
, Element.alignBottom
|
|
||||||
, Element.alignRight
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|> Maybe.withDefault Element.none
|
|
||||||
|
|
||||||
onDismiss =
|
|
||||||
Nothing
|
|
||||||
|> ChangedSidebar
|
|
||||||
|> msgMapper
|
|
||||||
|
|
||||||
modals =
|
|
||||||
Layout.orderModals
|
|
||||||
{ dialog = dialog
|
|
||||||
, leftSheet =
|
|
||||||
if active == Just LeftSheet then
|
|
||||||
Layout.leftSheet
|
|
||||||
{ button = style.sheetButton
|
|
||||||
, sheet = style.sideSheet
|
|
||||||
}
|
|
||||||
{ title = title
|
|
||||||
, menu = menu
|
|
||||||
, onDismiss = onDismiss
|
|
||||||
}
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, rightSheet =
|
|
||||||
if active == Just RightSheet then
|
|
||||||
Layout.rightSheet
|
|
||||||
{ sheet = style.sideSheet
|
|
||||||
, insetItem = style.insetItem
|
|
||||||
}
|
|
||||||
{ onDismiss = onDismiss
|
|
||||||
, moreActions = moreActions
|
|
||||||
}
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, topSheet =
|
|
||||||
if active == Just Search then
|
|
||||||
Layout.searchSheet style.searchFill
|
|
||||||
{ search = search
|
|
||||||
, onDismiss = onDismiss
|
|
||||||
}
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, bottomSheet = Nothing
|
|
||||||
}
|
|
||||||
in
|
|
||||||
[ nav
|
|
||||||
, Widget.button style.containedButton
|
|
||||||
{ onPress =
|
|
||||||
Just <|
|
|
||||||
msgMapper <|
|
|
||||||
AddSnackbar
|
|
||||||
, text = "Add Notification"
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Element.column [ Element.width <| Element.fill, Element.spacing 8 ]
|
|
||||||
|> Element.el
|
|
||||||
(List.concat
|
|
||||||
[ style.container
|
|
||||||
, [ Element.inFront snackbarElem ]
|
|
||||||
, modals
|
|
||||||
|> Widget.singleModal
|
|
||||||
, [ Element.height <| Element.minimum 200 <| Element.fill
|
|
||||||
, Element.width <| Element.minimum 400 <| Element.fill
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,223 +0,0 @@
|
|||||||
module Example.List exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Element.Font as Font
|
|
||||||
import FeatherIcons
|
|
||||||
import Widget exposing (ButtonStyle, ColumnStyle, DividerStyle, ExpansionItemStyle, FullBleedItemStyle, HeaderStyle, ImageItemStyle, InsetItemStyle, ItemStyle, MultiLineItemStyle, SwitchStyle)
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Widget.Material.Color as MaterialColor
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| cardColumn : ColumnStyle msg
|
|
||||||
, insetDivider : ItemStyle (DividerStyle msg) msg
|
|
||||||
, middleDivider : ItemStyle (DividerStyle msg) msg
|
|
||||||
, fullBleedDivider : ItemStyle (DividerStyle msg) msg
|
|
||||||
, insetHeader : ItemStyle (HeaderStyle msg) msg
|
|
||||||
, fullBleedHeader : ItemStyle (HeaderStyle msg) msg
|
|
||||||
, insetItem : ItemStyle (InsetItemStyle msg) msg
|
|
||||||
, imageItem : ItemStyle (ImageItemStyle msg) msg
|
|
||||||
, expansionItem : ExpansionItemStyle msg
|
|
||||||
, switch : SwitchStyle msg
|
|
||||||
, multiLineItem : ItemStyle (MultiLineItemStyle msg) msg
|
|
||||||
, fullBleedItem : ItemStyle (FullBleedItemStyle msg) msg
|
|
||||||
, selectItem : ItemStyle (ButtonStyle msg) msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ cardColumn = Material.cardColumn Material.defaultPalette
|
|
||||||
, insetDivider = Material.insetDivider Material.defaultPalette
|
|
||||||
, middleDivider = Material.middleDivider Material.defaultPalette
|
|
||||||
, fullBleedDivider = Material.fullBleedDivider Material.defaultPalette
|
|
||||||
, insetHeader = Material.insetHeader Material.defaultPalette
|
|
||||||
, fullBleedHeader = Material.fullBleedHeader Material.defaultPalette
|
|
||||||
, insetItem = Material.insetItem Material.defaultPalette
|
|
||||||
, imageItem = Material.imageItem Material.defaultPalette
|
|
||||||
, expansionItem = Material.expansionItem Material.defaultPalette
|
|
||||||
, switch = Material.switch Material.defaultPalette
|
|
||||||
, multiLineItem = Material.multiLineItem Material.defaultPalette
|
|
||||||
, fullBleedItem = Material.fullBleedItem Material.defaultPalette
|
|
||||||
, selectItem = Material.selectItem Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= IsExpanded Bool
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ToggleCollapsable Bool
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( IsExpanded False
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg _ =
|
|
||||||
case msg of
|
|
||||||
ToggleCollapsable bool ->
|
|
||||||
( IsExpanded bool
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (IsExpanded isExpanded) =
|
|
||||||
[ "Section 1"
|
|
||||||
|> Widget.headerItem style.fullBleedHeader
|
|
||||||
, Widget.asItem <| Element.text <| "Custom Item"
|
|
||||||
, Widget.divider style.middleDivider
|
|
||||||
, Widget.fullBleedItem style.fullBleedItem
|
|
||||||
{ onPress = Nothing
|
|
||||||
, icon =
|
|
||||||
\_ ->
|
|
||||||
Element.none
|
|
||||||
, text = "Full Bleed Item"
|
|
||||||
}
|
|
||||||
, "Section 2"
|
|
||||||
|> Widget.headerItem style.fullBleedHeader
|
|
||||||
, Widget.insetItem style.insetItem
|
|
||||||
{ onPress = Nothing
|
|
||||||
, icon =
|
|
||||||
FeatherIcons.triangle
|
|
||||||
|> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, text = "Item with Icon"
|
|
||||||
, content =
|
|
||||||
\_ ->
|
|
||||||
Element.none
|
|
||||||
}
|
|
||||||
, Widget.imageItem style.imageItem
|
|
||||||
{ onPress = Nothing
|
|
||||||
, image =
|
|
||||||
Element.image [ Element.width <| Element.px <| 40, Element.height <| Element.px <| 40 ]
|
|
||||||
{ src = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Elm_logo.svg/1024px-Elm_logo.svg.png"
|
|
||||||
, description = "Elm logo"
|
|
||||||
}
|
|
||||||
, text = "Item with Image"
|
|
||||||
, content =
|
|
||||||
\{ size, color } ->
|
|
||||||
"1."
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el
|
|
||||||
[ Font.color <| MaterialColor.fromColor color
|
|
||||||
, Font.size size
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, Widget.divider style.insetDivider
|
|
||||||
, Widget.insetItem style.insetItem
|
|
||||||
{ onPress = not isExpanded |> ToggleCollapsable |> msgMapper |> Just
|
|
||||||
, icon = always Element.none
|
|
||||||
, text = "Click Me"
|
|
||||||
, content =
|
|
||||||
\{ size, color } ->
|
|
||||||
"2."
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el
|
|
||||||
[ Font.color <| MaterialColor.fromColor color
|
|
||||||
, Font.size size
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, Widget.multiLineItem style.multiLineItem
|
|
||||||
{ title = "Item"
|
|
||||||
, text = "Description. Description. Description. Description. Description. Description. Description. Description. Description. Description."
|
|
||||||
, onPress = Nothing
|
|
||||||
, icon = always Element.none
|
|
||||||
, content = always Element.none
|
|
||||||
}
|
|
||||||
, Widget.imageItem style.imageItem
|
|
||||||
{ onPress = not isExpanded |> ToggleCollapsable |> msgMapper |> Just
|
|
||||||
, image = Element.none
|
|
||||||
, text = "Clickable Item with Switch"
|
|
||||||
, content =
|
|
||||||
\_ ->
|
|
||||||
Widget.switch style.switch
|
|
||||||
{ description = "Click Me"
|
|
||||||
, active = isExpanded
|
|
||||||
, onPress =
|
|
||||||
not isExpanded
|
|
||||||
|> ToggleCollapsable
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, Widget.divider style.fullBleedDivider
|
|
||||||
]
|
|
||||||
++ Widget.expansionItem style.expansionItem
|
|
||||||
{ onToggle = ToggleCollapsable >> msgMapper
|
|
||||||
, isExpanded = isExpanded
|
|
||||||
, icon = always Element.none
|
|
||||||
, text = "Expandable Item"
|
|
||||||
, content =
|
|
||||||
[ "Section 3"
|
|
||||||
|> Widget.headerItem style.insetHeader
|
|
||||||
, Widget.insetItem style.insetItem
|
|
||||||
{ onPress = Nothing
|
|
||||||
, icon = always Element.none
|
|
||||||
, text = "Item"
|
|
||||||
, content =
|
|
||||||
\{ size, color } ->
|
|
||||||
"3."
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el
|
|
||||||
[ Font.color <| MaterialColor.fromColor color
|
|
||||||
, Font.size size
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
++ [ "Menu" |> Widget.headerItem style.fullBleedHeader ]
|
|
||||||
++ ({ selected =
|
|
||||||
if isExpanded then
|
|
||||||
Just 1
|
|
||||||
|
|
||||||
else
|
|
||||||
Just 0
|
|
||||||
, options =
|
|
||||||
[ True, False ]
|
|
||||||
|> List.map
|
|
||||||
(\bool ->
|
|
||||||
{ text =
|
|
||||||
if bool then
|
|
||||||
"Expanded"
|
|
||||||
|
|
||||||
else
|
|
||||||
"Collapsed"
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect =
|
|
||||||
\int ->
|
|
||||||
(int == 1)
|
|
||||||
|> ToggleCollapsable
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
|> Widget.selectItem style.selectItem
|
|
||||||
)
|
|
||||||
|> Widget.itemList style.cardColumn
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
module Example.Modal exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import FeatherIcons
|
|
||||||
import Widget exposing (ButtonStyle, ColumnStyle)
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| cardColumn : ColumnStyle msg
|
|
||||||
, primaryButton : ButtonStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ cardColumn = Material.cardColumn Material.defaultPalette
|
|
||||||
, primaryButton = Material.containedButton Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (IsEnabled isEnabled) =
|
|
||||||
Widget.button style.primaryButton
|
|
||||||
{ text = "Show Modal"
|
|
||||||
, icon =
|
|
||||||
FeatherIcons.eye
|
|
||||||
|> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress =
|
|
||||||
ToggleModal True
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
|> Element.el
|
|
||||||
([ Element.height <| Element.minimum 200 <| Element.fill
|
|
||||||
, Element.width <| Element.minimum 400 <| Element.fill
|
|
||||||
]
|
|
||||||
++ (if isEnabled then
|
|
||||||
[ { 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.width <| Element.px 250
|
|
||||||
, Element.centerX
|
|
||||||
, Element.centerY
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, { onDismiss = Nothing
|
|
||||||
, content =
|
|
||||||
"This card can not be selected."
|
|
||||||
|> Element.text
|
|
||||||
|> List.singleton
|
|
||||||
|> Element.paragraph []
|
|
||||||
|> List.singleton
|
|
||||||
|> Widget.column style.cardColumn
|
|
||||||
|> Element.el
|
|
||||||
[ Element.height <| Element.px 150
|
|
||||||
, Element.width <| Element.px 200
|
|
||||||
, Element.centerX
|
|
||||||
, Element.centerY
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, { onDismiss = Nothing
|
|
||||||
, content =
|
|
||||||
"This is message is behind the other two"
|
|
||||||
|> Element.text
|
|
||||||
|> List.singleton
|
|
||||||
|> Element.paragraph []
|
|
||||||
|> List.singleton
|
|
||||||
|> Widget.column style.cardColumn
|
|
||||||
|> Element.el
|
|
||||||
[ Element.height <| Element.px 300
|
|
||||||
, Element.width <| Element.px 300
|
|
||||||
, Element.centerX
|
|
||||||
, Element.centerY
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Widget.multiModal
|
|
||||||
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
module Example.MultiSelect exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Set exposing (Set)
|
|
||||||
import Widget exposing (ButtonStyle, RowStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| buttonRow : RowStyle msg
|
|
||||||
, selectButton : ButtonStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ buttonRow = Material.buttonRow
|
|
||||||
, selectButton = Material.toggleButton Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= Selected (Set Int)
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ChangedSelected Int
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( Selected <| Set.empty
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg (Selected selected) =
|
|
||||||
case msg of
|
|
||||||
ChangedSelected int ->
|
|
||||||
( selected
|
|
||||||
|> (if selected |> Set.member int then
|
|
||||||
Set.remove int
|
|
||||||
|
|
||||||
else
|
|
||||||
Set.insert int
|
|
||||||
)
|
|
||||||
|> Selected
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (Selected selected) =
|
|
||||||
{ selected = selected
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = ChangedSelected >> msgMapper >> Just
|
|
||||||
}
|
|
||||||
|> Widget.multiSelect
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
module Example.PasswordInput exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Set exposing (Set)
|
|
||||||
import Widget exposing (ColumnStyle, PasswordInputStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| passwordInput : PasswordInputStyle msg
|
|
||||||
, column : ColumnStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ passwordInput = Material.passwordInput Material.defaultPalette
|
|
||||||
, column = Material.column
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ passwordInput : String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= SetPasswordInput String
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( { passwordInput = ""
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
case msg of
|
|
||||||
SetPasswordInput string ->
|
|
||||||
( { model | passwordInput = string }, Cmd.none )
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style model =
|
|
||||||
[ { text = model.passwordInput
|
|
||||||
, placeholder = Nothing
|
|
||||||
, label = "Chips"
|
|
||||||
, onChange = SetPasswordInput >> msgMapper
|
|
||||||
, show = False
|
|
||||||
}
|
|
||||||
|> Widget.currentPasswordInput style.passwordInput
|
|
||||||
]
|
|
||||||
|> Widget.column style.column
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
module Example.ProgressIndicator exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Widget exposing (ProgressIndicatorStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| progressIndicator : ProgressIndicatorStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ progressIndicator = Material.progressIndicator Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= MaybeProgress (Maybe Float)
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ChangedProgress (Maybe Float)
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( MaybeProgress Nothing
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg _ =
|
|
||||||
case msg of
|
|
||||||
ChangedProgress maybeFloat ->
|
|
||||||
( MaybeProgress maybeFloat
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (MaybeProgress maybeProgress) =
|
|
||||||
Widget.circularProgressIndicator style.progressIndicator maybeProgress
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
module Example.Select exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Widget exposing (ButtonStyle, RowStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| buttonRow : RowStyle msg
|
|
||||||
, selectButton : ButtonStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ buttonRow = Material.buttonRow
|
|
||||||
, selectButton = Material.toggleButton Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= Selected (Maybe Int)
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ChangedSelected Int
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( Selected Nothing
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg _ =
|
|
||||||
case msg of
|
|
||||||
ChangedSelected int ->
|
|
||||||
( Selected <| Just int
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (Selected selected) =
|
|
||||||
{ selected = selected
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = ChangedSelected >> msgMapper >> Just
|
|
||||||
}
|
|
||||||
|> Widget.select
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
module Example.Sheet exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import FeatherIcons
|
|
||||||
import Widget exposing (ButtonStyle, ColumnStyle, HeaderStyle, InsetItemStyle, ItemStyle)
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Widget.Material.Typography as Typography
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| sideSheet : ColumnStyle msg
|
|
||||||
, primaryButton : ButtonStyle msg
|
|
||||||
, fullBleedHeader : ItemStyle (HeaderStyle msg) msg
|
|
||||||
, insetItem : ItemStyle (InsetItemStyle msg) msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ sideSheet = Material.sideSheet Material.defaultPalette
|
|
||||||
, primaryButton = Material.containedButton Material.defaultPalette
|
|
||||||
, fullBleedHeader = Material.fullBleedHeader Material.defaultPalette
|
|
||||||
, insetItem = Material.insetItem Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (IsEnabled isEnabled) =
|
|
||||||
Widget.button style.primaryButton
|
|
||||||
{ text = "Show Sheet"
|
|
||||||
, icon =
|
|
||||||
FeatherIcons.eye
|
|
||||||
|> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress =
|
|
||||||
ToggleModal True
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
|> Element.el
|
|
||||||
([ Element.height <| Element.minimum 200 <| Element.fill
|
|
||||||
, Element.width <| Element.minimum 400 <| Element.fill
|
|
||||||
]
|
|
||||||
++ (if isEnabled then
|
|
||||||
{ content =
|
|
||||||
[ "Menu"
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el Typography.h6
|
|
||||||
|> Widget.asItem
|
|
||||||
, Widget.insetItem style.insetItem
|
|
||||||
{ onPress = Just <| msgMapper <| ToggleModal False
|
|
||||||
, icon =
|
|
||||||
FeatherIcons.triangle
|
|
||||||
|> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, text = "Home"
|
|
||||||
, content =
|
|
||||||
\_ ->
|
|
||||||
Element.none
|
|
||||||
}
|
|
||||||
, Widget.insetItem style.insetItem
|
|
||||||
{ onPress = Just <| msgMapper <| ToggleModal False
|
|
||||||
, icon =
|
|
||||||
FeatherIcons.triangle
|
|
||||||
|> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, text = "About"
|
|
||||||
, content =
|
|
||||||
\_ ->
|
|
||||||
Element.none
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Widget.itemList style.sideSheet
|
|
||||||
, onDismiss = Just <| msgMapper <| ToggleModal False
|
|
||||||
}
|
|
||||||
|> List.singleton
|
|
||||||
|> Widget.singleModal
|
|
||||||
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
module Example.Snackbar exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Time
|
|
||||||
import Widget exposing (ButtonStyle, ColumnStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
import Widget.Snackbar as Snackbar exposing (Snackbar, SnackbarStyle)
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| primaryButton : ButtonStyle msg
|
|
||||||
, button : ButtonStyle msg
|
|
||||||
, column : ColumnStyle msg
|
|
||||||
, snackbar : SnackbarStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ primaryButton = Material.containedButton Material.defaultPalette
|
|
||||||
, button = Material.outlinedButton Material.defaultPalette
|
|
||||||
, column = Material.column
|
|
||||||
, snackbar = Material.snackbar Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
Snackbar ( String, Bool )
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= AddSnackbar ( String, Bool )
|
|
||||||
| TimePassed Int
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( Snackbar.init
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
case msg of
|
|
||||||
TimePassed int ->
|
|
||||||
( model |> Snackbar.timePassed int
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
AddSnackbar snack ->
|
|
||||||
( model |> Snackbar.insert snack
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Time.every 50 (always (TimePassed 50))
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style model =
|
|
||||||
[ Widget.button style.button
|
|
||||||
{ onPress =
|
|
||||||
Just <|
|
|
||||||
msgMapper <|
|
|
||||||
AddSnackbar <|
|
|
||||||
( "This is a notification. It will disappear after 10 seconds."
|
|
||||||
, False
|
|
||||||
)
|
|
||||||
, text = "Add Notification"
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
, Widget.button style.button
|
|
||||||
{ onPress =
|
|
||||||
Just <|
|
|
||||||
msgMapper <|
|
|
||||||
AddSnackbar <|
|
|
||||||
( "You can add another notification if you want."
|
|
||||||
, True
|
|
||||||
)
|
|
||||||
, text = "Add Notification with Action"
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Widget.column style.column
|
|
||||||
|> Element.el
|
|
||||||
[ Element.height <| Element.minimum 200 <| Element.fill
|
|
||||||
, Element.width <| Element.minimum 400 <| Element.fill
|
|
||||||
, Element.inFront <|
|
|
||||||
(model
|
|
||||||
|> Snackbar.view style.snackbar
|
|
||||||
(\( text, hasButton ) ->
|
|
||||||
{ text = text
|
|
||||||
, button =
|
|
||||||
if hasButton then
|
|
||||||
Just
|
|
||||||
{ text = "Add"
|
|
||||||
, onPress =
|
|
||||||
Just <|
|
|
||||||
msgMapper <|
|
|
||||||
AddSnackbar ( "This is another message", False )
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Maybe.map
|
|
||||||
(Element.el
|
|
||||||
[ Element.padding 8
|
|
||||||
, Element.alignBottom
|
|
||||||
, Element.alignRight
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|> Maybe.withDefault Element.none
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
module Example.SortTable exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Widget exposing (SortTableStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| sortTable : SortTableStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ sortTable = Material.sortTable Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
module Example.Switch exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Widget exposing (SwitchStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| switch : SwitchStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ switch = Material.switch Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= IsButtonEnabled Bool
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ToggledButtonStatus
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( IsButtonEnabled False
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg (IsButtonEnabled buttonEnabled) =
|
|
||||||
case msg of
|
|
||||||
ToggledButtonStatus ->
|
|
||||||
( IsButtonEnabled <| not buttonEnabled
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (IsButtonEnabled isButtonEnabled) =
|
|
||||||
Widget.switch style.switch
|
|
||||||
{ description = "click me"
|
|
||||||
, active = isButtonEnabled
|
|
||||||
, onPress =
|
|
||||||
ToggledButtonStatus
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
module Example.Tab exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Widget exposing (TabStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| tab : TabStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ tab = Material.tab Material.defaultPalette
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= Selected (Maybe Int)
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ChangedTab Int
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
( Selected Nothing
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg _ =
|
|
||||||
case msg of
|
|
||||||
ChangedTab int ->
|
|
||||||
( Selected <| Just int
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions _ =
|
|
||||||
Sub.none
|
|
||||||
|
|
||||||
|
|
||||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
|
||||||
-}
|
|
||||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
|
||||||
view msgMapper style (Selected selected) =
|
|
||||||
Widget.tab style.tab
|
|
||||||
{ tabs =
|
|
||||||
{ selected = selected
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 3 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = "Tab " ++ (int |> String.fromInt)
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = ChangedTab >> msgMapper >> Just
|
|
||||||
}
|
|
||||||
, content =
|
|
||||||
\s ->
|
|
||||||
(case s of
|
|
||||||
Just 0 ->
|
|
||||||
"This is Tab 1"
|
|
||||||
|
|
||||||
Just 1 ->
|
|
||||||
"This is the second tab"
|
|
||||||
|
|
||||||
Just 2 ->
|
|
||||||
"The thrid and last tab"
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
"Please select a tab"
|
|
||||||
)
|
|
||||||
|> Element.text
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,122 +0,0 @@
|
|||||||
module Example.TextInput exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Set exposing (Set)
|
|
||||||
import Widget exposing (ColumnStyle, TextInputStyle)
|
|
||||||
import Widget.Material as Material
|
|
||||||
|
|
||||||
|
|
||||||
type alias Style style msg =
|
|
||||||
{ style
|
|
||||||
| textInput : TextInputStyle msg
|
|
||||||
, column : ColumnStyle msg
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
materialStyle : Style {} msg
|
|
||||||
materialStyle =
|
|
||||||
{ textInput = Material.textInput Material.defaultPalette
|
|
||||||
, column = Material.column
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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 = always 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.content.chips.content
|
|
||||||
{ onPress =
|
|
||||||
string
|
|
||||||
|> ToggleTextInputChip
|
|
||||||
|> msgMapper
|
|
||||||
|> Just
|
|
||||||
, text = string
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Element.wrappedRow [ Element.spacing 10 ]
|
|
||||||
]
|
|
||||||
|> Widget.column style.column
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = always init
|
|
||||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,207 +0,0 @@
|
|||||||
module Icons exposing
|
|
||||||
( book
|
|
||||||
, chevronDown
|
|
||||||
, chevronLeft
|
|
||||||
, chevronRight
|
|
||||||
, chevronUp
|
|
||||||
, circle
|
|
||||||
, github
|
|
||||||
, menu
|
|
||||||
, moreVertical
|
|
||||||
, penTool
|
|
||||||
, repeat
|
|
||||||
, search
|
|
||||||
, slash
|
|
||||||
, square
|
|
||||||
, triangle
|
|
||||||
)
|
|
||||||
|
|
||||||
import Html exposing (Html)
|
|
||||||
import Svg exposing (Svg, svg)
|
|
||||||
import Svg.Attributes as Attributes
|
|
||||||
|
|
||||||
|
|
||||||
svgFeatherIcon : String -> List (Svg msg) -> Html msg
|
|
||||||
svgFeatherIcon className =
|
|
||||||
svg
|
|
||||||
[ 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 [ Attributes.points "6 9 12 15 18 9" ] []
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
chevronRight : Html msg
|
|
||||||
chevronRight =
|
|
||||||
svgFeatherIcon "chevron-right"
|
|
||||||
[ Svg.polyline [ Attributes.points "9 18 15 12 9 6" ] []
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
chevronLeft : Html msg
|
|
||||||
chevronLeft =
|
|
||||||
svgFeatherIcon "chevron-left"
|
|
||||||
[ Svg.polyline [ Attributes.points "15 18 9 12 15 6" ] []
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
chevronUp : Html msg
|
|
||||||
chevronUp =
|
|
||||||
svgFeatherIcon "chevron-up"
|
|
||||||
[ Svg.polyline [ Attributes.points "18 15 12 9 6 15" ] []
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
repeat : Html msg
|
|
||||||
repeat =
|
|
||||||
svgFeatherIcon "repeat"
|
|
||||||
[ 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 [ 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 [ 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 [ 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
|
|
||||||
[ 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 [ 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 [ Attributes.cx "12", Attributes.cy "12", Attributes.r "10" ] []
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
slash : Html msg
|
|
||||||
slash =
|
|
||||||
svgFeatherIcon "slash"
|
|
||||||
[ 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 [ 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
|
|
||||||
[ 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
|
|
||||||
[ 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"
|
|
||||||
]
|
|
||||||
[]
|
|
||||||
]
|
|
@ -1,623 +0,0 @@
|
|||||||
module Main exposing (main)
|
|
||||||
|
|
||||||
import Array
|
|
||||||
import Browser
|
|
||||||
import Browser.Dom as Dom exposing (Viewport)
|
|
||||||
import Browser.Events as Events
|
|
||||||
import Browser.Navigation as Navigation
|
|
||||||
import Data.Example as Example exposing (Example)
|
|
||||||
import Data.Section exposing (Section(..))
|
|
||||||
import Data.Style exposing (Style)
|
|
||||||
import Data.Theme as Theme exposing (Theme(..))
|
|
||||||
import Element exposing (Attribute, DeviceClass(..), Element)
|
|
||||||
import Element.Input as Input
|
|
||||||
import FeatherIcons
|
|
||||||
import Framework
|
|
||||||
import Framework.Grid as Grid
|
|
||||||
import Framework.Heading as Heading
|
|
||||||
import Html exposing (Html)
|
|
||||||
import Html.Attributes as Attributes
|
|
||||||
import Icons
|
|
||||||
import Material.Icons
|
|
||||||
import Material.Icons.Types exposing (Coloring(..))
|
|
||||||
import Reusable
|
|
||||||
import Set.Any as AnySet exposing (AnySet)
|
|
||||||
import Stateless
|
|
||||||
import Task
|
|
||||||
import Time
|
|
||||||
import Widget exposing (Modal, TextInput)
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Layout as Layout
|
|
||||||
import Widget.Material.Typography as Typography
|
|
||||||
import Widget.ScrollingNav as ScrollingNav
|
|
||||||
import Widget.Snackbar as Snackbar exposing (Message)
|
|
||||||
|
|
||||||
|
|
||||||
type Part
|
|
||||||
= LeftSheet
|
|
||||||
| RightSheet
|
|
||||||
| Search
|
|
||||||
|
|
||||||
|
|
||||||
type alias LoadedModel =
|
|
||||||
{ stateless : Stateless.Model
|
|
||||||
, scrollingNav : ScrollingNav.ScrollingNav Example
|
|
||||||
, snackbar : Snackbar.Snackbar (Message LoadedMsg)
|
|
||||||
, active : Maybe Part
|
|
||||||
, displayDialog : Bool
|
|
||||||
, window :
|
|
||||||
{ height : Int
|
|
||||||
, width : Int
|
|
||||||
}
|
|
||||||
, search :
|
|
||||||
{ raw : String
|
|
||||||
, current : String
|
|
||||||
, remaining : Int
|
|
||||||
}
|
|
||||||
, theme : Theme
|
|
||||||
, expanded : AnySet String Example
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Model
|
|
||||||
= Loading
|
|
||||||
| Loaded LoadedModel
|
|
||||||
|
|
||||||
|
|
||||||
type LoadedMsg
|
|
||||||
= StatelessSpecific Stateless.Msg
|
|
||||||
| UpdateScrollingNav (ScrollingNav.ScrollingNav Example -> ScrollingNav.ScrollingNav Example)
|
|
||||||
| TimePassed Int
|
|
||||||
| AddSnackbar ( String, Bool )
|
|
||||||
| ChangedSidebar (Maybe Part)
|
|
||||||
| Resized { width : Int, height : Int }
|
|
||||||
| Load String
|
|
||||||
| JumpTo Example
|
|
||||||
| ChangedSearch String
|
|
||||||
| SetTheme Theme
|
|
||||||
| Idle
|
|
||||||
| ToggledExample Example
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= LoadedSpecific LoadedMsg
|
|
||||||
| GotViewport Viewport
|
|
||||||
|
|
||||||
|
|
||||||
initialModel : Viewport -> ( LoadedModel, Cmd LoadedMsg )
|
|
||||||
initialModel { viewport } =
|
|
||||||
let
|
|
||||||
( scrollingNav, cmd ) =
|
|
||||||
ScrollingNav.init
|
|
||||||
{ toString = Example.toString
|
|
||||||
, fromString = Example.fromString
|
|
||||||
, arrangement = Example.asList
|
|
||||||
, toMsg =
|
|
||||||
\result ->
|
|
||||||
case result of
|
|
||||||
Ok fun ->
|
|
||||||
UpdateScrollingNav fun
|
|
||||||
|
|
||||||
Err _ ->
|
|
||||||
Idle
|
|
||||||
}
|
|
||||||
|
|
||||||
( stateless, statelessCmd ) =
|
|
||||||
Stateless.init
|
|
||||||
in
|
|
||||||
( { stateless = stateless
|
|
||||||
, scrollingNav = scrollingNav
|
|
||||||
, snackbar = Snackbar.init
|
|
||||||
, active = Nothing
|
|
||||||
, displayDialog = False
|
|
||||||
, window =
|
|
||||||
{ width = viewport.width |> round
|
|
||||||
, height = viewport.height |> round
|
|
||||||
}
|
|
||||||
, search =
|
|
||||||
{ raw = ""
|
|
||||||
, current = ""
|
|
||||||
, remaining = 0
|
|
||||||
}
|
|
||||||
, theme = Material
|
|
||||||
, expanded = AnySet.empty Example.toString
|
|
||||||
}
|
|
||||||
, [ cmd
|
|
||||||
, statelessCmd |> Cmd.map StatelessSpecific
|
|
||||||
]
|
|
||||||
|> Cmd.batch
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
init : () -> ( Model, Cmd Msg )
|
|
||||||
init () =
|
|
||||||
( Loading
|
|
||||||
, Task.perform GotViewport Dom.getViewport
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
updateLoaded : LoadedMsg -> LoadedModel -> ( LoadedModel, Cmd LoadedMsg )
|
|
||||||
updateLoaded msg model =
|
|
||||||
case msg of
|
|
||||||
StatelessSpecific m ->
|
|
||||||
model.stateless
|
|
||||||
|> Stateless.update m
|
|
||||||
|> Tuple.mapBoth
|
|
||||||
(\stateless ->
|
|
||||||
{ model
|
|
||||||
| stateless = stateless
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(Cmd.map StatelessSpecific)
|
|
||||||
|
|
||||||
UpdateScrollingNav fun ->
|
|
||||||
( { model | scrollingNav = model.scrollingNav |> fun }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
TimePassed int ->
|
|
||||||
let
|
|
||||||
search =
|
|
||||||
model.search
|
|
||||||
in
|
|
||||||
( { model
|
|
||||||
| snackbar =
|
|
||||||
case model.active of
|
|
||||||
Just LeftSheet ->
|
|
||||||
model.snackbar
|
|
||||||
|
|
||||||
Just RightSheet ->
|
|
||||||
model.snackbar
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
model.snackbar |> Snackbar.timePassed int
|
|
||||||
, search =
|
|
||||||
if search.remaining > 0 then
|
|
||||||
if search.remaining <= int then
|
|
||||||
{ search
|
|
||||||
| current = search.raw
|
|
||||||
, remaining = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{ search
|
|
||||||
| remaining = search.remaining - int
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
model.search
|
|
||||||
}
|
|
||||||
, ScrollingNav.getPos
|
|
||||||
|> Task.perform UpdateScrollingNav
|
|
||||||
)
|
|
||||||
|
|
||||||
AddSnackbar ( string, bool ) ->
|
|
||||||
( { model
|
|
||||||
| snackbar =
|
|
||||||
model.snackbar
|
|
||||||
|> Snackbar.insert
|
|
||||||
{ text = string
|
|
||||||
, button =
|
|
||||||
if bool then
|
|
||||||
Just
|
|
||||||
{ text = "Add"
|
|
||||||
, onPress =
|
|
||||||
Just <|
|
|
||||||
AddSnackbar ( "This is another message", False )
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Resized window ->
|
|
||||||
( { model | window = window }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ChangedSidebar sidebar ->
|
|
||||||
( { model | active = sidebar }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Load string ->
|
|
||||||
( model, Navigation.load string )
|
|
||||||
|
|
||||||
JumpTo section ->
|
|
||||||
( model
|
|
||||||
, model.scrollingNav
|
|
||||||
|> ScrollingNav.jumpTo
|
|
||||||
{ section = section
|
|
||||||
, onChange = always Idle
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
ChangedSearch string ->
|
|
||||||
let
|
|
||||||
search =
|
|
||||||
model.search
|
|
||||||
in
|
|
||||||
( { model
|
|
||||||
| search =
|
|
||||||
{ search
|
|
||||||
| raw = string
|
|
||||||
, remaining = 300
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
SetTheme theme ->
|
|
||||||
( { model | theme = theme }
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ToggledExample example ->
|
|
||||||
( { model
|
|
||||||
| expanded = model.expanded |> AnySet.toggle example
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Idle ->
|
|
||||||
( model, Cmd.none )
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
case ( model, msg ) of
|
|
||||||
( Loading, GotViewport viewport ) ->
|
|
||||||
initialModel viewport
|
|
||||||
|> Tuple.mapBoth Loaded (Cmd.map LoadedSpecific)
|
|
||||||
|
|
||||||
( Loaded state, LoadedSpecific m ) ->
|
|
||||||
updateLoaded m state
|
|
||||||
|> Tuple.mapBoth Loaded (Cmd.map LoadedSpecific)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
( model, Cmd.none )
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions model =
|
|
||||||
let
|
|
||||||
ms = 2000
|
|
||||||
in
|
|
||||||
([ Time.every ms (always (TimePassed ms))
|
|
||||||
, Events.onResize (\h w -> Resized { height = h, width = w })
|
|
||||||
]
|
|
||||||
++ (case model of
|
|
||||||
Loading ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
Loaded { stateless } ->
|
|
||||||
Stateless.subscriptions stateless
|
|
||||||
|> Sub.map StatelessSpecific
|
|
||||||
|> List.singleton
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|> Sub.batch
|
|
||||||
|> Sub.map LoadedSpecific
|
|
||||||
|
|
||||||
|
|
||||||
view : Model -> Html Msg
|
|
||||||
view model =
|
|
||||||
case model of
|
|
||||||
Loading ->
|
|
||||||
Element.none |> Framework.responsiveLayout []
|
|
||||||
|
|
||||||
Loaded m ->
|
|
||||||
let
|
|
||||||
style : Style msg
|
|
||||||
style =
|
|
||||||
Theme.toStyle m.theme
|
|
||||||
in
|
|
||||||
Html.map LoadedSpecific <|
|
|
||||||
Element.layout
|
|
||||||
(viewLayout identity style m)
|
|
||||||
<|
|
|
||||||
viewLoaded m
|
|
||||||
|
|
||||||
|
|
||||||
viewLayout : (LoadedMsg -> LoadedMsg) -> Style LoadedMsg -> LoadedModel -> List (Attribute LoadedMsg)
|
|
||||||
viewLayout msgMapper style model =
|
|
||||||
let
|
|
||||||
deviceClass : DeviceClass
|
|
||||||
deviceClass =
|
|
||||||
Layout.getDeviceClass model.window
|
|
||||||
|
|
||||||
dialog : Maybe (Modal LoadedMsg)
|
|
||||||
dialog =
|
|
||||||
Nothing
|
|
||||||
|
|
||||||
onChangedSidebar =
|
|
||||||
ChangedSidebar
|
|
||||||
|
|
||||||
menu =
|
|
||||||
model.scrollingNav
|
|
||||||
|> ScrollingNav.toSelect
|
|
||||||
(\int ->
|
|
||||||
model.scrollingNav.arrangement
|
|
||||||
|> Array.fromList
|
|
||||||
|> Array.get int
|
|
||||||
|> Maybe.map JumpTo
|
|
||||||
)
|
|
||||||
|
|
||||||
actions =
|
|
||||||
[ { onPress = Just <| Load "https://package.elm-lang.org/packages/Orasund/elm-ui-widgets/latest/"
|
|
||||||
, text = "Docs"
|
|
||||||
, icon = FeatherIcons.book |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
}
|
|
||||||
, { onPress = Just <| Load "https://github.com/Orasund/elm-ui-widgets"
|
|
||||||
, text = "Github"
|
|
||||||
, icon = FeatherIcons.github |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
}
|
|
||||||
, { onPress =
|
|
||||||
if model.theme /= Material then
|
|
||||||
Just <| SetTheme <| Material
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, text = "Material Theme"
|
|
||||||
, icon = FeatherIcons.penTool |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
}
|
|
||||||
, { onPress =
|
|
||||||
if model.theme /= DarkMaterial then
|
|
||||||
Just <| SetTheme <| DarkMaterial
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, text = "Dark Material Theme"
|
|
||||||
, icon = FeatherIcons.penTool |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
{ primaryActions, moreActions } =
|
|
||||||
Layout.partitionActions actions
|
|
||||||
|
|
||||||
title =
|
|
||||||
"Elm-Ui-Widgets"
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el (Typography.h6 ++ [ Element.paddingXY 8 0 ])
|
|
||||||
|
|
||||||
search : TextInput LoadedMsg
|
|
||||||
search =
|
|
||||||
{ chips = []
|
|
||||||
, text = model.search.raw
|
|
||||||
, placeholder =
|
|
||||||
Just <|
|
|
||||||
Input.placeholder [] <|
|
|
||||||
Element.text "Search Widgets..."
|
|
||||||
, label = "Search"
|
|
||||||
, onChange = ChangedSearch >> msgMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
nav : Element LoadedMsg
|
|
||||||
nav =
|
|
||||||
if
|
|
||||||
(deviceClass == Phone)
|
|
||||||
|| (deviceClass == Tablet)
|
|
||||||
|| (menu.options |> List.length)
|
|
||||||
> 5
|
|
||||||
then
|
|
||||||
Widget.menuBar style.menuBar
|
|
||||||
{ title = title
|
|
||||||
, deviceClass = deviceClass
|
|
||||||
, openLeftSheet = Just <| msgMapper <| ChangedSidebar <| Just LeftSheet
|
|
||||||
, openRightSheet = Just <| msgMapper <| ChangedSidebar <| Just RightSheet
|
|
||||||
, openTopSheet = Just <| msgMapper <| ChangedSidebar <| Just Search
|
|
||||||
, primaryActions = primaryActions
|
|
||||||
, search = Just search
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
Widget.tabBar style.tabBar
|
|
||||||
{ title = title
|
|
||||||
, menu = menu
|
|
||||||
, deviceClass = deviceClass
|
|
||||||
, openRightSheet = Just <| msgMapper <| ChangedSidebar <| Just RightSheet
|
|
||||||
, openTopSheet = Nothing
|
|
||||||
, primaryActions = primaryActions
|
|
||||||
, search = Just search
|
|
||||||
}
|
|
||||||
|
|
||||||
snackbarElem : Element LoadedMsg
|
|
||||||
snackbarElem =
|
|
||||||
model.snackbar
|
|
||||||
|> Snackbar.view style.snackbar identity
|
|
||||||
|> Maybe.map
|
|
||||||
(Element.el
|
|
||||||
[ Element.padding 8
|
|
||||||
, Element.alignBottom
|
|
||||||
, Element.alignRight
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|> Maybe.withDefault Element.none
|
|
||||||
|
|
||||||
onDismiss =
|
|
||||||
Nothing
|
|
||||||
|> ChangedSidebar
|
|
||||||
|> msgMapper
|
|
||||||
|
|
||||||
modals =
|
|
||||||
Layout.orderModals
|
|
||||||
{ dialog = dialog
|
|
||||||
, leftSheet =
|
|
||||||
if model.active == Just LeftSheet then
|
|
||||||
Layout.leftSheet
|
|
||||||
{ button = style.sheetButton
|
|
||||||
, sheet = style.sideSheet
|
|
||||||
}
|
|
||||||
{ title = title
|
|
||||||
, menu = menu
|
|
||||||
, onDismiss = onDismiss
|
|
||||||
}
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, rightSheet =
|
|
||||||
if model.active == Just RightSheet then
|
|
||||||
Layout.rightSheet
|
|
||||||
{ sheet = style.sideSheet
|
|
||||||
, insetItem = style.insetItem
|
|
||||||
}
|
|
||||||
{ onDismiss = onDismiss
|
|
||||||
, moreActions = moreActions
|
|
||||||
}
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, topSheet =
|
|
||||||
if model.active == Just Search then
|
|
||||||
Layout.searchSheet style.searchFill
|
|
||||||
{ search = search
|
|
||||||
, onDismiss = onDismiss
|
|
||||||
}
|
|
||||||
|> Just
|
|
||||||
|
|
||||||
else
|
|
||||||
Nothing
|
|
||||||
, bottomSheet = Nothing
|
|
||||||
}
|
|
||||||
in
|
|
||||||
List.concat
|
|
||||||
[ style.container
|
|
||||||
, [ Element.inFront snackbarElem
|
|
||||||
, Element.inFront nav
|
|
||||||
]
|
|
||||||
, modals
|
|
||||||
|> Widget.singleModal
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
viewLoaded : LoadedModel -> Element LoadedMsg
|
|
||||||
viewLoaded m =
|
|
||||||
let
|
|
||||||
style : Style msg
|
|
||||||
style =
|
|
||||||
Theme.toStyle m.theme
|
|
||||||
in
|
|
||||||
[ Element.el [ Element.height <| Element.px <| 42 ] <| Element.none
|
|
||||||
, [ StatelessViews, ReusableViews ]
|
|
||||||
|> List.map
|
|
||||||
(\section ->
|
|
||||||
(case section of
|
|
||||||
ReusableViews ->
|
|
||||||
Reusable.view
|
|
||||||
{ theme = m.theme
|
|
||||||
, addSnackbar = AddSnackbar
|
|
||||||
}
|
|
||||||
|
|
||||||
StatelessViews ->
|
|
||||||
Stateless.view
|
|
||||||
{ theme = m.theme
|
|
||||||
, msgMapper = StatelessSpecific
|
|
||||||
, model = m.stateless
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> (\{ title, description, items } ->
|
|
||||||
[ title
|
|
||||||
|> Element.text
|
|
||||||
|> Element.el Heading.h2
|
|
||||||
, if m.search.current == "" then
|
|
||||||
description
|
|
||||||
|> Element.text
|
|
||||||
|> List.singleton
|
|
||||||
|> Element.paragraph []
|
|
||||||
|
|
||||||
else
|
|
||||||
Element.none
|
|
||||||
, items
|
|
||||||
|> (if m.search.current /= "" then
|
|
||||||
List.filter
|
|
||||||
(\( a, _, _ ) ->
|
|
||||||
a
|
|
||||||
|> String.toLower
|
|
||||||
|> String.contains (m.search.current |> String.toLower)
|
|
||||||
)
|
|
||||||
|
|
||||||
else
|
|
||||||
identity
|
|
||||||
)
|
|
||||||
|> List.map
|
|
||||||
(\( name, elem, more ) ->
|
|
||||||
(([ Element.text name
|
|
||||||
|> Element.el
|
|
||||||
(Heading.h3
|
|
||||||
++ [ Element.height <| Element.shrink
|
|
||||||
, name
|
|
||||||
|> Attributes.id
|
|
||||||
|> Element.htmlAttribute
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, elem
|
|
||||||
]
|
|
||||||
|> Element.column Grid.simple
|
|
||||||
|> Widget.asItem
|
|
||||||
)
|
|
||||||
:: (if more |> List.isEmpty then
|
|
||||||
[]
|
|
||||||
|
|
||||||
else
|
|
||||||
[ Widget.divider style.fullBleedDivider
|
|
||||||
]
|
|
||||||
++ Widget.expansionItem style.expansionItem
|
|
||||||
{ onToggle =
|
|
||||||
always
|
|
||||||
(name
|
|
||||||
|> Example.fromString
|
|
||||||
|> Maybe.map ToggledExample
|
|
||||||
|> Maybe.withDefault Idle
|
|
||||||
)
|
|
||||||
, icon = always Element.none
|
|
||||||
, text =
|
|
||||||
"States"
|
|
||||||
, content =
|
|
||||||
Element.column
|
|
||||||
(Grid.simple
|
|
||||||
++ [ Element.width <| Element.fill ]
|
|
||||||
)
|
|
||||||
more
|
|
||||||
|> Widget.asItem
|
|
||||||
|> List.singleton
|
|
||||||
, isExpanded =
|
|
||||||
name
|
|
||||||
|> Example.fromString
|
|
||||||
|> Maybe.map
|
|
||||||
(\example ->
|
|
||||||
m.expanded
|
|
||||||
|> AnySet.member example
|
|
||||||
)
|
|
||||||
|> Maybe.withDefault False
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|> Widget.itemList style.cardColumn
|
|
||||||
)
|
|
||||||
|> Element.wrappedRow
|
|
||||||
(Grid.simple
|
|
||||||
++ [ Element.height <| Element.shrink
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|> Element.column (Grid.section ++ [ Element.centerX ])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|> Element.column (Framework.container ++ style.container)
|
|
||||||
]
|
|
||||||
|> Element.column Grid.compact
|
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
|
||||||
main =
|
|
||||||
Browser.element
|
|
||||||
{ init = init
|
|
||||||
, view = view
|
|
||||||
, update = update
|
|
||||||
, subscriptions = subscriptions
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
module Reusable exposing (view)
|
|
||||||
|
|
||||||
import Data.Style exposing (Style)
|
|
||||||
import Data.Theme as Theme exposing (Theme)
|
|
||||||
import Element exposing (Element)
|
|
||||||
import Framework.Grid as Grid
|
|
||||||
import Widget
|
|
||||||
|
|
||||||
|
|
||||||
snackbar : Style msg -> (( String, Bool ) -> msg) -> ( String, Element msg, List (Element msg) )
|
|
||||||
snackbar style addSnackbar =
|
|
||||||
( "Snackbar"
|
|
||||||
, [ Widget.button style.button
|
|
||||||
{ onPress =
|
|
||||||
Just <|
|
|
||||||
addSnackbar <|
|
|
||||||
( "This is a notification. It will disappear after 10 seconds."
|
|
||||||
, False
|
|
||||||
)
|
|
||||||
, text = "Add Notification"
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
, Widget.button style.button
|
|
||||||
{ onPress =
|
|
||||||
Just <|
|
|
||||||
addSnackbar <|
|
|
||||||
( "You can add another notification if you want."
|
|
||||||
, True
|
|
||||||
)
|
|
||||||
, text = "Add Notification with Action"
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|> Element.column Grid.simple
|
|
||||||
, []
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{--scrollingNavCard : Style msg -> ( String, Element msg, List (Element msg) )
|
|
||||||
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
|
|
||||||
|> Element.paragraph []
|
|
||||||
, []
|
|
||||||
)
|
|
||||||
-}
|
|
||||||
|
|
||||||
|
|
||||||
view :
|
|
||||||
{ theme : Theme
|
|
||||||
, addSnackbar : ( String, Bool ) -> msg
|
|
||||||
}
|
|
||||||
->
|
|
||||||
{ title : String
|
|
||||||
, description : String
|
|
||||||
, items : List ( String, Element msg, List (Element msg) )
|
|
||||||
}
|
|
||||||
view { theme, addSnackbar } =
|
|
||||||
let
|
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
module Stateless exposing (Model, Msg, init, subscriptions, update, view)
|
|
||||||
|
|
||||||
import Data.Example as Example
|
|
||||||
import Data.Theme as Theme exposing (Theme)
|
|
||||||
import Element exposing (Element)
|
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ carousel : Int
|
|
||||||
, example : Example.Model
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
|
||||||
= ExampleSpecific Example.Msg
|
|
||||||
| Idle
|
|
||||||
|
|
||||||
|
|
||||||
init : ( Model, Cmd Msg )
|
|
||||||
init =
|
|
||||||
let
|
|
||||||
( example, cmd ) =
|
|
||||||
Example.init
|
|
||||||
in
|
|
||||||
( { carousel = 0
|
|
||||||
, example = example
|
|
||||||
}
|
|
||||||
, cmd |> Cmd.map ExampleSpecific
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
||||||
update msg model =
|
|
||||||
case msg of
|
|
||||||
ExampleSpecific exampleMsg ->
|
|
||||||
let
|
|
||||||
( exampleModel, exampleCmd ) =
|
|
||||||
Example.update exampleMsg model.example
|
|
||||||
in
|
|
||||||
( { model | example = exampleModel }
|
|
||||||
, exampleCmd |> Cmd.map ExampleSpecific
|
|
||||||
)
|
|
||||||
|
|
||||||
Idle ->
|
|
||||||
( model, Cmd.none )
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
|
||||||
subscriptions model =
|
|
||||||
Example.subscriptions model.example |> Sub.map ExampleSpecific
|
|
||||||
|
|
||||||
|
|
||||||
view :
|
|
||||||
{ theme : Theme
|
|
||||||
, msgMapper : Msg -> msg
|
|
||||||
, model : Model
|
|
||||||
}
|
|
||||||
->
|
|
||||||
{ title : String
|
|
||||||
, description : String
|
|
||||||
, items : List ( String, Element msg, List (Element msg) )
|
|
||||||
}
|
|
||||||
view { theme, msgMapper, model } =
|
|
||||||
let
|
|
||||||
style =
|
|
||||||
Theme.toStyle theme
|
|
||||||
in
|
|
||||||
{ title = "Stateless Views"
|
|
||||||
, description = "Stateless views are simple functions that view some content. No wiring required."
|
|
||||||
, items =
|
|
||||||
Example.toCardList
|
|
||||||
{ idle = Idle |> msgMapper
|
|
||||||
, msgMapper = ExampleSpecific >> msgMapper
|
|
||||||
, style = style
|
|
||||||
, model = model.example
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,592 +0,0 @@
|
|||||||
module View.States exposing (appBar, button, dialog, icon, layout, list, modal, multiSelect, passwordInput, progressIndicator, select, sheet, snackbar, sortTable, switch, tab, textInput)
|
|
||||||
|
|
||||||
import Data.Style exposing (Style)
|
|
||||||
import Element exposing (Element)
|
|
||||||
import FeatherIcons
|
|
||||||
import Icons
|
|
||||||
import Set
|
|
||||||
import Widget
|
|
||||||
import Widget.Icon as Icon
|
|
||||||
import Widget.Layout
|
|
||||||
|
|
||||||
|
|
||||||
button : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
button idle style =
|
|
||||||
[ ( "Button"
|
|
||||||
, Widget.button style.button
|
|
||||||
{ text = "Button"
|
|
||||||
, icon = FeatherIcons.triangle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Text button"
|
|
||||||
, Widget.textButton style.button
|
|
||||||
{ text = "Button"
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Icon button"
|
|
||||||
, Widget.iconButton style.button
|
|
||||||
{ text = "Button"
|
|
||||||
, icon = FeatherIcons.triangle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Disabled button"
|
|
||||||
, Widget.button style.button
|
|
||||||
{ text = "Button"
|
|
||||||
, icon = FeatherIcons.triangle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress = Nothing
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Inactive Select button"
|
|
||||||
, Widget.selectButton style.button
|
|
||||||
( False
|
|
||||||
, { text = "Button"
|
|
||||||
, icon = FeatherIcons.triangle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
, ( "Active Select button"
|
|
||||||
, Widget.selectButton style.button
|
|
||||||
( True
|
|
||||||
, { text = "Button"
|
|
||||||
, icon = FeatherIcons.triangle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
switch : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
switch idle style =
|
|
||||||
[ ( "Disabled switch"
|
|
||||||
, Widget.switch style.switch
|
|
||||||
{ description = "Disabled switch"
|
|
||||||
, onPress = Nothing
|
|
||||||
, active = False
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Inactive Select switch"
|
|
||||||
, Widget.switch style.switch
|
|
||||||
{ description = "Inactive Select switch"
|
|
||||||
, onPress = Just idle
|
|
||||||
, active = False
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Active Select switch"
|
|
||||||
, Widget.switch style.switch
|
|
||||||
{ description = "Active Select switch"
|
|
||||||
, onPress = Just idle
|
|
||||||
, active = True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
select : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
select idle style =
|
|
||||||
[ ( "First selected"
|
|
||||||
, { selected = Just 0
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.select
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Nothing selected"
|
|
||||||
, { selected = Nothing
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.select
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Invalid selection"
|
|
||||||
, { selected = Just -1
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.select
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Disabled selection"
|
|
||||||
, { selected = Just 0
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always Nothing
|
|
||||||
}
|
|
||||||
|> Widget.select
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Empty Options"
|
|
||||||
, { selected = Nothing
|
|
||||||
, options =
|
|
||||||
[]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.select
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
multiSelect : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
multiSelect idle style =
|
|
||||||
[ ( "Some selected"
|
|
||||||
, { selected = Set.fromList [ 0, 1 ]
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.multiSelect
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Nothing selected"
|
|
||||||
, { selected = Set.empty
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.multiSelect
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Invalid selection"
|
|
||||||
, { selected = Set.singleton -1
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.multiSelect
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Disabled selection"
|
|
||||||
, { selected = Set.singleton 0
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 42 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always Nothing
|
|
||||||
}
|
|
||||||
|> Widget.multiSelect
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Empty Options"
|
|
||||||
, { selected = Set.empty
|
|
||||||
, options =
|
|
||||||
[]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = String.fromInt int
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
|> Widget.multiSelect
|
|
||||||
|> Widget.buttonRow
|
|
||||||
{ elementRow = style.buttonRow
|
|
||||||
, content = style.selectButton
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
tab : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
tab idle style =
|
|
||||||
[ ( "Nothing selected"
|
|
||||||
, Widget.tab style.tab
|
|
||||||
{ tabs =
|
|
||||||
{ selected = Nothing
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 3 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = int |> String.fromInt
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
, content =
|
|
||||||
\selected ->
|
|
||||||
(case selected of
|
|
||||||
Nothing ->
|
|
||||||
"Please select a tab"
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
""
|
|
||||||
)
|
|
||||||
|> Element.text
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, ( "Tab selected"
|
|
||||||
, Widget.tab style.tab
|
|
||||||
{ tabs =
|
|
||||||
{ selected = Just 0
|
|
||||||
, options =
|
|
||||||
[ 1, 2, 3 ]
|
|
||||||
|> List.map
|
|
||||||
(\int ->
|
|
||||||
{ text = int |> String.fromInt
|
|
||||||
, icon = always Element.none
|
|
||||||
}
|
|
||||||
)
|
|
||||||
, onSelect = always idle >> Just
|
|
||||||
}
|
|
||||||
, content =
|
|
||||||
\selected ->
|
|
||||||
(case selected of
|
|
||||||
Just 0 ->
|
|
||||||
"First Tab selected"
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
"Please select a tab"
|
|
||||||
)
|
|
||||||
|> 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 = FeatherIcons.triangle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, text = "A"
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
, { icon = FeatherIcons.circle |> Icon.elmFeather FeatherIcons.toHtml
|
|
||||||
, text = "B"
|
|
||||||
, onPress = Just idle
|
|
||||||
}
|
|
||||||
]
|
|
||||||
, text = ""
|
|
||||||
, placeholder = Nothing
|
|
||||||
, label = "Label"
|
|
||||||
, onChange = always idle
|
|
||||||
}
|
|
||||||
|> Widget.textInput style.textInput
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
passwordInput : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
passwordInput idle style =
|
|
||||||
[ ( "show"
|
|
||||||
, { text = "password"
|
|
||||||
, placeholder = Nothing
|
|
||||||
, label = "Label"
|
|
||||||
, onChange = always idle
|
|
||||||
, show = True
|
|
||||||
}
|
|
||||||
|> Widget.currentPasswordInput style.passwordInput
|
|
||||||
)
|
|
||||||
, ( "no show"
|
|
||||||
, { text = "password"
|
|
||||||
, placeholder = Nothing
|
|
||||||
, label = "Label"
|
|
||||||
, onChange = always idle
|
|
||||||
, show = False
|
|
||||||
}
|
|
||||||
|> Widget.currentPasswordInput style.passwordInput
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
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.column
|
|
||||||
)
|
|
||||||
, ( "Column as Card"
|
|
||||||
, [ Element.text "A"
|
|
||||||
, Element.text "B"
|
|
||||||
, Element.text "C"
|
|
||||||
]
|
|
||||||
|> Widget.column style.cardColumn
|
|
||||||
)
|
|
||||||
, ( "Singleton List as Card"
|
|
||||||
, [ Element.text "A"
|
|
||||||
]
|
|
||||||
|> Widget.column style.cardColumn
|
|
||||||
)
|
|
||||||
, ( "Empty List as Card"
|
|
||||||
, []
|
|
||||||
|> Widget.column style.cardColumn
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
progressIndicator : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
progressIndicator _ style =
|
|
||||||
let
|
|
||||||
determinateIndicators =
|
|
||||||
[ 0, 0.25, 0.5, 0.75, 1 ]
|
|
||||||
|> List.map
|
|
||||||
(\completeness ->
|
|
||||||
( "Completeness " ++ String.fromFloat completeness
|
|
||||||
, Widget.circularProgressIndicator style.progressIndicator (Just completeness)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
in
|
|
||||||
[ ( "Indeterminate Progress Indicator"
|
|
||||||
, Widget.circularProgressIndicator style.progressIndicator Nothing
|
|
||||||
)
|
|
||||||
]
|
|
||||||
++ determinateIndicators
|
|
||||||
|
|
||||||
|
|
||||||
icon : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
icon _ style =
|
|
||||||
[]
|
|
||||||
|
|
||||||
|
|
||||||
sheet : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
sheet _ style =
|
|
||||||
[]
|
|
||||||
|
|
||||||
|
|
||||||
appBar : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
appBar _ style =
|
|
||||||
[]
|
|
||||||
|
|
||||||
|
|
||||||
layout : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
layout _ style =
|
|
||||||
[]
|
|
||||||
|
|
||||||
|
|
||||||
snackbar : msg -> Style msg -> List ( String, Element msg )
|
|
||||||
snackbar _ style =
|
|
||||||
[]
|
|
@ -1,10 +0,0 @@
|
|||||||
module Example exposing (..)
|
|
||||||
|
|
||||||
import Expect exposing (Expectation)
|
|
||||||
import Fuzz exposing (Fuzzer, int, list, string)
|
|
||||||
import Test exposing (..)
|
|
||||||
|
|
||||||
|
|
||||||
suite : Test
|
|
||||||
suite =
|
|
||||||
todo "Implement our first test. See https://package.elm-lang.org/packages/elm-explorations/test/latest for how to do this!"
|
|
@ -1,43 +0,0 @@
|
|||||||
module IconBug exposing (main)
|
|
||||||
|
|
||||||
import Browser
|
|
||||||
import Element exposing (..)
|
|
||||||
import Element.Border as Border
|
|
||||||
import Element.Input as Input
|
|
||||||
import Html exposing (Html)
|
|
||||||
import Svg
|
|
||||||
import Svg.Attributes
|
|
||||||
|
|
||||||
|
|
||||||
main : Html msg
|
|
||||||
main =
|
|
||||||
Element.layout [] <|
|
|
||||||
row []
|
|
||||||
[ el
|
|
||||||
[ width (shrink |> minimum 100)
|
|
||||||
, explain Debug.todo
|
|
||||||
]
|
|
||||||
(el
|
|
||||||
[ width (px 200)
|
|
||||||
, height (px 200)
|
|
||||||
]
|
|
||||||
none
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{--Element.layout [] <|
|
|
||||||
row [ width shrink
|
|
||||||
]
|
|
||||||
[ Element.el
|
|
||||||
[ height <| px 48
|
|
||||||
, width (shrink |> minimum 32)
|
|
||||||
, explain Debug.todo
|
|
||||||
]
|
|
||||||
(row
|
|
||||||
[ width (shrink)
|
|
||||||
]
|
|
||||||
[ Element.el [centerX] <| text "test test test Test Test"]
|
|
||||||
)
|
|
||||||
]--}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"root": "../src",
|
|
||||||
"tests": []
|
|
||||||
}
|
|
@ -12,7 +12,6 @@ module Internal.Material.Item exposing
|
|||||||
, selectItem
|
, selectItem
|
||||||
)
|
)
|
||||||
|
|
||||||
import Color
|
|
||||||
import Element
|
import Element
|
||||||
import Element.Background as Background
|
import Element.Background as Background
|
||||||
import Element.Border as Border
|
import Element.Border as Border
|
||||||
|
@ -7,7 +7,6 @@ module Internal.Material.List exposing
|
|||||||
, toggleRow
|
, toggleRow
|
||||||
)
|
)
|
||||||
|
|
||||||
import Color
|
|
||||||
import Element
|
import Element
|
||||||
import Element.Background as Background
|
import Element.Background as Background
|
||||||
import Element.Border as Border
|
import Element.Border as Border
|
||||||
|
@ -2,10 +2,8 @@ module Internal.Material.PasswordInput exposing (passwordInput, passwordInputBas
|
|||||||
|
|
||||||
import Element
|
import Element
|
||||||
import Element.Border as Border
|
import Element.Border as Border
|
||||||
import Internal.Material.Chip as Chip
|
|
||||||
import Internal.Material.Palette exposing (Palette)
|
import Internal.Material.Palette exposing (Palette)
|
||||||
import Internal.PasswordInput exposing (PasswordInputStyle)
|
import Internal.PasswordInput exposing (PasswordInputStyle)
|
||||||
import Widget.Customize as Customize
|
|
||||||
import Widget.Material.Color as MaterialColor
|
import Widget.Material.Color as MaterialColor
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ module Internal.PasswordInput exposing
|
|||||||
|
|
||||||
import Element exposing (Attribute, Element)
|
import Element exposing (Attribute, Element)
|
||||||
import Element.Input as Input exposing (Label, Placeholder)
|
import Element.Input as Input exposing (Label, Placeholder)
|
||||||
import Internal.Button as Button exposing (Button, ButtonStyle)
|
|
||||||
|
|
||||||
|
|
||||||
{-| -}
|
{-| -}
|
||||||
|
Loading…
Reference in New Issue
Block a user