Merge pull request #65 from Orasund/unstable

Added additional Pages to Explorer
This commit is contained in:
Orasund 2021-06-04 09:45:37 +02:00 committed by GitHub
commit 029fd2efd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 20758 additions and 252 deletions

19905
explorer/index.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,15 +3,18 @@ module Main exposing (main)
import Element
import Page.Button
import Page.PasswordInput
import Page.Select
import Page.Switch
import Page.Tab
import UIExplorer
pages =
UIExplorer.firstPage "Button" Page.Button.page
--|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|> UIExplorer.nextPage "Select" Page.Select.page
|> UIExplorer.nextPage "Switch" Page.Switch.page
|> UIExplorer.nextPage "Tab" Page.Tab.page
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
main =

View File

@ -1,9 +1,9 @@
module Page exposing (create, viewTile)
module Page exposing (create, demo, viewTile)
import Element exposing (Element)
import UIExplorer exposing (Page)
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
import UIExplorer.Tile as Tile exposing (Group, Tile, TileMsg)
import UIExplorer.Tile as Tile exposing (Context, Group, Position, Tile, TileMsg)
import Widget.Material as Material exposing (Palette)
import Widget.Material.Typography as Typography
@ -21,17 +21,17 @@ create :
, demo : Tile model msg ()
}
-> Page ( ( ( (), () ), ( StorySelectorModel, () ) ), model ) (TileMsg (TileMsg (TileMsg () msg1) (TileMsg StorySelectorMsg ())) msg) ()
create { title, description, book, demo } =
create config =
Tile.static []
(\_ _ ->
[ title |> Element.text |> Element.el Typography.h3
, description |> Element.text |> Element.el []
[ config.title |> Element.text |> Element.el Typography.h3
, config.description |> Element.text |> List.singleton |> Element.paragraph []
]
|> Element.column [ Element.spacing 32 ]
)
|> Tile.first
|> Tile.nextGroup book
|> Tile.next demo
|> Tile.nextGroup config.book
|> Tile.next config.demo
|> Tile.page
@ -59,3 +59,21 @@ viewTile title content =
, content
]
}
demo :
(Context -> model -> Element msg)
->
(Context
-> model
-> { title : Maybe String, position : Position, attributes : List b, body : Element msg }
)
demo fun context model =
fun context model
|> (\body ->
{ title = Just "Interactive Demo"
, position = Tile.FullWidthTile
, attributes = []
, body = body
}
)

View File

