Added unstable homepage

This commit is contained in:
Lucas Payr 2020-04-22 13:14:55 +02:00
parent b73a19d3ce
commit 27dff31fb9
7 changed files with 18370 additions and 41 deletions

17994
docs/unstable/index.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@ import Browser
import Element exposing (Color, Element)
import Element.Background as Background
import Element.Input as Input
import Element.Border as Border
import Element.Font as Font
import Framework
import Framework.Button as Button
import Framework.Card as Card
@ -19,22 +21,32 @@ import Html.Attributes as Attributes
import Set exposing (Set)
import Time
import Widget
import Widget.Button as Button exposing (ButtonStyle)
import Widget.FilterSelect as FilterSelect
import Widget.FilterMultiSelect as FilterMultiSelect
import Widget.ScrollingNav as ScrollingNav
import Widget.Snackbar as Snackbar
import Widget.ValidatedInput as ValidatedInput
type alias Model =
{ filterSelect : FilterSelect.Model
, filterMultiSelect : FilterMultiSelect.Model
, validatedInput : ValidatedInput.Model () ( String, String )
}
type Msg
= FilterSelectSpecific FilterSelect.Msg
| FilterMultiSelectSpecific FilterMultiSelect.Msg
| ValidatedInputSpecific ValidatedInput.Msg
chipButton : ButtonStyle msg
chipButton =
{ container = Tag.simple
, disabled = []
, label = Grid.simple
, active = Color.primary
}
init : Model
init =
@ -56,6 +68,24 @@ init =
]
|> Set.fromList
|> FilterSelect.init
, filterMultiSelect =
[ "Apple"
, "Kiwi"
, "Strawberry"
, "Pineapple"
, "Mango"
, "Grapes"
, "Watermelon"
, "Orange"
, "Lemon"
, "Blueberry"
, "Grapefruit"
, "Coconut"
, "Cherry"
, "Banana"
]
|> Set.fromList
|> FilterMultiSelect.init
, validatedInput =
ValidatedInput.init
{ value = ( "John", "Doe" )
@ -83,6 +113,13 @@ update msg model =
, Cmd.none
)
FilterMultiSelectSpecific m ->
( { model
| filterMultiSelect = model.filterMultiSelect |> FilterMultiSelect.update m
}
, Cmd.none
)
ValidatedInputSpecific m ->
( { model
| validatedInput = model.validatedInput |> ValidatedInput.update m
@ -129,6 +166,55 @@ filterSelect model =
]
)
filterMultiSelect : FilterMultiSelect.Model -> (String,Element Msg)
filterMultiSelect model =
( "Filter Multi Select"
, [ FilterMultiSelect.viewInput model
{ msgMapper = FilterMultiSelectSpecific
, placeholder =
Just <|
Input.placeholder [] <|
Element.text <|
"Fruit"
, label = "Fruit"
, toChip = \string ->
{ text = string
, onPress = Just <| FilterMultiSelectSpecific <| FilterMultiSelect.ToggleSelected <| string
, icon = Element.none
}
}
|> Widget.textInput
{ chip = chipButton
, chipsRow =
[ Element.width <| Element.shrink
, Element.spacing <| 4 ]
, containerRow =
Button.simple
++ Color.light
++ [ Border.color <| Element.rgb255 186 189 182
, Font.alignLeft
, Element.padding 8
, Element.height <| Element.px <|42
]
++ Grid.simple
, input =
Color.light
++ [Element.padding 0]
}
, model
|> FilterMultiSelect.viewOptions
|> List.map
(\string ->
Input.button (Button.simple ++ Tag.simple)
{ onPress = Just <| FilterMultiSelectSpecific <| FilterMultiSelect.ToggleSelected <| string
, label = Element.text string
}
)
|> Element.wrappedRow [ Element.spacing 10 ]
]
|> Element.column Grid.simple
)
validatedInput : ValidatedInput.Model () ( String, String ) -> (String,Element Msg)
validatedInput model =
@ -162,6 +248,7 @@ view msgMapper model =
, description = "Components have a Model, an Update- and sometimes even a Subscription-function. It takes some time to set them up correctly."
, items =
[ filterSelect model.filterSelect
, filterMultiSelect model.filterMultiSelect
, validatedInput model.validatedInput
]
|> List.map (Tuple.mapSecond (Element.map msgMapper) )

