mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-22 04:58:49 +03:00
commit
9f27c296a8
@ -8,6 +8,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"direct": {
|
"direct": {
|
||||||
"avh4/elm-color": "1.0.0",
|
"avh4/elm-color": "1.0.0",
|
||||||
|
"capitalist/elm-octicons": "2.3.0",
|
||||||
|
"danmarcab/material-icons": "1.0.0",
|
||||||
"elm/browser": "1.0.2",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.5",
|
"elm/core": "1.0.5",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
@ -16,12 +18,18 @@
|
|||||||
"elm/time": "1.0.0",
|
"elm/time": "1.0.0",
|
||||||
"elm/url": "1.0.0",
|
"elm/url": "1.0.0",
|
||||||
"elm-explorations/markdown": "1.0.0",
|
"elm-explorations/markdown": "1.0.0",
|
||||||
|
"feathericons/elm-feather": "1.5.0",
|
||||||
"ianmackenzie/elm-units": "2.9.0",
|
"ianmackenzie/elm-units": "2.9.0",
|
||||||
"icidasset/elm-material-icons": "8.0.0",
|
"icidasset/elm-material-icons": "8.0.0",
|
||||||
"insurello/elm-ui-explorer": "2.0.0",
|
"insurello/elm-ui-explorer": "2.0.0",
|
||||||
|
"j-panasiuk/elm-ionicons": "2.0.0",
|
||||||
|
"jasonliang-dev/elm-heroicons": "1.0.3",
|
||||||
|
"lattyware/elm-fontawesome": "5.0.0",
|
||||||
|
"lemol/ant-design-icons-elm": "2.0.0",
|
||||||
"mdgriffith/elm-ui": "1.1.7",
|
"mdgriffith/elm-ui": "1.1.7",
|
||||||
"miyamoen/select-list": "4.1.0",
|
"miyamoen/select-list": "4.1.0",
|
||||||
"noahzgordon/elm-color-extra": "1.0.2",
|
"noahzgordon/elm-color-extra": "1.0.2",
|
||||||
|
"pehota/elm-zondicons": "1.0.1",
|
||||||
"turboMaCk/queue": "1.1.0",
|
"turboMaCk/queue": "1.1.0",
|
||||||
"zwilias/elm-rosetree": "1.5.0"
|
"zwilias/elm-rosetree": "1.5.0"
|
||||||
},
|
},
|
||||||
|
@ -3,19 +3,25 @@ module Main exposing (main)
|
|||||||
import Element
|
import Element
|
||||||
import Page.Button
|
import Page.Button
|
||||||
import Page.Item
|
import Page.Item
|
||||||
|
import Page.Layout
|
||||||
|
import Page.Modal
|
||||||
|
import Page.MultiSelect
|
||||||
import Page.PasswordInput
|
import Page.PasswordInput
|
||||||
|
import Page.ProgressIndicator
|
||||||
import Page.Select
|
import Page.Select
|
||||||
import Page.Snackbar
|
import Page.Snackbar
|
||||||
import Page.SortTable
|
import Page.SortTable
|
||||||
import Page.Switch
|
import Page.Switch
|
||||||
import Page.Tab
|
import Page.Tab
|
||||||
import Page.TextInput
|
import Page.TextInput
|
||||||
|
import Page.Icon
|
||||||
import UIExplorer
|
import UIExplorer
|
||||||
|
|
||||||
|
|
||||||
pages =
|
pages =
|
||||||
UIExplorer.firstPage "Button" Page.Button.page
|
UIExplorer.firstPage "Button" Page.Button.page
|
||||||
|> UIExplorer.nextPage "Select" Page.Select.page
|
|> UIExplorer.nextPage "Select" Page.Select.page
|
||||||
|
|> UIExplorer.nextPage "Multi Select" Page.MultiSelect.page
|
||||||
|> UIExplorer.nextPage "Switch" Page.Switch.page
|
|> UIExplorer.nextPage "Switch" Page.Switch.page
|
||||||
|> UIExplorer.nextPage "Tab" Page.Tab.page
|
|> UIExplorer.nextPage "Tab" Page.Tab.page
|
||||||
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|
||||||
@ -23,6 +29,10 @@ pages =
|
|||||||
|> UIExplorer.nextPage "Sort Table" Page.SortTable.page
|
|> UIExplorer.nextPage "Sort Table" Page.SortTable.page
|
||||||
|> UIExplorer.nextPage "Snackbar" Page.Snackbar.page
|
|> UIExplorer.nextPage "Snackbar" Page.Snackbar.page
|
||||||
|> UIExplorer.nextPage "Item" Page.Item.page
|
|> UIExplorer.nextPage "Item" Page.Item.page
|
||||||
|
|> UIExplorer.nextPage "ProgressIndicator" Page.ProgressIndicator.page
|
||||||
|
|> UIExplorer.nextPage "Modal" Page.Modal.page
|
||||||
|
|> UIExplorer.nextPage "Layout" Page.Layout.page
|
||||||
|
|> UIExplorer.nextPage "Icon" Page.Icon.page
|
||||||
|
|
||||||
|
|
||||||
main =
|
main =
|
||||||
|
164
explorer/src/Page/Icon.elm
Normal file
164
explorer/src/Page/Icon.elm
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
module Page.Icon exposing (page)
|
||||||
|
|
||||||
|
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Ant.Icons.Svg
|
||||||
|
import Browser
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Element.Background as Background
|
||||||
|
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 Page
|
||||||
|
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
|
||||||
|
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
|
||||||
|
import Widget exposing (ButtonStyle, RowStyle)
|
||||||
|
import Widget.Customize as Customize
|
||||||
|
import Widget.Icon
|
||||||
|
import Widget.Material as Material
|
||||||
|
import Widget.Material.Color as MaterialColor
|
||||||
|
import Widget.Material.Typography as Typography
|
||||||
|
import Zondicons
|
||||||
|
|
||||||
|
|
||||||
|
{-| The title of this page
|
||||||
|
-}
|
||||||
|
title : String
|
||||||
|
title =
|
||||||
|
"Icon"
|
||||||
|
|
||||||
|
|
||||||
|
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||||
|
-}
|
||||||
|
description : String
|
||||||
|
description =
|
||||||
|
"Every icon package on elm-packages is supported."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{- This next section is essentially just a normal Elm program. -}
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Interactive Demonstration
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
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 : Context -> Model -> Element Msg
|
||||||
|
view { palette } () =
|
||||||
|
[ ( 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 (Material.containedButton palette)
|
||||||
|
{ text = text
|
||||||
|
, icon = icon
|
||||||
|
, onPress = Just ()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> Element.wrappedRow [ Element.spacing 10 ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
demo : Tile Model Msg ()
|
||||||
|
demo =
|
||||||
|
{ init = always init
|
||||||
|
, update = update
|
||||||
|
, view = Page.demo view
|
||||||
|
, subscriptions = subscriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
page =
|
||||||
|
Tile.static []
|
||||||
|
(\_ _ ->
|
||||||
|
[ title |> Element.text |> Element.el Typography.h3
|
||||||
|
, description |> Element.text |> List.singleton |> Element.paragraph []
|
||||||
|
]
|
||||||
|
|> Element.column [ Element.spacing 32 ]
|
||||||
|
)
|
||||||
|
|> Tile.first
|
||||||
|
|> Tile.next demo
|
||||||
|
|> Tile.page
|
521
explorer/src/Page/Layout.elm
Normal file
521
explorer/src/Page/Layout.elm
Normal file
@ -0,0 +1,521 @@
|
|||||||
|
module Page.Layout exposing (page)
|
||||||
|
|
||||||
|
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Browser
|
||||||
|
import Browser.Events as Events
|
||||||
|
import Element exposing (Attribute, DeviceClass(..), Element)
|
||||||
|
import Element.Background as Background
|
||||||
|
import Element.Border as Border
|
||||||
|
import Element.Font as Font
|
||||||
|
import Material.Icons as MaterialIcons
|
||||||
|
import Material.Icons.Types exposing (Coloring(..))
|
||||||
|
import Page
|
||||||
|
import Time
|
||||||
|
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
|
||||||
|
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
|
||||||
|
import Widget
|
||||||
|
exposing
|
||||||
|
( AppBarStyle
|
||||||
|
, ButtonStyle
|
||||||
|
, ColumnStyle
|
||||||
|
, DialogStyle
|
||||||
|
, InsetItemStyle
|
||||||
|
, ItemStyle
|
||||||
|
, Modal
|
||||||
|
, TextInput
|
||||||
|
, TextInputStyle
|
||||||
|
)
|
||||||
|
import Widget.Customize as Customize
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
{-| The title of this page
|
||||||
|
-}
|
||||||
|
title : String
|
||||||
|
title =
|
||||||
|
"Button"
|
||||||
|
|
||||||
|
|
||||||
|
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||||
|
-}
|
||||||
|
description : String
|
||||||
|
description =
|
||||||
|
"Buttons allow users to take actions, and make choices, with a single tap."
|
||||||
|
|
||||||
|
|
||||||
|
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||||
|
-}
|
||||||
|
viewFunctions =
|
||||||
|
let
|
||||||
|
viewMenuBar titleString deviceClass openLeftSheet openRightSheet openTopSheet primaryActions search { palette } () =
|
||||||
|
Widget.menuBar (Material.menuBar palette)
|
||||||
|
{ title = titleString |> Element.text |> Element.el []
|
||||||
|
, deviceClass = deviceClass
|
||||||
|
, openLeftSheet = openLeftSheet
|
||||||
|
, openRightSheet = openRightSheet
|
||||||
|
, openTopSheet = openTopSheet
|
||||||
|
, primaryActions =
|
||||||
|
{ icon =
|
||||||
|
MaterialIcons.change_history
|
||||||
|
|> Icon.elmMaterialIcons Color
|
||||||
|
, text = "Action"
|
||||||
|
, onPress = Just ()
|
||||||
|
}
|
||||||
|
|> List.repeat primaryActions
|
||||||
|
, search = search
|
||||||
|
}
|
||||||
|
|> Element.el [ Element.width <| Element.px 400, Element.scrollbarX ]
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.button"
|
||||||
|
|
||||||
|
viewTabBar titleString deviceClass _ openRightSheet openTopSheet primaryActions search { palette } () =
|
||||||
|
Widget.tabBar (Material.tabBar palette)
|
||||||
|
{ title = titleString |> Element.text |> Element.el []
|
||||||
|
, menu =
|
||||||
|
{ selected = Just 0
|
||||||
|
, options =
|
||||||
|
[ "Home", "About" ]
|
||||||
|
|> List.map
|
||||||
|
(\string ->
|
||||||
|
{ text = string
|
||||||
|
, icon = always Element.none
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, onSelect = always (Just ())
|
||||||
|
}
|
||||||
|
, deviceClass = deviceClass
|
||||||
|
, openRightSheet = openRightSheet
|
||||||
|
, openTopSheet = openTopSheet
|
||||||
|
, primaryActions =
|
||||||
|
{ icon =
|
||||||
|
MaterialIcons.change_history
|
||||||
|
|> Icon.elmMaterialIcons Color
|
||||||
|
, text = "Action"
|
||||||
|
, onPress = Just ()
|
||||||
|
}
|
||||||
|
|> List.repeat primaryActions
|
||||||
|
, search = search
|
||||||
|
}
|
||||||
|
|> Element.el [ Element.width <| Element.px 400, Element.scrollbarX ]
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.button"
|
||||||
|
in
|
||||||
|
[ viewMenuBar, viewTabBar ]
|
||||||
|
|> List.foldl Story.addTile
|
||||||
|
Story.initStaticTiles
|
||||||
|
|
||||||
|
|
||||||
|
{-| Let's you play around with the options.
|
||||||
|
Note that the order of these stories must follow the order of the arguments from the view functions.
|
||||||
|
-}
|
||||||
|
book : Tile.Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) ()
|
||||||
|
book =
|
||||||
|
Story.book (Just "Options")
|
||||||
|
viewFunctions
|
||||||
|
--Changing the text of the label
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.textStory "Title"
|
||||||
|
"Title"
|
||||||
|
)
|
||||||
|
--Change the Icon
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Device Class"
|
||||||
|
( "Phone", Phone )
|
||||||
|
[ ( "Tablet", Tablet )
|
||||||
|
, ( "Desktop", Desktop )
|
||||||
|
, ( "BigDesktop", BigDesktop )
|
||||||
|
]
|
||||||
|
)
|
||||||
|
--Should an event be triggered when pressing the button?
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "With openLeftSheet event handler"
|
||||||
|
( Just (), Nothing )
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "With openRightSheet event handler"
|
||||||
|
( Just (), Nothing )
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "With openTopSheet event handler"
|
||||||
|
( Just (), Nothing )
|
||||||
|
True
|
||||||
|
)
|
||||||
|
--Changing the text of the label
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.rangeStory "Primary Actions"
|
||||||
|
{ unit = "Buttons", min = 0, max = 5, default = 3 }
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "With search"
|
||||||
|
( Just
|
||||||
|
{ chips = []
|
||||||
|
, text = "Placeholder Text"
|
||||||
|
, placeholder = Nothing
|
||||||
|
, label = "Search"
|
||||||
|
, onChange = always ()
|
||||||
|
}
|
||||||
|
, Nothing
|
||||||
|
)
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{- This next section is essentially just a normal Elm program. -}
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Interactive Demonstration
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
container palette =
|
||||||
|
(palette.background |> MaterialColor.textAndBackground)
|
||||||
|
++ [ Font.family
|
||||||
|
[ Font.typeface "Roboto"
|
||||||
|
, Font.sansSerif
|
||||||
|
]
|
||||||
|
, Font.size 16
|
||||||
|
, Font.letterSpacing 0.5
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
searchFill palette =
|
||||||
|
{ elementRow =
|
||||||
|
(palette.surface
|
||||||
|
|> MaterialColor.textAndBackground
|
||||||
|
)
|
||||||
|
++ [ Element.height <| Element.px 56 ]
|
||||||
|
, content =
|
||||||
|
{ chips =
|
||||||
|
{ elementRow = [ Element.spacing 8 ]
|
||||||
|
, content = Material.chip palette
|
||||||
|
}
|
||||||
|
, text =
|
||||||
|
{ elementTextInput =
|
||||||
|
(palette.surface
|
||||||
|
|> MaterialColor.textAndBackground
|
||||||
|
)
|
||||||
|
++ [ Border.width 0
|
||||||
|
, Element.mouseOver []
|
||||||
|
, Element.focused []
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Part
|
||||||
|
= LeftSheet
|
||||||
|
| RightSheet
|
||||||
|
| Search
|
||||||
|
|
||||||
|
|
||||||
|
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 : Context -> Model -> Element Msg
|
||||||
|
view { palette } { 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 <|
|
||||||
|
ShowDialog False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> Widget.dialog (Material.alertDialog palette)
|
||||||
|
|> Just
|
||||||
|
|
||||||
|
else
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
menu =
|
||||||
|
{ selected = Just selected
|
||||||
|
, options =
|
||||||
|
[ "Home", "About" ]
|
||||||
|
|> List.map
|
||||||
|
(\string ->
|
||||||
|
{ text = string
|
||||||
|
, icon = always Element.none
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, onSelect = SetSelected >> Just
|
||||||
|
}
|
||||||
|
|
||||||
|
actions =
|
||||||
|
{ icon =
|
||||||
|
MaterialIcons.change_history
|
||||||
|
|> Icon.elmMaterialIcons Color
|
||||||
|
, text = "Action"
|
||||||
|
, onPress = Nothing
|
||||||
|
}
|
||||||
|
|> List.repeat 5
|
||||||
|
|
||||||
|
{ primaryActions, moreActions } =
|
||||||
|
Layout.partitionActions actions
|
||||||
|
|
||||||
|
titleEl =
|
||||||
|
"Title"
|
||||||
|
|> Element.text
|
||||||
|
|> Element.el (Typography.h6 ++ [ Element.paddingXY 8 0 ])
|
||||||
|
|
||||||
|
search : TextInput Msg
|
||||||
|
search =
|
||||||
|
{ chips = []
|
||||||
|
, text = searchText
|
||||||
|
, placeholder = Nothing
|
||||||
|
, label = "Search"
|
||||||
|
, onChange = SetSearchText
|
||||||
|
}
|
||||||
|
|
||||||
|
nav : Element Msg
|
||||||
|
nav =
|
||||||
|
if
|
||||||
|
(deviceClass == Phone)
|
||||||
|
|| (deviceClass == Tablet)
|
||||||
|
|| (menu.options |> List.length)
|
||||||
|
> 5
|
||||||
|
then
|
||||||
|
Widget.menuBar (Material.menuBar palette)
|
||||||
|
{ title = titleEl
|
||||||
|
, deviceClass = deviceClass
|
||||||
|
, openLeftSheet = Just <| ChangedSidebar <| Just LeftSheet
|
||||||
|
, openRightSheet = Just <| ChangedSidebar <| Just RightSheet
|
||||||
|
, openTopSheet = Just <| ChangedSidebar <| Just Search
|
||||||
|
, primaryActions = primaryActions
|
||||||
|
, search = Just search
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
Widget.tabBar (Material.tabBar palette)
|
||||||
|
{ title = titleEl
|
||||||
|
, menu = menu
|
||||||
|
, deviceClass = deviceClass
|
||||||
|
, openRightSheet = Just <| ChangedSidebar <| Just RightSheet
|
||||||
|
, openTopSheet = Nothing
|
||||||
|
, primaryActions = primaryActions
|
||||||
|
, search = Just search
|
||||||
|
}
|
||||||
|
|
||||||
|
snackbarElem : Element Msg
|
||||||
|
snackbarElem =
|
||||||
|
snackbar
|
||||||
|
|> Snackbar.view (Material.snackbar palette)
|
||||||
|
(\text ->
|
||||||
|
{ text = text
|
||||||
|
, button = Nothing
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> Maybe.map
|
||||||
|
(Element.el
|
||||||
|
[ Element.padding 8
|
||||||
|
, Element.alignBottom
|
||||||
|
, Element.alignRight
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|> Maybe.withDefault Element.none
|
||||||
|
|
||||||
|
onDismiss =
|
||||||
|
Nothing
|
||||||
|
|> ChangedSidebar
|
||||||
|
|
||||||
|
modals =
|
||||||
|
Layout.orderModals
|
||||||
|
{ dialog = dialog
|
||||||
|
, leftSheet =
|
||||||
|
if active == Just LeftSheet then
|
||||||
|
Layout.leftSheet
|
||||||
|
{ button = Material.selectItem palette
|
||||||
|
, sheet = Material.sideSheet palette
|
||||||
|
}
|
||||||
|
{ title = titleEl
|
||||||
|
, menu = menu
|
||||||
|
, onDismiss = onDismiss
|
||||||
|
}
|
||||||
|
|> Just
|
||||||
|
|
||||||
|
else
|
||||||
|
Nothing
|
||||||
|
, rightSheet =
|
||||||
|
if active == Just RightSheet then
|
||||||
|
Layout.rightSheet
|
||||||
|
{ sheet = Material.sideSheet palette
|
||||||
|
, insetItem = Material.insetItem palette
|
||||||
|
}
|
||||||
|
{ onDismiss = onDismiss
|
||||||
|
, moreActions = moreActions
|
||||||
|
}
|
||||||
|
|> Just
|
||||||
|
|
||||||
|
else
|
||||||
|
Nothing
|
||||||
|
, topSheet =
|
||||||
|
if active == Just Search then
|
||||||
|
Layout.searchSheet (searchFill palette)
|
||||||
|
{ search = search
|
||||||
|
, onDismiss = onDismiss
|
||||||
|
}
|
||||||
|
|> Just
|
||||||
|
|
||||||
|
else
|
||||||
|
Nothing
|
||||||
|
, bottomSheet = Nothing
|
||||||
|
}
|
||||||
|
in
|
||||||
|
[ nav
|
||||||
|
, Widget.button (Material.containedButton palette)
|
||||||
|
{ onPress = Just <| AddSnackbar
|
||||||
|
, text = "Add Notification"
|
||||||
|
, icon = always Element.none
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|> Element.column [ Element.width <| Element.fill, Element.spacing 8 ]
|
||||||
|
|> Element.el
|
||||||
|
(List.concat
|
||||||
|
[ container palette
|
||||||
|
, [ Element.inFront snackbarElem ]
|
||||||
|
, modals
|
||||||
|
|> Widget.singleModal
|
||||||
|
, [ Element.height <| Element.minimum 200 <| Element.fill
|
||||||
|
, Element.width <| Element.minimum 400 <| Element.fill
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
demo : Tile Model Msg ()
|
||||||
|
demo =
|
||||||
|
{ init = always init
|
||||||
|
, update = update
|
||||||
|
, view = Page.demo view
|
||||||
|
, subscriptions = subscriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
page =
|
||||||
|
Page.create
|
||||||
|
{ title = title
|
||||||
|
, description = description
|
||||||
|
, book = book
|
||||||
|
, demo = demo
|
||||||
|
}
|
280
explorer/src/Page/Modal.elm
Normal file
280
explorer/src/Page/Modal.elm
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
module Page.Modal exposing (page)
|
||||||
|
|
||||||
|
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Browser
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Element.Background as Background
|
||||||
|
import Material.Icons as MaterialIcons
|
||||||
|
import Material.Icons.Types exposing (Coloring(..))
|
||||||
|
import Page
|
||||||
|
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
|
||||||
|
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
|
||||||
|
import Widget exposing (ButtonStyle, ColumnStyle)
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
{-| The title of this page
|
||||||
|
-}
|
||||||
|
title : String
|
||||||
|
title =
|
||||||
|
"Modal"
|
||||||
|
|
||||||
|
|
||||||
|
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||||
|
-}
|
||||||
|
description : String
|
||||||
|
description =
|
||||||
|
"All modal surfaces are interruptive by design – their purpose is to have the user focus on content on a surface that appears in front of all other surfaces."
|
||||||
|
|
||||||
|
|
||||||
|
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||||
|
-}
|
||||||
|
viewFunctions =
|
||||||
|
let
|
||||||
|
viewSingle content onDismiss { palette } () =
|
||||||
|
let
|
||||||
|
contentEl =
|
||||||
|
content
|
||||||
|
|> Element.text
|
||||||
|
|> List.singleton
|
||||||
|
|> Element.paragraph []
|
||||||
|
|> List.singleton
|
||||||
|
|> Widget.column (Material.cardColumn palette)
|
||||||
|
|> Element.el [ Element.padding 8 ]
|
||||||
|
in
|
||||||
|
"Placeholder Text"
|
||||||
|
|> Element.text
|
||||||
|
|> Element.el
|
||||||
|
([ Element.height <| Element.px 200
|
||||||
|
, Element.width <| Element.fill
|
||||||
|
]
|
||||||
|
++ ([ { onDismiss = onDismiss
|
||||||
|
, content = contentEl
|
||||||
|
}
|
||||||
|
, { onDismiss = onDismiss
|
||||||
|
, content =
|
||||||
|
contentEl
|
||||||
|
|> Element.el
|
||||||
|
[ Element.moveDown 10
|
||||||
|
, Element.moveRight 10
|
||||||
|
]
|
||||||
|
}
|
||||||
|
, { onDismiss = onDismiss
|
||||||
|
, content =
|
||||||
|
contentEl
|
||||||
|
|> Element.el
|
||||||
|
[ Element.moveDown 20
|
||||||
|
, Element.moveRight 20
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|> Widget.singleModal
|
||||||
|
)
|
||||||
|
)
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.singleModal"
|
||||||
|
|
||||||
|
viewMulti content onDismiss { palette } () =
|
||||||
|
let
|
||||||
|
contentEl =
|
||||||
|
content
|
||||||
|
|> Element.text
|
||||||
|
|> List.singleton
|
||||||
|
|> Element.paragraph []
|
||||||
|
|> List.singleton
|
||||||
|
|> Widget.column (Material.cardColumn palette)
|
||||||
|
|> Element.el [ Element.padding 8 ]
|
||||||
|
in
|
||||||
|
"Placeholder Text"
|
||||||
|
|> Element.text
|
||||||
|
|> Element.el
|
||||||
|
([ Element.height <| Element.px 200
|
||||||
|
, Element.width <| Element.fill
|
||||||
|
]
|
||||||
|
++ ([ { onDismiss = onDismiss
|
||||||
|
, content = contentEl
|
||||||
|
}
|
||||||
|
, { onDismiss = onDismiss
|
||||||
|
, content =
|
||||||
|
contentEl
|
||||||
|
|> Element.el
|
||||||
|
[ Element.moveDown 10
|
||||||
|
, Element.moveRight 10
|
||||||
|
]
|
||||||
|
}
|
||||||
|
, { onDismiss = onDismiss
|
||||||
|
, content =
|
||||||
|
contentEl
|
||||||
|
|> Element.el
|
||||||
|
[ Element.moveDown 20
|
||||||
|
, Element.moveRight 20
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|> Widget.multiModal
|
||||||
|
)
|
||||||
|
)
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.multiModal"
|
||||||
|
in
|
||||||
|
[ viewSingle, viewMulti ]
|
||||||
|
|> List.foldl Story.addTile
|
||||||
|
Story.initStaticTiles
|
||||||
|
|
||||||
|
|
||||||
|
{-| Let's you play around with the options.
|
||||||
|
Note that the order of these stories must follow the order of the arguments from the view functions.
|
||||||
|
-}
|
||||||
|
book : Tile.Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) ()
|
||||||
|
book =
|
||||||
|
Story.book (Just "Options")
|
||||||
|
viewFunctions
|
||||||
|
--Changing the text of the label
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.textStory "Content"
|
||||||
|
"This is a windows that is in front of everything else. You can allow the user to close it by pressing outside of it or disable this feature."
|
||||||
|
)
|
||||||
|
--Should an event be triggered when pressing the button?
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "With event handler"
|
||||||
|
( Just (), Nothing )
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{- This next section is essentially just a normal Elm program. -}
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Interactive Demonstration
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
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 : Context -> Model -> Element Msg
|
||||||
|
view { palette } (IsEnabled isEnabled) =
|
||||||
|
Widget.button (Material.containedButton palette)
|
||||||
|
{ text = "Show Modal"
|
||||||
|
, icon = MaterialIcons.visibility |> Icon.elmMaterialIcons Color
|
||||||
|
, onPress =
|
||||||
|
ToggleModal True
|
||||||
|
|> Just
|
||||||
|
}
|
||||||
|
|> Element.el
|
||||||
|
([ Element.height <| Element.minimum 200 <| Element.fill
|
||||||
|
, Element.width <| Element.minimum 400 <| Element.fill
|
||||||
|
]
|
||||||
|
++ (if isEnabled then
|
||||||
|
[ { onDismiss =
|
||||||
|
ToggleModal False
|
||||||
|
|> Just
|
||||||
|
, content =
|
||||||
|
"Click on the area around this box to close it."
|
||||||
|
|> Element.text
|
||||||
|
|> List.singleton
|
||||||
|
|> Element.paragraph []
|
||||||
|
|> List.singleton
|
||||||
|
|> Widget.column (Material.cardColumn palette)
|
||||||
|
|> 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 (Material.cardColumn palette)
|
||||||
|
|> 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 (Material.cardColumn palette)
|
||||||
|
|> Element.el
|
||||||
|
[ Element.height <| Element.px 300
|
||||||
|
, Element.width <| Element.px 300
|
||||||
|
, Element.centerX
|
||||||
|
, Element.centerY
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|> Widget.multiModal
|
||||||
|
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
demo : Tile Model Msg ()
|
||||||
|
demo =
|
||||||
|
{ init = always init
|
||||||
|
, update = update
|
||||||
|
, view = Page.demo view
|
||||||
|
, subscriptions = subscriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
page =
|
||||||
|
Page.create
|
||||||
|
{ title = title
|
||||||
|
, description = description
|
||||||
|
, book = book
|
||||||
|
, demo = demo
|
||||||
|
}
|
249
explorer/src/Page/MultiSelect.elm
Normal file
249
explorer/src/Page/MultiSelect.elm
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
module Page.MultiSelect exposing (page)
|
||||||
|
|
||||||
|
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
|
||||||
|
-}
|
||||||
|
import Browser
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Set exposing (Set)
|
||||||
|
import Widget exposing (ButtonStyle, RowStyle)
|
||||||
|
import Widget.Material as Material
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Element.Background as Background
|
||||||
|
import Material.Icons as MaterialIcons
|
||||||
|
import Material.Icons.Types exposing (Coloring(..))
|
||||||
|
import Page
|
||||||
|
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
|
||||||
|
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
|
||||||
|
import Widget
|
||||||
|
import Widget.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
|
||||||
|
|
||||||
|
{-| The title of this page
|
||||||
|
-}
|
||||||
|
title : String
|
||||||
|
title =
|
||||||
|
"Multi Select"
|
||||||
|
|
||||||
|
|
||||||
|
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||||
|
-}
|
||||||
|
description : String
|
||||||
|
description =
|
||||||
|
"Select buttons group a set of actions using layout and spacing."
|
||||||
|
|
||||||
|
|
||||||
|
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||||
|
-}
|
||||||
|
viewFunctions =
|
||||||
|
let
|
||||||
|
viewSelectRow style selected1 selected2 selected3 options onSelect { palette } () =
|
||||||
|
Widget.multiSelect
|
||||||
|
{ selected =
|
||||||
|
[ selected1, selected2, selected3] |> List.filterMap identity
|
||||||
|
|> Set.fromList
|
||||||
|
, options = options
|
||||||
|
, onSelect = onSelect
|
||||||
|
}
|
||||||
|
|> Widget.buttonRow
|
||||||
|
{ elementRow = Material.row
|
||||||
|
, content = style palette
|
||||||
|
}
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.buttonRow "
|
||||||
|
|
||||||
|
viewTogggleRow style selected1 selected2 selected3 options onSelect { palette } () =
|
||||||
|
Widget.multiSelect
|
||||||
|
{ selected = [ selected1, selected2, selected3] |> List.filterMap identity
|
||||||
|
|> Set.fromList
|
||||||
|
, options = options
|
||||||
|
, onSelect = onSelect
|
||||||
|
}
|
||||||
|
|> Widget.toggleRow
|
||||||
|
{ elementRow = Material.toggleRow
|
||||||
|
, content = style palette
|
||||||
|
}
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.toggleRow"
|
||||||
|
|
||||||
|
viewWrappedRow style selected1 selected2 selected3 options onSelect { palette } () =
|
||||||
|
Widget.multiSelect
|
||||||
|
{ selected = [ selected1, selected2, selected3] |> List.filterMap identity
|
||||||
|
|> Set.fromList
|
||||||
|
, options = options
|
||||||
|
, onSelect = onSelect
|
||||||
|
}
|
||||||
|
|> Widget.wrappedButtonRow
|
||||||
|
{ elementRow = Material.row
|
||||||
|
, content = style palette
|
||||||
|
}
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.wrappedButtonRow"
|
||||||
|
|
||||||
|
viewSelectColumn style selected1 selected2 selected3 options onSelect { palette } () =
|
||||||
|
Widget.multiSelect
|
||||||
|
{ selected = [ selected1, selected2, selected3] |> List.filterMap identity
|
||||||
|
|> Set.fromList
|
||||||
|
, options = options
|
||||||
|
, onSelect = onSelect
|
||||||
|
}
|
||||||
|
|> Widget.buttonColumn
|
||||||
|
{ elementColumn = Material.column
|
||||||
|
, content = style palette
|
||||||
|
}
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.buttonColumn"
|
||||||
|
in
|
||||||
|
[ viewTogggleRow, viewSelectRow, viewSelectColumn, viewWrappedRow ]
|
||||||
|
|> List.foldl Story.addTile
|
||||||
|
Story.initStaticTiles
|
||||||
|
|
||||||
|
|
||||||
|
{-| Let's you play around with the options.
|
||||||
|
Note that the order of these stories must follow the order of the arguments from the view functions.
|
||||||
|
-}
|
||||||
|
book : Tile.Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) ()
|
||||||
|
book =
|
||||||
|
Story.book (Just "Options")
|
||||||
|
viewFunctions
|
||||||
|
--Adding a option for different styles.
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Style"
|
||||||
|
( "Contained", Material.containedButton )
|
||||||
|
[ ( "Outlined", Material.outlinedButton )
|
||||||
|
, ( "Text", Material.textButton )
|
||||||
|
, ( "Chip", Material.chip )
|
||||||
|
, ( "IconButton", Material.iconButton )
|
||||||
|
, ( "Toggle", Material.toggleButton )
|
||||||
|
]
|
||||||
|
)
|
||||||
|
--Changing the text of the label
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "Selected First"
|
||||||
|
(Just 0,Nothing)
|
||||||
|
False
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "Selected Second"
|
||||||
|
(Just 1,Nothing)
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "Selected Third"
|
||||||
|
(Just 2,Nothing)
|
||||||
|
True
|
||||||
|
)
|
||||||
|
--Change the Icon
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Options"
|
||||||
|
( "3 Option"
|
||||||
|
, [ { icon = always Element.none, text = "Submit" }
|
||||||
|
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "" }
|
||||||
|
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "Submit" }
|
||||||
|
]
|
||||||
|
)
|
||||||
|
[ ( "2 Option"
|
||||||
|
, [ { icon = always Element.none, text = "Submit" }
|
||||||
|
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "" }
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, ( "1 Option", [ { icon = always Element.none, text = "Submit" } ] )
|
||||||
|
]
|
||||||
|
)
|
||||||
|
--Should an event be triggered when pressing the button?
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "With event handler"
|
||||||
|
( always <| Just (), always Nothing )
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|> Story.build
|
||||||
|
|
||||||
|
|
||||||
|
{- This next section is essentially just a normal Elm program. -}
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Interactive Demonstration
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
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 : Context -> Model -> Element Msg
|
||||||
|
view {palette} (Selected selected) =
|
||||||
|
{ selected = selected
|
||||||
|
, options =
|
||||||
|
[ 1, 2, 42 ]
|
||||||
|
|> List.map
|
||||||
|
(\int ->
|
||||||
|
{ text = String.fromInt int
|
||||||
|
, icon = always Element.none
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, onSelect = ChangedSelected >> Just
|
||||||
|
}
|
||||||
|
|> Widget.multiSelect
|
||||||
|
|> Widget.buttonRow
|
||||||
|
{ elementRow = Material.toggleRow
|
||||||
|
, content = Material.toggleButton palette
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
demo : Tile Model Msg ()
|
||||||
|
demo =
|
||||||
|
{ init = always init
|
||||||
|
, update = update
|
||||||
|
, view = Page.demo view
|
||||||
|
, subscriptions = subscriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
page =
|
||||||
|
Page.create
|
||||||
|
{ title = title
|
||||||
|
, description = description
|
||||||
|
, book = book
|
||||||
|
, demo = demo
|
||||||
|
}
|
||||||
|
|
149
explorer/src/Page/ProgressIndicator.elm
Normal file
149
explorer/src/Page/ProgressIndicator.elm
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
module Page.ProgressIndicator exposing (page)
|
||||||
|
|
||||||
|
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
|
||||||
|
-}
|
||||||
|
import Browser
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Widget exposing (ProgressIndicatorStyle)
|
||||||
|
import Widget.Material as Material
|
||||||
|
import Element exposing (Element)
|
||||||
|
import Element.Background as Background
|
||||||
|
import Material.Icons as MaterialIcons
|
||||||
|
import Material.Icons.Types exposing (Coloring(..))
|
||||||
|
import Page
|
||||||
|
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
|
||||||
|
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
|
||||||
|
import Widget
|
||||||
|
import Widget.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
|
||||||
|
|
||||||
|
|
||||||
|
{-| The title of this page
|
||||||
|
-}
|
||||||
|
title : String
|
||||||
|
title =
|
||||||
|
"Progress Indicator"
|
||||||
|
|
||||||
|
|
||||||
|
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||||
|
-}
|
||||||
|
description : String
|
||||||
|
description =
|
||||||
|
"Progress indicators express an unspecified wait time or display the length of a process."
|
||||||
|
|
||||||
|
|
||||||
|
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||||
|
-}
|
||||||
|
viewFunctions =
|
||||||
|
let
|
||||||
|
viewIndicator style progress indeterminate { palette } () =
|
||||||
|
Widget.circularProgressIndicator (style palette)
|
||||||
|
(indeterminate (toFloat progress/ 100 ))
|
||||||
|
--Don't forget to change the title
|
||||||
|
|> Page.viewTile "Widget.circularProgressIndicator"
|
||||||
|
|
||||||
|
in
|
||||||
|
[ viewIndicator ]
|
||||||
|
|> List.foldl Story.addTile
|
||||||
|
Story.initStaticTiles
|
||||||
|
|
||||||
|
|
||||||
|
{-| Let's you play around with the options.
|
||||||
|
Note that the order of these stories must follow the order of the arguments from the view functions.
|
||||||
|
-}
|
||||||
|
book : Tile.Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) ()
|
||||||
|
book =
|
||||||
|
Story.book (Just "Options")
|
||||||
|
viewFunctions
|
||||||
|
--Adding a option for different styles.
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.optionListStory "Style"
|
||||||
|
( "ProgressIndicator", Material.progressIndicator )
|
||||||
|
[ ]
|
||||||
|
)
|
||||||
|
--Changing the text of the label
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.rangeStory "Progress"
|
||||||
|
{ unit = "%", min = 0, max = 100, default = 50 }
|
||||||
|
|
||||||
|
)
|
||||||
|
--Should an event be triggered when pressing the button?
|
||||||
|
|> Story.addStory
|
||||||
|
(Story.boolStory "Indeterminate Indicator"
|
||||||
|
( always Nothing, Just )
|
||||||
|
False
|
||||||
|
)
|
||||||
|
|> Story.build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{- This next section is essentially just a normal Elm program. -}
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Interactive Demonstration
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
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 : Context -> Model -> Element Msg
|
||||||
|
view {palette} (MaybeProgress maybeProgress) =
|
||||||
|
Widget.circularProgressIndicator (Material.progressIndicator palette)
|
||||||
|
maybeProgress
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
demo : Tile Model Msg ()
|
||||||
|
demo =
|
||||||
|
{ init = always init
|
||||||
|
, update = update
|
||||||
|
, view = Page.demo view
|
||||||
|
, subscriptions = subscriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
page =
|
||||||
|
Page.create
|
||||||
|
{ title = title
|
||||||
|
, description = description
|
||||||
|
, book = book
|
||||||
|
, demo = demo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -701,6 +701,7 @@ viewSuccess config ((PageBuilder pages) as pages_) model =
|
|||||||
:: Element.inFront
|
:: Element.inFront
|
||||||
(Element.el
|
(Element.el
|
||||||
[ Element.height <| Element.px (Pixels.inPixels model.windowSize.height)
|
[ Element.height <| Element.px (Pixels.inPixels model.windowSize.height)
|
||||||
|
, Element.scrollbarY
|
||||||
, Element.Font.size 16
|
, Element.Font.size 16
|
||||||
]
|
]
|
||||||
(viewSidebar pages_ config model)
|
(viewSidebar pages_ config model)
|
||||||
|
Loading…
Reference in New Issue
Block a user