@ -5,25 +5,15 @@ module Page.Button exposing (page)
import Element exposing (Element)
import Element.Background as Background
import Element.Font
import Material.Icons as MaterialIcons exposing (offline_bolt)
import Material.Icons as MaterialIcons
import Material.Icons.Types exposing (Coloring(..))
import Page
import UIExplorer
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
import UIExplorer.Tile as Tile exposing (Context, Position, Tile, TileMsg)
import Widget exposing (ButtonStyle)
import UIExplorer.Tile as Tile exposing (Context, Tile, TileMsg)
import Widget
import Widget.Customize as Customize
import Widget.Icon as Icon exposing (Icon)
import Widget.Icon as Icon
import Widget.Material as Material
exposing
( Palette
, containedButton
, darkPalette
, defaultPalette
, outlinedButton
, textButton
)
import Widget.Material.Color as MaterialColor
import Widget.Material.Typography as Typography
@ -46,8 +36,8 @@ description =
-}
viewFunctions =
let
viewButton button text icon onPress { palette } () =
Widget.button (button palette)
viewButton style text icon onPress { palette } () =
Widget.button (style palette)
{ text = text
, icon = icon
, onPress = onPress
@ -55,9 +45,9 @@ viewFunctions =
--Don't forget to change the title
|> Page.viewTile "Widget.button"
viewTextButton button text icon onPress { palette } () =
viewTextButton style text _ onPress { palette } () =
Widget.textButton
(button palette
(style palette
|> Customize.elementButton
[ Element.alignLeft
, Element.centerY
@ -69,9 +59,9 @@ viewFunctions =
--Don't forget to change the title
|> Page.viewTile "Widget.textButton"
viewIconButton button text icon onPress { palette } () =
viewIconButton style text icon onPress { palette } () =
Widget.iconButton
(button palette
(style palette
|> Customize.elementButton
[ Element.alignLeft
, Element.centerY
@ -98,10 +88,9 @@ book =
--Adding a option for different styles.
|> Story.addStory
(Story.optionListStory "Style"
containedButton
[ ( "contained", containedButton )
, ( "outlined", outlinedButton )
, ( "text", textButton )
( "Contained", Material.containedButton )
[ ( "Outlined", Material.outlinedButton )
, ( "Text", Material.textButton )
]
)
--Changing the text of the label
@ -111,19 +100,16 @@ book =
)
--Change the Icon
|> Story.addStory
(Story.optionListStory "Icon"
(MaterialIcons.done
(Story.boolStory "With Icon"
( MaterialIcons.done
|> Icon.elmMaterialIcons Color
, always Element.none
)
[ ( "done"
, MaterialIcons.done
|> Icon.elmMaterialIcons Color
)
]
True
)
--Should an event be triggered when pressing the button?
|> Story.addStory
(Story.boolStory "with event handler"
(Story.boolStory "With event handler"
( Just (), Nothing )
True
)
@ -131,10 +117,10 @@ book =
{- This next section is essentially just a normal Elm program. -}
--------------------------------------------------------------------------------
-- Interactive Demonstration
--------------------------------------------------------------------------------
{- This section here is essentially just a normal Elm program. -}
type alias Model =
@ -148,10 +134,6 @@ type Msg
| Noop
--|> Story.addTile (Just "Interactive example") view
init : ( Model, Cmd Msg )
init =
( 0, Cmd.none )
@ -188,7 +170,7 @@ subscriptions _ =
Sub.none
view : Context -> Int -> { title : Maybe String, position : Position, attributes : List b, body : Element Msg }
view : Context -> Model -> Element Msg
view { palette } model =
let
style =
@ -201,108 +183,103 @@ view { palette } model =
, cardColumn = Material.cardColumn palette
}
in
{ title = Just "Interactive Demo"
, position = Tile.FullWidthTile
, attributes = []
, body =
[ 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
[ 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
|> Just
}
|> Element.el [ Element.alignRight ]
|> Element.inFront
]
|> Customize.mapContent
(Customize.element
[ 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
|> Just
}
|> Element.el [ Element.alignRight ]
|> Element.inFront
, Material.defaultPalette.secondary
|> MaterialColor.fromColor
|> Background.color
]
|> 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
)
)
, [ [ Widget.textButton style.textButton
{ text = "Reset"
, onPress =
Reset
|> Just
}
, Widget.button style.outlinedButton
{ text = "Decrease"
, icon =
MaterialIcons.remove
|> Icon.elmMaterialIcons Color
, onPress =
if model > 0 then
Decrease 1
|> Just
}
, Widget.button style.outlinedButton
{ text = "Decrease"
, icon =
MaterialIcons.remove
|> Icon.elmMaterialIcons Color
, onPress =
if model > 0 then
Decrease 1
|> 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
|> 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 ])
)
else
Nothing
}
]
|> Widget.column
(style.column
|> Customize.elementColumn [ Element.width <| Element.fill ]
|> Customize.mapContent (Customize.element [ Element.width <| Element.fill ])
)
}
|> Widget.row (style.row |> Customize.elementRow [ Element.alignRight ])
, [ Widget.button style.containedButton
{ text = "Increase"
, icon =
MaterialIcons.add
|> Icon.elmMaterialIcons Color
, onPress =
Increase 1
|> 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 ])
)
--------------------------------------------------------------------------------
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
--------------------------------------------------------------------------------
demo : Tile Model Msg ()
demo =
{ init = always init
, update = update
, view = view
, view = Page.demo view
, subscriptions = subscriptions
}
--------------------------------------------------------------------------------
-- DO NOT MODIFY ANTHING AFTER THIS LINE
--------------------------------------------------------------------------------
page =
Page.create
{ title = title

View File

@ -1,71 +1,80 @@
module Page.PasswordInput exposing (Model, Msg, init, page, subscriptions, update, view)
import Browser
import Element exposing (Element)
import Element.Background as Background
import Element.Font
import Element.Input as Input
import Material.Icons as MaterialIcons exposing (offline_bolt)
import Material.Icons.Types exposing (Coloring(..))
import Set exposing (Set)
import UIExplorer
import Page
import UIExplorer.Story as Story
import UIExplorer.Tile as Tile
import Widget exposing (ColumnStyle, PasswordInputStyle)
import Widget.Customize as Customize
import Widget.Icon as Icon exposing (Icon)
import UIExplorer.Tile exposing (Context, Tile)
import Widget
import Widget.Material as Material
exposing
( Palette
, containedButton
, darkPalette
( darkPalette
, defaultPalette
, outlinedButton
, textButton
)
import Widget.Material.Color as MaterialColor
import Widget.Material.Typography as Typography
page =
Tile.first (intro |> Tile.withTitle "Password Input")
|> Tile.nextGroup book
|> Tile.next demo
|> Tile.page
{-| The title of this page
-}
title : String
title =
"Password Input"
intro =
Tile.markdown []
""" An input field for a password. """
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
-}
description : String
description =
"If we want to play nicely with a browser's ability to autofill a form, we need to be able to give it a hint about what we're expecting.\n \nThe following inputs are very similar to Input.text, but they give the browser a hint to allow autofill to work correctly."
{-| List of view functions. Essentially, anything that takes a Button as input.
-}
viewFunctions =
let
viewCurrentPassword text placeholder label { palette } () =
Widget.currentPasswordInput (Material.passwordInput palette)
{ text = text
, placeholder = placeholder
, label = label
, onChange = always ()
, show = False
}
--Don't forget to change the title
|> Page.viewTile "Widget.currentPasswordInput"
viewNewPassword text placeholder label { palette } () =
Widget.newPasswordInput (Material.passwordInput palette)
{ text = text
, placeholder = placeholder
, label = label
, onChange = always ()
, show = False
}
--Don't forget to change the title
|> Page.viewTile "Widget.newPasswordInput"
in
[ viewNewPassword, viewCurrentPassword ]
|> List.foldl Story.addTile
Story.initStaticTiles
book =
Story.book (Just "options")
(Story.initStaticTiles
|> Story.addTile viewPassword
)
|> Story.addStory
(Story.optionListStory "Palette"
darkPalette
[ ( "dark", darkPalette )
, ( "default", defaultPalette )
]
)
Story.book (Just "Options")
viewFunctions
|> Story.addStory
(Story.textStory "Text"
"123456789"
)
|> Story.addStory
(Story.optionListStory "Placeholder"
Nothing
[ ( "Yes"
, "password"
|> Element.text
|> Input.placeholder []
|> Just
)
, ( "No", Nothing )
]
(Story.boolStory "Placeholder"
( "password"
|> Element.text
|> Input.placeholder []
|> Just
, Nothing
)
True
)
|> Story.addStory
(Story.textStory "Label"
@ -74,65 +83,28 @@ book =
|> Story.build
type alias Style style msg =
{ style
| passwordInput : PasswordInputStyle msg
, column : ColumnStyle msg
}
viewLabel : String -> Element msg
viewLabel =
Element.el [ Element.width <| Element.px 250 ] << Element.text
viewPassword palette text placeholder label _ _ =
{ title = Nothing
, position = Tile.LeftColumnTile
, attributes = [ Background.color <| MaterialColor.fromColor palette.surface ]
, body =
Element.column
[ Element.width Element.fill
, Element.centerY
, Element.Font.color <| MaterialColor.fromColor palette.on.surface
]
[ viewLabel "Current Password"
, { text = text
, placeholder = placeholder
, label = label
, onChange = always ()
, show = False
}
|> Widget.currentPasswordInput (Material.passwordInput palette)
]
}
---{- This next section is essentially just a normal Elm program. -}
-----------------------------------------------------------------------------
-- Interactive Demonstration
--------------------------------------------------------------------------------
-- Example
--------------------------------------------------------------------------------
materialStyle : Style {} msg
materialStyle =
{ passwordInput = Material.passwordInput Material.defaultPalette
, column = Material.column
}
type alias Model =
{ passwordInput : String
, newInput : String
}
type Msg
= SetPasswordInput String
| SetNewPasswordInput String
init : ( Model, Cmd Msg )
init =
( { passwordInput = ""
, newInput = ""
}
, Cmd.none
)
@ -144,30 +116,71 @@ update msg model =
SetPasswordInput string ->
( { model | passwordInput = string }, Cmd.none )
SetNewPasswordInput string ->
( { model | newInput = string }, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
view _ model =
{ title = Just "Interactive Demo"
, position = Tile.FullWidthTile
, attributes = []
, body =
{ text = model.passwordInput
, placeholder = Nothing
, label = "Chips"
, onChange = SetPasswordInput
, show = False
}
|> Widget.currentPasswordInput (Material.passwordInput Material.defaultPalette)
}
view : Context -> Model -> Element Msg
view { palette } model =
[ "Try fill out these fields using autofill" |> Element.text
, [ "Current Password"
|> Element.text
|> Element.el [ Element.width <| Element.fill ]
, Widget.currentPasswordInput (Material.passwordInput palette)
{ text = model.passwordInput
, placeholder = Nothing
, label = "Chips"
, onChange = SetPasswordInput
, show = False
}
]
|> Element.row [ Element.width <| Element.fill, Element.spaceEvenly ]
, [ "New Password"
|> Element.text
|> Element.el [ Element.width <| Element.fill ]
, Widget.newPasswordInput (Material.passwordInput palette)
{ text = model.newInput
, placeholder = Nothing
, label = "Chips"
, onChange = SetNewPasswordInput
, show = False
}
]
|> Element.row [ Element.width <| Element.fill, Element.spaceEvenly ]
, Element.text <|
if (model.newInput /= "") && (model.newInput == model.passwordInput) then
"Yeay, the two passwords match!"
else
""
]
|> Element.column [ Element.width <| Element.fill, Element.spacing 8 ]
--------------------------------------------------------------------------------
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
--------------------------------------------------------------------------------
demo : Tile Model Msg ()
demo =
{ init = always init
, update = update
, view = view
, view = Page.demo view
, subscriptions = subscriptions
}
page =
Page.create
{ title = title
, description = description
, book = book
, demo = demo
}

View File

@ -0,0 +1,214 @@
module Page.Select exposing (page)
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
-}
import Element exposing (Element)
import Element.Background as Background
import Element.Font
import Material.Icons as MaterialIcons exposing (offline_bolt)
import Material.Icons.Types exposing (Coloring(..))
import Page
import UIExplorer
import UIExplorer.Story as Story exposing (StorySelectorModel, StorySelectorMsg)
import UIExplorer.Tile as Tile exposing (Context, Position, Tile, TileMsg)
import Widget exposing (ButtonStyle)
import Widget.Customize as Customize
import Widget.Icon as Icon exposing (Icon)
import Widget.Material as Material exposing (Palette)
import Widget.Material.Color as MaterialColor
import Widget.Material.Typography as Typography
{-| The title of this page
-}
title : String
title =
"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
viewSelectButtonRow style selected options onSelect { palette } () =
Widget.select
{ selected = selected
, options = options
, onSelect = onSelect
}
|> Widget.buttonRow
{ elementRow = Material.buttonRow
, content = style palette
}
--Don't forget to change the title
|> Page.viewTile "Widget.buttonRow with Material.buttonRow"
viewSelectRow style selected options onSelect { palette } () =
Widget.select
{ selected = selected
, options = options
, onSelect = onSelect
}
|> Widget.buttonRow
{ elementRow = Material.row
, content = style palette
}
--Don't forget to change the title
|> Page.viewTile "Widget.buttonRow with Material.row"
viewSelectColumn style selected options onSelect { palette } () =
Widget.select
{ selected = selected
, options = options
, onSelect = onSelect
}
|> Widget.buttonColumn
{ elementColumn = Material.column
, content = style palette
}
--Don't forget to change the title
|> Page.viewTile "Widget.buttonColumn"
in
[ viewSelectButtonRow, viewSelectRow, viewSelectColumn ]
|> 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 )
, ( "Toggle", Material.toggleButton )
]
)
--Changing the text of the label
|> Story.addStory
(Story.optionListStory "Selected"
( "Third", Just 2 )
[ ( "Second", Just 1 )
, ( "First", Just 0 )
, ( "Nothing or Invalid", Nothing )
]
)
--Change the Icon
|> Story.addStory
(Story.optionListStory "Options"
( "3 Option"
, [ { icon = always Element.none, text = "42" }
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "" }
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "42" }
]
)
[ ( "2 Option"
, [ { icon = always Element.none, text = "42" }
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "" }
]
)
, ( "1 Option", [ { icon = always Element.none, text = "42" } ] )
]
)
--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 (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 : 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.select
|> Widget.buttonRow
{ elementRow = Material.buttonRow
, content = Material.toggleButton palette
}
--------------------------------------------------------------------------------
-- DO NOT MODIFY ANYTHING AFTER THIS LINE
--------------------------------------------------------------------------------
demo =
{ init = always init
, view = Page.demo view
, update = update
, subscriptions = subscriptions
}
page =
Page.create
{ title = title
, description = description
, book = book
, demo = demo
}

View File

@ -0,0 +1,163 @@
module Page.Switch exposing (page)
{-| This is an example Page. If you want to add your own pages, simple copy and modify this one.
-}
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
exposing
( containedButton
, outlinedButton
, textButton
)
import Widget.Material.Color as MaterialColor
import Widget.Material.Typography as Typography
{-| The title of this page
-}
title : String
title =
"Switch"
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
-}
description : String
description =
"Switches toggle the state of a single item on or off."
{-| List of view functions. Essentially, anything that takes a Button as input.
-}
viewFunctions =
let
viewSwitch style desc active onPress { palette } () =
Widget.switch (style palette)
{ description = desc
, active = active
, onPress = onPress
}
--Don't forget to change the title
|> Page.viewTile "Widget.switch"
in
[ viewSwitch ]
|> 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"
( "Switch", Material.switch )
[]
)
--Changing the text of the label
|> Story.addStory
(Story.textStory "Description"
"Be Awesome"
)
--Change the Icon
|> Story.addStory
(Story.boolStory "Active"
( True
, False
)
True
)
--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
= 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 : Context -> Model -> Element Msg
view { palette } (IsButtonEnabled isButtonEnabled) =
Widget.switch (Material.switch palette)
{ description = "click me"
, active = isButtonEnabled
, onPress =
ToggledButtonStatus
|> Just
}
--------------------------------------------------------------------------------
-- 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
}

