Removed Example (replace with Explorer)

This commit is contained in:
Lucas Payr 2021-06-09 16:18:14 +02:00
parent 66df2aa7a5
commit 6b7b8bddc0
36 changed files with 0 additions and 29012 deletions

View File

@ -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"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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"
]
[]
]

View File

@ -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
}

View File

@ -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
]
}

View File

@ -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
}
}

View File

@ -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 =
[]

View File

@ -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!"

View File

@ -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"]
)
]--}

View File

@ -1,4 +0,0 @@
{
"root": "../src",
"tests": []
}

View File

@ -12,7 +12,6 @@ module Internal.Material.Item exposing
, selectItem
)
import Color
import Element
import Element.Background as Background
import Element.Border as Border

View File

@ -7,7 +7,6 @@ module Internal.Material.List exposing
, toggleRow
)
import Color
import Element
import Element.Background as Background
import Element.Border as Border

View File

@ -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

View File

@ -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)
{-| -}