mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-22 04:58:49 +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
|
||||
)
|
||||
|
||||
import Color
|
||||
import Element
|
||||
import Element.Background as Background
|
||||
import Element.Border as Border
|
||||
|
@ -7,7 +7,6 @@ module Internal.Material.List exposing
|
||||
, toggleRow
|
||||
)
|
||||
|
||||
import Color
|
||||
import Element
|
||||
import Element.Background as Background
|
||||
import Element.Border as Border
|
||||
|
@ -2,10 +2,8 @@ module Internal.Material.PasswordInput exposing (passwordInput, passwordInputBas
|
||||
|
||||
import Element
|
||||
import Element.Border as Border
|
||||
import Internal.Material.Chip as Chip
|
||||
import Internal.Material.Palette exposing (Palette)
|
||||
import Internal.PasswordInput exposing (PasswordInputStyle)
|
||||
import Widget.Customize as Customize
|
||||
import Widget.Material.Color as MaterialColor
|
||||
|
||||
|
||||
|
@ -7,7 +7,6 @@ module Internal.PasswordInput exposing
|
||||
|
||||
import Element exposing (Attribute, Element)
|
||||
import Element.Input as Input exposing (Label, Placeholder)
|
||||
import Internal.Button as Button exposing (Button, ButtonStyle)
|
||||
|
||||
|
||||
{-| -}
|
||||
|
Loading…
Reference in New Issue
Block a user