213
explorer/src/Page/Tab.elm Normal file
View File

@ -0,0 +1,213 @@
module Page.Tab 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 (TabStyle)
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 =
"Tab"
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
-}
description : String
description =
"Tabs organize content across different screens, data sets, and other interactions."
{-| List of view functions. Essentially, anything that takes a Button as input.
-}
viewFunctions =
let
viewTab style selected options onSelect { palette } () =
Widget.tab (style palette)
{ tabs =
{ selected = selected
, options = options
, onSelect = onSelect
}
, 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
}
--Don't forget to change the title
|> Page.viewTile "Widget.tab"
in
[ viewTab ]
|> 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"
( "Tab", Material.tab )
[]
)
--Changing the text of the label
|> Story.addStory
(Story.optionListStory "Selected"
( "Third", Just 2 )
[ ( "Second", Just 1 )
, ( "First", Just 0 )
, ( "Nothing or Invalid", Nothing )
]
)
--Change the Icon
|> Story.addStory
(Story.optionListStory "Options"
( "3 Option"
, [ { icon = always Element.none, text = "42" }
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "" }
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "42" }
]
)
[ ( "2 Option"
, [ { icon = always Element.none, text = "42" }
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "" }
]
)
, ( "1 Option", [ { icon = always Element.none, text = "42" } ] )
]
)
--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 (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 : Context -> Model -> Element Msg
view { palette } (Selected selected) =
Widget.tab (Material.tab palette)
{ tabs =
{ selected = selected
, options =
[ 1, 2, 3 ]
|> List.map
(\int ->
{ text = "Tab " ++ (int |> String.fromInt)
, icon = always Element.none
}
)
, onSelect = ChangedTab >> 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
}
--------------------------------------------------------------------------------
-- 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

@ -23,12 +23,12 @@ type alias Story a =
}
optionListStory : String -> a -> List ( String, a ) -> Story a
optionListStory label default options =
{ info = OptionListStory label <| List.map Tuple.first options
optionListStory : String -> ( String, a ) -> List ( String, a ) -> Story a
optionListStory label first options =
{ info = OptionListStory label <| List.map Tuple.first (first :: options)
, toValue =
\optLabel ->
options
(first :: options)
|> List.foldl
(\( key, optvalue ) res ->
case ( res, optLabel == key ) of
@ -42,7 +42,7 @@ optionListStory label default options =
Nothing
)
Nothing
|> Maybe.withDefault default
|> Maybe.withDefault (first |> Tuple.second)
}
@ -319,7 +319,7 @@ storyView : Context -> StoryModel -> Element StorySelectorMsg
storyView context model =
case model of
RangeStoryModel label { unit, min, max, value } ->
Element.column [ Element.spacing 8 ]
Element.column [ Element.spacing 8, Element.width Element.fill ]
[ label
++ " ("
++ String.fromInt value
@ -339,7 +339,7 @@ storyView context model =
]
TextStoryModel label value ->
Element.column [ Element.spacing 8 ]
Element.column [ Element.spacing 8, Element.width Element.fill ]
[ Element.text label |> Element.el Typography.caption
, Widget.textInput (Material.textInput context.palette)
{ chips = []
@ -351,7 +351,7 @@ storyView context model =
]
OptionListStoryModel label options ->
Element.column [ Element.spacing 8 ]
Element.column [ Element.spacing 8, Element.width Element.fill ]
[ Element.text label |> Element.el Typography.caption
, { selected =
Just <| SelectList.index options
@ -421,7 +421,7 @@ storyTile title stories storiesToValue =
, body =
model
|> List.map (storyView context)
|> Element.column [ Element.spacing 8 ]
|> Element.column [ Element.spacing 8, Element.width Element.fill ]
}
]
}

View File

@ -283,7 +283,7 @@ layoutView palette _ view =
Just string ->
[ string
|> Widget.headerItem (Material.fullBleedHeader palette)
, view.body |> Widget.asItem
, view.body |> Element.el [ Element.width Element.fill ] |> Widget.asItem
]
|> Widget.itemList (Material.cardColumn palette)
@ -323,9 +323,7 @@ layoutRowView palette row =
]
<|
List.map
(layoutView palette
[ Element.height Element.fill ]
)
(layoutView palette [ Element.height Element.fill ])
<|
List.reverse right
]

View File

@ -30,6 +30,7 @@ passwordInput palette =
|> Border.color
]
, Element.mouseOver [ Border.shadow <| MaterialColor.shadow 2 ]
, Element.width <| Element.px <| 280
]
, content =
{ password =

View File

@ -29,6 +29,7 @@ textInput palette =
|> MaterialColor.fromColor
|> Border.color
]
, Element.width <| Element.px <| 280
, Element.mouseOver [ Border.shadow <| MaterialColor.shadow 2 ]
]
, content =