Merge pull request #73 from Orasund/unstable

Add Additional Pages
This commit is contained in:
Orasund 2021-06-08 14:13:39 +02:00 committed by GitHub
commit 9f27c296a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1382 additions and 0 deletions

View File

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

View File

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

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

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

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

View File

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