View File

@ -127,7 +127,8 @@ style =
Card.simple
++ Color.dark
++ Grid.simple
++ [ Element.paddingXY 8 6]
++ [ Element.paddingXY 8 6
, Element.height <| Element.px <|54]
, button =
{ label = Grid.simple
, container = Button.simple ++ Color.dark
@ -137,6 +138,23 @@ style =
, text = [Element.paddingXY 8 0]
}
, layout = Framework.responsiveLayout
{--\a w ->
Html.div []
[ Html.node "meta"
[ Attributes.attribute "name" "viewport"
, Attributes.attribute "content" "width=device-width, initial-scale=1.0"
]
[]
, Element.layoutWith
{options = (Element.focusStyle
{ borderColor = Nothing
, backgroundColor = Nothing
, shadow = Nothing
}
|> List.singleton)
}
(Framework.layoutAttributes ++ a) <| w
]--}
, header =
Framework.container
++ Color.dark

View File

@ -21,6 +21,7 @@ import Widget.Button as Button exposing (ButtonStyle)
import Layout exposing (Part(..))
import Icons
import Widget
import Element.Font as Font
buttonStyle : ButtonStyle msg
buttonStyle =
@ -38,13 +39,23 @@ tabButtonStyle=
, active = Color.primary
}
chipButton : ButtonStyle msg
chipButton =
{ container = Tag.simple
, disabled = []
, label = Grid.simple
, active = Color.primary
}
type alias Model =
{ selected : Maybe Int
, multiSelected : Set Int
, chipTextInput : Set String
, isCollapsed : Bool
, carousel : Int
, tab : Maybe Int
, button : Bool
, textInput : String
}
@ -52,19 +63,24 @@ type Msg
= ChangedSelected Int
| ChangedMultiSelected Int
| ToggleCollapsable Bool
| ToggleTextInputChip String
| ChangedTab Int
| SetCarousel Int
| ToggleButton Bool
| SetTextInput String
| Idle
init : Model
init =
{ selected = Nothing
, multiSelected = Set.empty
, chipTextInput = Set.empty
, isCollapsed = False
, carousel = 0
, tab = Just 1
, button = True
, textInput = ""
}
@ -99,6 +115,18 @@ update msg model =
, Cmd.none
)
ToggleTextInputChip string ->
( { model
| chipTextInput =
model.chipTextInput |>
if model.chipTextInput |> Set.member string then
Set.remove string
else
Set.insert string
}
, Cmd.none
)
SetCarousel int ->
( if (int < 0) || (int > 3) then
model
@ -116,6 +144,12 @@ update msg model =
ToggleButton bool ->
( { model | button = bool }, Cmd.none )
SetTextInput string ->
( {model | textInput = string },Cmd.none)
Idle ->
( model, Cmd.none)
select : Model -> (String,Element Msg)
select model =
@ -187,29 +221,35 @@ multiSelect model =
collapsable : Model -> (String,Element Msg)
collapsable model =
( "Collapsable"
, Widget.collapsable
{ onToggle = ToggleCollapsable
, { onToggle = ToggleCollapsable
, isCollapsed = model.isCollapsed
, label =
Element.row Grid.compact
Element.row (Grid.simple ++ [Element.width<| Element.fill])
[ Element.html <|
if model.isCollapsed then
Heroicons.cheveronRight [ Attributes.width 20 ]
else
Heroicons.cheveronDown [ Attributes.width 20 ]
, Element.el Heading.h4 <| Element.text <| "Title"
, Element.text <| "Title"
]
, content = Element.text <| "Hello World"
}
|>Widget.collapsable
{ containerColumn = Card.simple ++ Grid.simple
++ [ Element.padding 8 ]
, button = []
}
)
tab : Model -> (String,Element Msg)
tab model =
( "Tab"
, Widget.tab
{ tabButton = tabButtonStyle
, tabRow = Grid.simple
{ button = tabButtonStyle
, optionRow = Grid.simple
, containerColumn = Grid.compact
}
{ selected = model.tab
, options = [ 1, 2, 3 ]
@ -315,6 +355,64 @@ iconButton model =
] |> Element.column Grid.simple
)
textInput : Model -> (String,Element Msg)
textInput model =
( "Chip Text Input"
, [ { chips =
model.chipTextInput
|> Set.toList
|> List.map (\string ->
{ icon = Element.none
, text = string
, onPress =
string
|> ToggleTextInputChip
|> Just
}
)
, text = model.textInput
, placeholder = Nothing
, label = "Chips"
, onChange = SetTextInput
}
|> Widget.textInput
{ chip = chipButton
, chipsRow =
[ Element.width <| Element.shrink
, Element.spacing <| 4 ]
, containerRow =
Button.simple
++ Color.light
++ [ Border.color <| Element.rgb255 186 189 182
, Font.alignLeft
, Element.padding 8
, Element.height <| Element.px <|42
]
++ Grid.simple
, input =
Color.light
++ [Element.padding 0]
}
, model.chipTextInput
|> Set.diff
(["A","B","C"]
|> Set.fromList
)
|> Set.toList
|> List.map
(\string ->
Input.button (Button.simple ++ Tag.simple)
{ onPress =
string
|> ToggleTextInputChip
|> Just
, label = Element.text string
}
)
|> Element.wrappedRow [ Element.spacing 10 ]
] |> Element.column Grid.simple
)
view :
{ msgMapper : Msg -> msg
, showDialog : msg
@ -336,5 +434,6 @@ view { msgMapper, showDialog, changedSheet } model =
, carousel model |> Tuple.mapSecond (Element.map msgMapper)
, tab model |> Tuple.mapSecond (Element.map msgMapper)
, dialog showDialog model
, textInput model |> Tuple.mapSecond (Element.map msgMapper)
]
}

View File

@ -1,24 +1,19 @@
module Widget exposing
( select, multiSelect, collapsable, carousel, modal, tab, dialog
, Dialog, MultiSelect, Select, selectButton
, Dialog, Select, selectButton, textInput
)
{-| This module contains functions for displaying data.
@docs select, multiSelect, collapsable, carousel, modal, tab, dialog
# DEPRECATED
@docs dialog
-}
import Array exposing (Array)
import Element exposing (Attribute, Element)
import Element.Background as Background
import Element.Events as Events
import Element.Input as Input
import Element.Input as Input exposing (Placeholder)
import Set exposing (Set)
import Widget.Button as Button exposing (Button, ButtonStyle, TextButton)
@ -34,17 +29,6 @@ type alias Select msg =
}
type alias MultiSelect msg =
{ selected : Set Int
, options :
List
{ text : String
, icon : Element Never
}
, onSelect : Int -> Maybe msg
}
type alias Dialog msg =
{ title : Maybe String
, body : Element msg
@ -95,7 +79,14 @@ select { selected, options, onSelect } =
{-| Selects multible options. This can be used for checkboxes.
-}
multiSelect :
MultiSelect msg
{ selected : Set Int
, options :
List
{ text : String
, icon : Element Never
}
, onSelect : Int -> Maybe msg
}
-> List ( Bool, Button msg )
multiSelect { selected, options, onSelect } =
options
@ -110,18 +101,51 @@ multiSelect { selected, options, onSelect } =
)
{-| -}
textInput :
{ chip : ButtonStyle msg
, containerRow : List (Attribute msg)
, chipsRow : List (Attribute msg)
, input : List (Attribute msg)
}
->
{ chips : List (Button msg)
, text : String
, placeholder : Maybe (Placeholder msg)
, label : String
, onChange : String -> msg
}
-> Element msg
textInput style { chips, placeholder, label, text, onChange } =
Element.row style.containerRow
[ chips
|> List.map (Button.view style.chip)
|> Element.row style.chipsRow
, Input.text style.input
{ onChange = onChange
, text = text
, placeholder = placeholder
, label = Input.labelHidden label
}
]
{-| Some collapsable content.
-}
collapsable :
{ containerColumn : List (Attribute msg)
, button : List (Attribute msg)
}
->
{ onToggle : Bool -> msg
, isCollapsed : Bool
, label : Element msg
, content : Element msg
}
-> Element msg
collapsable { onToggle, isCollapsed, label, content } =
Element.column [] <|
[ Input.button []
collapsable style { onToggle, isCollapsed, label, content } =
Element.column style.containerColumn <|
[ Input.button style.button
{ onPress = Just <| onToggle <| not isCollapsed
, label = label
}
@ -137,9 +161,9 @@ collapsable { onToggle, isCollapsed, label, content } =
{-| Displayes a list of contents in a tab
-}
tab :
{ style
| tabButton : ButtonStyle msg
, tabRow : List (Attribute msg)
{ button : ButtonStyle msg
, optionRow : List (Attribute msg)
, containerColumn : List (Attribute msg)
}
-> Select msg
-> (Maybe Int -> Element msg)
@ -147,12 +171,12 @@ tab :
tab style options content =
[ options
|> select
|> List.map (selectButton style.tabButton)
|> Element.row style.tabRow
|> List.map (selectButton style.button)
|> Element.row style.optionRow
, options.selected
|> content
]
|> Element.column []
|> Element.column style.containerColumn
dialog :

View File

@ -0,0 +1,108 @@
module Widget.FilterMultiSelect exposing (Model, Msg(..), init, update, viewInput, viewOptions)
{-|
@docs Model, Msg, init, update, viewInput, viewOptions
-}
import Element.Input exposing (Placeholder)
import Set exposing (Set)
import Widget.Button exposing (Button)
{-| The Model containing the raw value, the selected value and all the possible options.
-}
type alias Model =
{ raw : String
, selected : Set String
, options : Set String
}
{-| The Msg is exposed by design. You can unselect by sending `Selected Nothing`.
-}
type Msg
= ChangedRaw String
| ToggleSelected String
{-| The initial state contains the set of possible options.
-}
init : Set String -> Model
init options =
{ raw = ""
, selected = Set.empty
, options = options
}
{-| Updates the Model
-}
update : Msg -> Model -> Model
update msg model =
case msg of
ChangedRaw string ->
{ model
| raw = string
}
ToggleSelected string ->
if model.selected |> Set.member string then
{ model
| selected = model.selected |> Set.remove string
}
else
{ model
| selected = model.selected |> Set.insert string
, raw = ""
}
{-| A wrapper around Input.text.
-}
viewInput :
Model
->
{ msgMapper : Msg -> msg
, placeholder : Maybe (Placeholder msg)
, label : String
, toChip : String -> Button msg
}
->
{ chips : List (Button msg)
, text : String
, placeholder : Maybe (Placeholder msg)
, label : String
, onChange : String -> msg
}
viewInput model { msgMapper, placeholder, label, toChip } =
{ chips =
model.selected
|> Set.toList
|> List.map toChip
, text = model.raw
, placeholder = placeholder
, label = label
, onChange = ChangedRaw >> msgMapper
}
{-| Returns a List of all options that matches the filter.
-}
viewOptions : Model -> List String
viewOptions { raw, options, selected } =
if raw == "" then
[]
else
options
|> Set.filter (String.toUpper >> String.contains (raw |> String.toUpper))
|> Set.filter
(\string ->
selected
|> Set.member string
|> not
)
|> Set.toList

View File

@ -20,7 +20,6 @@ module Widget.Snackbar exposing
import Element exposing (Attribute, Element)
import Queue exposing (Queue)
import Widget
import Widget.Button as Button exposing (ButtonStyle, TextButton)