mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-22 04:58:49 +03:00
Merge pull request #71 from Orasund/unstable
Added TextInput, SortTable and Snackbar Pages
This commit is contained in:
commit
53a1e248d6
@ -13,6 +13,7 @@
|
||||
"elm/html": "1.0.0",
|
||||
"elm/json": "1.1.3",
|
||||
"elm/svg": "1.0.1",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/url": "1.0.0",
|
||||
"elm-explorations/markdown": "1.0.0",
|
||||
"ianmackenzie/elm-units": "2.9.0",
|
||||
@ -26,7 +27,6 @@
|
||||
},
|
||||
"indirect": {
|
||||
"elm/regex": "1.0.0",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.2",
|
||||
"fredcy/elm-parseint": "2.0.1"
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ import Element
|
||||
import Page.Button
|
||||
import Page.PasswordInput
|
||||
import Page.Select
|
||||
import Page.Snackbar
|
||||
import Page.SortTable
|
||||
import Page.Switch
|
||||
import Page.Tab
|
||||
import Page.TextInput
|
||||
import UIExplorer
|
||||
|
||||
|
||||
@ -15,6 +18,9 @@ pages =
|
||||
|> UIExplorer.nextPage "Switch" Page.Switch.page
|
||||
|> UIExplorer.nextPage "Tab" Page.Tab.page
|
||||
|> UIExplorer.nextPage "Password Input" Page.PasswordInput.page
|
||||
|> UIExplorer.nextPage "Text Input" Page.TextInput.page
|
||||
|> UIExplorer.nextPage "Sort Table" Page.SortTable.page
|
||||
|> UIExplorer.nextPage "Snackbar" Page.Snackbar.page
|
||||
|
||||
|
||||
main =
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Page exposing (create, demo, viewTile)
|
||||
module Page exposing (create, create2, demo, viewTile)
|
||||
|
||||
import Element exposing (Element)
|
||||
import UIExplorer exposing (Page)
|
||||
@ -35,6 +35,29 @@ create config =
|
||||
|> Tile.page
|
||||
|
||||
|
||||
create2 :
|
||||
{ title : String
|
||||
, description : String
|
||||
, book1 : Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) ()
|
||||
, book2 : Group ( StorySelectorModel, () ) (TileMsg StorySelectorMsg ()) ()
|
||||
, demo : Tile model msg ()
|
||||
}
|
||||
-> Page ( ( ( ( (), () ), ( StorySelectorModel, () ) ), ( StorySelectorModel, () ) ), model ) (TileMsg (TileMsg (TileMsg (TileMsg () msg1) (TileMsg StorySelectorMsg ())) (TileMsg StorySelectorMsg ())) msg) ()
|
||||
create2 config =
|
||||
Tile.static []
|
||||
(\_ _ ->
|
||||
[ 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 config.book1
|
||||
|> Tile.nextGroup config.book2
|
||||
|> Tile.next config.demo
|
||||
|> Tile.page
|
||||
|
||||
|
||||
viewTile :
|
||||
String
|
||||
-> Element msg
|
||||
|
@ -32,24 +32,24 @@ description =
|
||||
-}
|
||||
viewFunctions =
|
||||
let
|
||||
viewCurrentPassword text placeholder label { palette } () =
|
||||
viewCurrentPassword text placeholder label show { palette } () =
|
||||
Widget.currentPasswordInput (Material.passwordInput palette)
|
||||
{ text = text
|
||||
, placeholder = placeholder
|
||||
, label = label
|
||||
, onChange = always ()
|
||||
, show = False
|
||||
, show = show
|
||||
}
|
||||
--Don't forget to change the title
|
||||
|> Page.viewTile "Widget.currentPasswordInput"
|
||||
|
||||
viewNewPassword text placeholder label { palette } () =
|
||||
viewNewPassword text placeholder label show { palette } () =
|
||||
Widget.newPasswordInput (Material.passwordInput palette)
|
||||
{ text = text
|
||||
, placeholder = placeholder
|
||||
, label = label
|
||||
, onChange = always ()
|
||||
, show = False
|
||||
, show = show
|
||||
}
|
||||
--Don't forget to change the title
|
||||
|> Page.viewTile "Widget.newPasswordInput"
|
||||
@ -80,6 +80,13 @@ book =
|
||||
(Story.textStory "Label"
|
||||
"Password"
|
||||
)
|
||||
|> Story.addStory
|
||||
(Story.boolStory "Show"
|
||||
( True
|
||||
, False
|
||||
)
|
||||
True
|
||||
)
|
||||
|> Story.build
|
||||
|
||||
|
||||
@ -127,7 +134,7 @@ subscriptions _ =
|
||||
|
||||
view : Context -> Model -> Element Msg
|
||||
view { palette } model =
|
||||
[ "Try fill out these fields using autofill" |> Element.text
|
||||
[ "Try filling out these fields using autofill" |> Element.text
|
||||
, [ "Current Password"
|
||||
|> Element.text
|
||||
|> Element.el [ Element.width <| Element.fill ]
|
||||
|
223
explorer/src/Page/Snackbar.elm
Normal file
223
explorer/src/Page/Snackbar.elm
Normal file
@ -0,0 +1,223 @@
|
||||
module Page.Snackbar 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 Time
|
||||
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
|
||||
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
|
||||
viewSnackbar style text button { palette } () =
|
||||
Snackbar.view (style palette)
|
||||
identity
|
||||
(Snackbar.init
|
||||
|> Snackbar.insert
|
||||
{ text = text
|
||||
, button = button
|
||||
}
|
||||
)
|
||||
|> Maybe.withDefault Element.none
|
||||
--Don't forget to change the title
|
||||
|> Page.viewTile "Snackbar.view"
|
||||
in
|
||||
[ viewSnackbar ]
|
||||
|> 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"
|
||||
( "Snackbar", Material.snackbar )
|
||||
[]
|
||||
)
|
||||
--Changing the text of the label
|
||||
|> Story.addStory
|
||||
(Story.textStory "Text"
|
||||
"This is a notification that will close after 10 seconds. Additional notifications are being queued."
|
||||
)
|
||||
--Change the Icon
|
||||
|> Story.addStory
|
||||
(Story.optionListStory "Button"
|
||||
( "Button with event handler"
|
||||
, Just
|
||||
{ text = "Close"
|
||||
, onPress = Just ()
|
||||
}
|
||||
)
|
||||
[ ( "Eventless Button"
|
||||
, Just
|
||||
{ text = "Close"
|
||||
, onPress = Nothing
|
||||
}
|
||||
)
|
||||
, ( "None"
|
||||
, Nothing
|
||||
)
|
||||
]
|
||||
)
|
||||
|> Story.build
|
||||
|
||||
|
||||
|
||||
{- This next section is essentially just a normal Elm program. -}
|
||||
--------------------------------------------------------------------------------
|
||||
-- Interactive Demonstration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
type alias Model =
|
||||
Snackbar ( String, Bool )
|
||||
|
||||
|
||||
type Msg
|
||||
= AddSnackbar ( String, Bool )
|
||||
| TimePassed Int
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( Snackbar.init
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
TimePassed int ->
|
||||
( model |> Snackbar.timePassed int
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
AddSnackbar snack ->
|
||||
( model |> Snackbar.dismiss |> Snackbar.insert snack
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Time.every 50 (always (TimePassed 50))
|
||||
|
||||
|
||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
||||
-}
|
||||
view : Context -> Model -> Element Msg
|
||||
view { palette } model =
|
||||
[ Widget.button (Material.containedButton palette)
|
||||
{ onPress =
|
||||
Just <|
|
||||
AddSnackbar <|
|
||||
( "This is a notification. It will disappear after 10 seconds."
|
||||
, False
|
||||
)
|
||||
, text = "Add Notification"
|
||||
, icon = always Element.none
|
||||
}
|
||||
, Widget.button (Material.containedButton palette)
|
||||
{ onPress =
|
||||
Just <|
|
||||
AddSnackbar <|
|
||||
( "You can add another notification if you want."
|
||||
, True
|
||||
)
|
||||
, text = "Add Notification with Action"
|
||||
, icon = always Element.none
|
||||
}
|
||||
]
|
||||
|> Widget.column Material.column
|
||||
|> Element.el
|
||||
[ Element.height <| Element.minimum 200 <| Element.fill
|
||||
, Element.width <| Element.minimum 400 <| Element.fill
|
||||
, Element.inFront <|
|
||||
(model
|
||||
|> Snackbar.view (Material.snackbar palette)
|
||||
(\( text, hasButton ) ->
|
||||
{ text = text
|
||||
, button =
|
||||
if hasButton then
|
||||
Just
|
||||
{ text = "Add"
|
||||
, onPress =
|
||||
Just <|
|
||||
AddSnackbar ( "This is another message", False )
|
||||
}
|
||||
|
||||
else
|
||||
Nothing
|
||||
}
|
||||
)
|
||||
|> Maybe.map
|
||||
(Element.el
|
||||
[ Element.padding 8
|
||||
, Element.alignBottom
|
||||
, Element.alignRight
|
||||
]
|
||||
)
|
||||
|> Maybe.withDefault Element.none
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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
|
||||
}
|
250
explorer/src/Page/SortTable.elm
Normal file
250
explorer/src/Page/SortTable.elm
Normal file
@ -0,0 +1,250 @@
|
||||
module Page.SortTable 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 (SortTableStyle)
|
||||
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 =
|
||||
"Sort Table"
|
||||
|
||||
|
||||
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||
-}
|
||||
description : String
|
||||
description =
|
||||
"A simple sort table."
|
||||
|
||||
|
||||
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||
-}
|
||||
viewFunctions =
|
||||
let
|
||||
viewTable style content columns asc sortBy { palette } () =
|
||||
Widget.sortTable (style palette)
|
||||
{ content = content
|
||||
, columns = columns
|
||||
, asc = asc
|
||||
, sortBy = sortBy
|
||||
, onChange = always ()
|
||||
}
|
||||
--Don't forget to change the title
|
||||
|> Page.viewTile "Widget.sortTable"
|
||||
in
|
||||
[ viewTable ]
|
||||
|> 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"
|
||||
( "SortTable", Material.sortTable )
|
||||
[]
|
||||
)
|
||||
|> Story.addStory
|
||||
(Story.optionListStory "Content"
|
||||
( "Data"
|
||||
, [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
, { id = 3, name = "Alfred", rating = 4.22, hash = Just "6fs1" }
|
||||
, { id = 4, name = "Thomas", rating = 3, hash = Just "k52f" }
|
||||
]
|
||||
)
|
||||
[ ( "None", [] )
|
||||
]
|
||||
)
|
||||
--Changing the text of the label
|
||||
|> Story.addStory
|
||||
(Story.optionListStory "Columns"
|
||||
( "4 Columns"
|
||||
, [ Widget.intColumn
|
||||
{ title = "Id"
|
||||
, value = .id
|
||||
, toString = \int -> "#" ++ String.fromInt int
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.stringColumn
|
||||
{ title = "Name"
|
||||
, value = .name
|
||||
, toString = identity
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.floatColumn
|
||||
{ title = "Rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.unsortableColumn
|
||||
{ title = "Hash"
|
||||
, toString = .hash >> Maybe.withDefault "None"
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
)
|
||||
[ ( "1 Column"
|
||||
, [ Widget.intColumn
|
||||
{ title = "Id"
|
||||
, value = .id
|
||||
, toString = \int -> "#" ++ String.fromInt int
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
)
|
||||
, ( "None", [] )
|
||||
]
|
||||
)
|
||||
--Change the Icon
|
||||
|> Story.addStory
|
||||
(Story.boolStory "Sort ascendingly"
|
||||
( True
|
||||
, False
|
||||
)
|
||||
True
|
||||
)
|
||||
|> Story.addStory
|
||||
(Story.optionListStory "Sort by"
|
||||
( "Id", "Id" )
|
||||
[ ( "Name", "Name" )
|
||||
, ( "Rating", "Rating" )
|
||||
, ( "Hash", "Hash" )
|
||||
, ( "None", "" )
|
||||
]
|
||||
)
|
||||
|> Story.build
|
||||
|
||||
|
||||
|
||||
{- This next section is essentially just a normal Elm program. -}
|
||||
--------------------------------------------------------------------------------
|
||||
-- Interactive Demonstration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ title : String
|
||||
, asc : Bool
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ChangedSorting String
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { title = "Name", asc = True }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
ChangedSorting string ->
|
||||
( { title = string
|
||||
, asc =
|
||||
if model.title == string then
|
||||
not model.asc
|
||||
|
||||
else
|
||||
True
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
||||
-}
|
||||
view : Context -> Model -> Element Msg
|
||||
view { palette } model =
|
||||
Widget.sortTable (Material.sortTable palette)
|
||||
{ content =
|
||||
[ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
|
||||
, { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
|
||||
, { id = 3, name = "Alfred", rating = 4.22, hash = Just "6fs1" }
|
||||
, { id = 4, name = "Thomas", rating = 3, hash = Just "k52f" }
|
||||
]
|
||||
, columns =
|
||||
[ Widget.intColumn
|
||||
{ title = "Id"
|
||||
, value = .id
|
||||
, toString = \int -> "#" ++ String.fromInt int
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.stringColumn
|
||||
{ title = "Name"
|
||||
, value = .name
|
||||
, toString = identity
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.floatColumn
|
||||
{ title = "Rating"
|
||||
, value = .rating
|
||||
, toString = String.fromFloat
|
||||
, width = Element.fill
|
||||
}
|
||||
, Widget.unsortableColumn
|
||||
{ title = "Hash"
|
||||
, toString = .hash >> Maybe.withDefault "None"
|
||||
, width = Element.fill
|
||||
}
|
||||
]
|
||||
, asc = model.asc
|
||||
, sortBy = model.title
|
||||
, onChange = ChangedSorting
|
||||
}
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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
|
||||
}
|
214
explorer/src/Page/TextInput.elm
Normal file
214
explorer/src/Page/TextInput.elm
Normal file
@ -0,0 +1,214 @@
|
||||
module Page.TextInput exposing (Model, Msg, init, page, subscriptions, update, view)
|
||||
|
||||
import Element exposing (Element)
|
||||
import Element.Input as Input
|
||||
import Material.Icons as MaterialIcons
|
||||
import Material.Icons.Types exposing (Coloring(..))
|
||||
import Page
|
||||
import Set exposing (Set)
|
||||
import UIExplorer.Story as Story
|
||||
import UIExplorer.Tile exposing (Context, Tile)
|
||||
import Widget
|
||||
import Widget.Icon as Icon exposing (Icon)
|
||||
import Widget.Material as Material
|
||||
exposing
|
||||
( darkPalette
|
||||
, defaultPalette
|
||||
)
|
||||
|
||||
|
||||
{-| The title of this page
|
||||
-}
|
||||
title : String
|
||||
title =
|
||||
"Text Input"
|
||||
|
||||
|
||||
{-| The description. I've taken this description directly from the [Material-UI-Specification](https://material.io/components/buttons)
|
||||
-}
|
||||
description : String
|
||||
description =
|
||||
"Text fields let users enter and edit text."
|
||||
|
||||
|
||||
{-| List of view functions. Essentially, anything that takes a Button as input.
|
||||
-}
|
||||
viewFunctions =
|
||||
let
|
||||
viewInput chips text placeholder label { palette } () =
|
||||
Widget.textInput (Material.textInput palette)
|
||||
{ chips = chips
|
||||
, text = text
|
||||
, placeholder = placeholder
|
||||
, label = label
|
||||
, onChange = always ()
|
||||
}
|
||||
--Don't forget to change the title
|
||||
|> Page.viewTile "Widget.currentPasswordInput"
|
||||
in
|
||||
[ viewInput ]
|
||||
|> List.foldl Story.addTile
|
||||
Story.initStaticTiles
|
||||
|
||||
|
||||
book =
|
||||
Story.book (Just "Options")
|
||||
viewFunctions
|
||||
|> Story.addStory
|
||||
(Story.optionListStory "Chips"
|
||||
( "3 Chips"
|
||||
, [ { icon = always Element.none, text = "Apples", onPress = Nothing }
|
||||
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "", onPress = Just () }
|
||||
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "Oranges", onPress = Just () }
|
||||
]
|
||||
)
|
||||
[ ( "2 Chips"
|
||||
, [ { icon = always Element.none, text = "Apples", onPress = Nothing }
|
||||
, { icon = MaterialIcons.done |> Icon.elmMaterialIcons Color, text = "", onPress = Just () }
|
||||
]
|
||||
)
|
||||
, ( "1 Chips"
|
||||
, [ { icon = always Element.none, text = "Apples", onPress = Nothing } ]
|
||||
)
|
||||
, ( "None", [] )
|
||||
]
|
||||
)
|
||||
|> Story.addStory
|
||||
(Story.textStory "Text"
|
||||
"123456789"
|
||||
)
|
||||
|> Story.addStory
|
||||
(Story.boolStory "Placeholder"
|
||||
( "password"
|
||||
|> Element.text
|
||||
|> Input.placeholder []
|
||||
|> Just
|
||||
, Nothing
|
||||
)
|
||||
True
|
||||
)
|
||||
|> Story.addStory
|
||||
(Story.textStory "Label"
|
||||
"Name"
|
||||
)
|
||||
|> Story.build
|
||||
|
||||
|
||||
|
||||
---{- This next section is essentially just a normal Elm program. -}
|
||||
-----------------------------------------------------------------------------
|
||||
-- Interactive Demonstration
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ chipTextInput : Set String
|
||||
, textInput : String
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= ToggleTextInputChip String
|
||||
| SetTextInput String
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { chipTextInput = Set.empty
|
||||
, textInput = ""
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg model =
|
||||
case msg of
|
||||
ToggleTextInputChip string ->
|
||||
( { model
|
||||
| chipTextInput =
|
||||
model.chipTextInput
|
||||
|> (if model.chipTextInput |> Set.member string then
|
||||
Set.remove string
|
||||
|
||||
else
|
||||
Set.insert string
|
||||
)
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SetTextInput string ->
|
||||
( { model | textInput = string }, Cmd.none )
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.none
|
||||
|
||||
|
||||
view : Context -> Model -> Element Msg
|
||||
view { palette } model =
|
||||
[ { chips =
|
||||
model.chipTextInput
|
||||
|> Set.toList
|
||||
|> List.map
|
||||
(\string ->
|
||||
{ icon = always Element.none
|
||||
, text = string
|
||||
, onPress =
|
||||
string
|
||||
|> ToggleTextInputChip
|
||||
|> Just
|
||||
}
|
||||
)
|
||||
, text = model.textInput
|
||||
, placeholder = Nothing
|
||||
, label = "Chips"
|
||||
, onChange = SetTextInput
|
||||
}
|
||||
|> Widget.textInput (Material.textInput palette)
|
||||
, model.chipTextInput
|
||||
|> Set.diff
|
||||
([ "A", "B", "C" ]
|
||||
|> Set.fromList
|
||||
)
|
||||
|> Set.toList
|
||||
|> List.map
|
||||
(\string ->
|
||||
Widget.button (Material.textInput palette).content.chips.content
|
||||
{ onPress =
|
||||
string
|
||||
|> ToggleTextInputChip
|
||||
|> Just
|
||||
, text = string
|
||||
, icon = always Element.none
|
||||
}
|
||||
)
|
||||
|> Element.wrappedRow [ Element.spacing 10 ]
|
||||
]
|
||||
|> Widget.column Material.column
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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
|
||||
}
|
@ -864,8 +864,6 @@ viewSidebar pages config model =
|
||||
|> Widget.itemList (Material.sideSheet palette)
|
||||
|
||||
|
||||
|
||||
|
||||
colorblindnessCss : Html msg
|
||||
colorblindnessCss =
|
||||
Html.node "style"
|
||||
@ -1118,8 +1116,6 @@ optionGroupView dark isExpanded selectedItem items itemToString onPress toggleEx
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
showSearchResults : String -> Bool
|
||||
showSearchResults searchText =
|
||||
String.length searchText > 1
|
||||
|
Loading…
Reference in New Issue
Block a user