mirror of
https://github.com/Orasund/elm-ui-widgets.git
synced 2024-11-22 04:58:49 +03:00
Added Layout Example
This commit is contained in:
parent
7898a85bb2
commit
5e3847cdda
@ -15,9 +15,10 @@ import Example.Switch as Switch
|
||||
import Example.Tab as Tab
|
||||
import Example.TextInput as TextInput
|
||||
import Example.Sheet as Sheet
|
||||
import Example.AppBar as AppBar
|
||||
import Framework.Grid as Grid
|
||||
import View.States as States
|
||||
|
||||
import Example.Layout as Layout
|
||||
|
||||
type Example
|
||||
= ButtonExample
|
||||
@ -33,6 +34,8 @@ type Example
|
||||
| ProgressIndicatorExample
|
||||
| IconExample
|
||||
| SheetExample
|
||||
| AppBarExample
|
||||
| LayoutExample
|
||||
|
||||
|
||||
asList : List Example
|
||||
@ -50,6 +53,8 @@ asList =
|
||||
, ProgressIndicatorExample
|
||||
, IconExample
|
||||
, SheetExample
|
||||
, AppBarExample
|
||||
, LayoutExample
|
||||
]
|
||||
|> List.sortBy toString
|
||||
|
||||
@ -94,7 +99,10 @@ toString example =
|
||||
"Icon"
|
||||
SheetExample ->
|
||||
"Sheet"
|
||||
|
||||
AppBarExample ->
|
||||
"App Bar"
|
||||
LayoutExample ->
|
||||
"Layout"
|
||||
|
||||
fromString : String -> Maybe Example
|
||||
fromString string =
|
||||
@ -137,6 +145,11 @@ fromString string =
|
||||
|
||||
"Sheet" ->
|
||||
Just SheetExample
|
||||
"App Bar" ->
|
||||
Just AppBarExample
|
||||
|
||||
"Layout" ->
|
||||
Just LayoutExample
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
@ -183,6 +196,12 @@ get example =
|
||||
|
||||
SheetExample ->
|
||||
.sheet
|
||||
|
||||
AppBarExample ->
|
||||
.appBar
|
||||
|
||||
LayoutExample ->
|
||||
.layout
|
||||
|
||||
|
||||
toTests : Example -> msg -> Style msg -> List ( String, Element msg )
|
||||
@ -226,6 +245,12 @@ toTests example =
|
||||
|
||||
SheetExample ->
|
||||
States.sheet
|
||||
|
||||
AppBarExample ->
|
||||
States.appBar
|
||||
|
||||
LayoutExample ->
|
||||
States.layout
|
||||
|
||||
|
||||
type Msg
|
||||
@ -242,7 +267,8 @@ type Msg
|
||||
| ProgressIndicator ProgressIndicator.Msg
|
||||
| Icon Icon.Msg
|
||||
| Sheet Sheet.Msg
|
||||
|
||||
| AppBar AppBar.Msg
|
||||
| Layout Layout.Msg
|
||||
|
||||
type alias Model =
|
||||
{ button : Button.Model
|
||||
@ -258,6 +284,8 @@ type alias Model =
|
||||
, progressIndicator : ProgressIndicator.Model
|
||||
, icon : Icon.Model
|
||||
, sheet : Sheet.Model
|
||||
, appBar : AppBar.Model
|
||||
, layout : Layout.Model
|
||||
}
|
||||
|
||||
|
||||
@ -284,6 +312,8 @@ type alias UpgradeCollection =
|
||||
, progressIndicator : UpgradeRecord ProgressIndicator.Model ProgressIndicator.Msg
|
||||
, icon : UpgradeRecord Icon.Model Icon.Msg
|
||||
, sheet : UpgradeRecord Sheet.Model Sheet.Msg
|
||||
, appBar : UpgradeRecord AppBar.Model AppBar.Msg
|
||||
, layout : UpgradeRecord Layout.Model Layout.Msg
|
||||
}
|
||||
|
||||
|
||||
@ -301,6 +331,8 @@ type alias ExampleView msg =
|
||||
, progressIndicator : Element msg
|
||||
, icon : Element msg
|
||||
, sheet : Element msg
|
||||
, appBar : Element msg
|
||||
, layout : Element msg
|
||||
}
|
||||
|
||||
|
||||
@ -345,6 +377,12 @@ init =
|
||||
|
||||
( sheetModel, sheetMsg ) =
|
||||
Sheet.init
|
||||
|
||||
( appBarModel, appBarMsg ) =
|
||||
AppBar.init
|
||||
|
||||
( layoutModel, layoutMsg ) =
|
||||
Layout.init
|
||||
in
|
||||
( { button = buttonModel
|
||||
, switch = switchModel
|
||||
@ -359,6 +397,8 @@ init =
|
||||
, progressIndicator = progressIndicatorModel
|
||||
, icon = iconModel
|
||||
, sheet = sheetModel
|
||||
, appBar = appBarModel
|
||||
, layout = layoutModel
|
||||
}
|
||||
, [ Cmd.map Button buttonMsg
|
||||
, Cmd.map Switch switchMsg
|
||||
@ -373,6 +413,8 @@ init =
|
||||
, Cmd.map ProgressIndicator progressIndicatorMsg
|
||||
, Cmd.map Icon iconMsg
|
||||
, Cmd.map Sheet sheetMsg
|
||||
, Cmd.map AppBar appBarMsg
|
||||
, Cmd.map Layout layoutMsg
|
||||
]
|
||||
|> Cmd.batch
|
||||
)
|
||||
@ -471,6 +513,20 @@ upgradeRecord =
|
||||
, updateFun = Sheet.update
|
||||
, subscriptionsFun = Sheet.subscriptions
|
||||
}
|
||||
, appBar =
|
||||
{ from = .appBar
|
||||
, to = \model a -> { model | appBar = a }
|
||||
, msgMapper = AppBar
|
||||
, updateFun = AppBar.update
|
||||
, subscriptionsFun = AppBar.subscriptions
|
||||
}
|
||||
, layout =
|
||||
{ from = .layout
|
||||
, to = \model a -> { model | layout = a }
|
||||
, msgMapper = Layout
|
||||
, updateFun = Layout.update
|
||||
, subscriptionsFun = Layout.subscriptions
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -515,6 +571,10 @@ update msg model =
|
||||
|
||||
Sheet m ->
|
||||
updateField .sheet m
|
||||
AppBar m ->
|
||||
updateField .appBar m
|
||||
Layout m ->
|
||||
updateField .layout m
|
||||
)
|
||||
model
|
||||
|
||||
@ -538,6 +598,8 @@ subscriptions model =
|
||||
, upgradeRecord.progressIndicator |> subFun
|
||||
, upgradeRecord.icon |> subFun
|
||||
, upgradeRecord.sheet |> subFun
|
||||
, upgradeRecord.appBar |> subFun
|
||||
, upgradeRecord.layout |> subFun
|
||||
]
|
||||
|> Sub.batch
|
||||
|
||||
@ -574,6 +636,10 @@ view msgMapper style model =
|
||||
Icon.view (Icon >> msgMapper) style (.icon model)
|
||||
, sheet =
|
||||
Sheet.view (Sheet >> msgMapper) style (.sheet model)
|
||||
, appBar =
|
||||
AppBar.view (AppBar >> msgMapper) style (.appBar model)
|
||||
, layout =
|
||||
Layout.view (Layout >> msgMapper) style (.layout model)
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,16 +30,27 @@ import Widget
|
||||
, InsetItemStyle
|
||||
, SideSheetStyle
|
||||
, FullBleedItemStyle
|
||||
, AppBarStyle
|
||||
)
|
||||
import Widget.Icon as Icon
|
||||
import Widget.Icon as Icon exposing (Icon)
|
||||
import Widget.Layout exposing (LayoutStyle)
|
||||
import Widget.Snackbar exposing (SnackbarStyle)
|
||||
import Widget.Material as Material exposing (Palette)
|
||||
import Widget.Material.Color as MaterialColor
|
||||
|
||||
|
||||
style : Palette -> Style msg
|
||||
style palette =
|
||||
{ containedButton = Material.containedButton Material.defaultPalette
|
||||
{ container =
|
||||
(Material.defaultPalette.background |> MaterialColor.textAndBackground)
|
||||
++ [ Font.family
|
||||
[ Font.typeface "Roboto"
|
||||
, Font.sansSerif
|
||||
]
|
||||
, Font.size 16
|
||||
, Font.letterSpacing 0.5
|
||||
]
|
||||
, containedButton = Material.containedButton Material.defaultPalette
|
||||
, outlinedButton = Material.outlinedButton Material.defaultPalette
|
||||
, textButton = Material.textButton Material.defaultPalette
|
||||
, iconButton = Material.iconButton Material.defaultPalette
|
||||
@ -70,11 +81,38 @@ style palette =
|
||||
, sideSheet = Material.sideSheet palette
|
||||
, fullBleedItem = Material.fullBleedItem Material.defaultPalette
|
||||
, selectItem = Material.selectItem Material.defaultPalette
|
||||
, menuBar = Material.menuBar Material.defaultPalette
|
||||
, tabBar = Material.tabBar Material.defaultPalette
|
||||
, sheetButton = Material.selectItem Material.defaultPalette
|
||||
, searchFill =
|
||||
{ elementRow =
|
||||
(Material.defaultPalette.surface
|
||||
|> MaterialColor.textAndBackground) ++
|
||||
[ Element.height <| Element.px 56 ]
|
||||
, content =
|
||||
{ chips =
|
||||
{ elementRow = [ Element.spacing 8 ]
|
||||
, content = Material.chip Material.defaultPalette
|
||||
}
|
||||
, text =
|
||||
{ elementTextInput =
|
||||
(Material.defaultPalette.surface
|
||||
|> MaterialColor.textAndBackground
|
||||
)
|
||||
++ [ Border.width 0
|
||||
, Element.mouseOver []
|
||||
, Element.focused []
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
, snackbar = Material.snackbar Material.defaultPalette
|
||||
}
|
||||
|
||||
|
||||
type alias Style msg =
|
||||
{ containedButton : ButtonStyle msg
|
||||
{ container : List (Attribute msg)
|
||||
, containedButton : ButtonStyle msg
|
||||
, outlinedButton : ButtonStyle msg
|
||||
, textButton : ButtonStyle msg
|
||||
, iconButton : ButtonStyle msg
|
||||
@ -105,4 +143,19 @@ type alias Style msg =
|
||||
, sideSheet : SideSheetStyle msg
|
||||
, fullBleedItem : ItemStyle (FullBleedItemStyle msg) msg
|
||||
, selectItem : ItemStyle (ButtonStyle msg) msg
|
||||
, menuBar :
|
||||
AppBarStyle
|
||||
{ menuIcon : Icon msg
|
||||
, title : List (Attribute msg)
|
||||
}
|
||||
msg
|
||||
, tabBar :
|
||||
AppBarStyle
|
||||
{ menuTabButton : ButtonStyle msg
|
||||
, title : List (Attribute msg)
|
||||
}
|
||||
msg
|
||||
, sheetButton : ItemStyle (ButtonStyle msg) msg
|
||||
, searchFill : TextInputStyle msg
|
||||
, snackbar : SnackbarStyle msg
|
||||
}
|
||||
|
158
example/src/Example/AppBar.elm
Normal file
158
example/src/Example/AppBar.elm
Normal file
@ -0,0 +1,158 @@
|
||||
module Example.AppBar exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Browser
|
||||
import FeatherIcons
|
||||
import Widget exposing (Modal ,ItemStyle ,SideSheetStyle ,Button , TextInput ,TextInputStyle, AppBarStyle,ButtonStyle)
|
||||
import Widget.Icon as Icon exposing (Icon)
|
||||
import Widget.Material as Material
|
||||
import Element exposing (Attribute, DeviceClass(..), Element)
|
||||
import Widget.Material.Typography as Typography
|
||||
import Material.Icons.Types exposing (Coloring(..))
|
||||
import Material.Icons.Action
|
||||
import Material.Icons
|
||||
import Browser.Events as Events
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| menuBar :
|
||||
AppBarStyle
|
||||
{ menuIcon : Icon msg
|
||||
, title : List (Attribute msg)
|
||||
}
|
||||
msg
|
||||
, tabBar :
|
||||
AppBarStyle
|
||||
{ menuTabButton : ButtonStyle msg
|
||||
, title : List (Attribute msg)
|
||||
}
|
||||
msg
|
||||
}
|
||||
|
||||
|
||||
materialStyle : Style {} msg
|
||||
materialStyle =
|
||||
{ menuBar = Material.menuBar Material.defaultPalette
|
||||
, tabBar = Material.tabBar Material.defaultPalette
|
||||
}
|
||||
|
||||
|
||||
type alias Model
|
||||
= { isMenuBar : Bool
|
||||
, selected : Int
|
||||
, search : String
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= SetDesign Bool
|
||||
| SetSelected Int
|
||||
| SetSearch String
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
( { isMenuBar = True
|
||||
, selected = 0
|
||||
, search = ""
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update msg menu =
|
||||
case msg of
|
||||
SetDesign bool ->
|
||||
( { menu | isMenuBar = bool }
|
||||
, Cmd.none
|
||||
)
|
||||
SetSelected int ->
|
||||
( { menu | selected = int}
|
||||
, Cmd.none
|
||||
)
|
||||
SetSearch string ->
|
||||
( { menu | search = string}
|
||||
, 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 : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style model =
|
||||
let
|
||||
primaryActions =
|
||||
[ { icon =
|
||||
Material.Icons.change_history
|
||||
|> Icon.elmMaterialIcons Color
|
||||
, text = "Action"
|
||||
, onPress = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
||||
}
|
||||
]
|
||||
|
||||
search =
|
||||
{ chips = []
|
||||
, text = model.search
|
||||
, placeholder = Nothing
|
||||
, label = "Search"
|
||||
, onChange = SetSearch >> msgMapper
|
||||
}
|
||||
in
|
||||
( if model.isMenuBar then
|
||||
Widget.menuBar style.menuBar
|
||||
{ title =
|
||||
"Title"
|
||||
|> Element.text
|
||||
|> Element.el Typography.h6
|
||||
, deviceClass = Tablet
|
||||
, openLeftSheet = Just <|msgMapper <| SetDesign (not model.isMenuBar)
|
||||
, openRightSheet = Just <|msgMapper <| SetDesign (not model.isMenuBar)
|
||||
, openTopSheet = Just <|msgMapper <| SetDesign (not model.isMenuBar)
|
||||
, primaryActions = primaryActions
|
||||
, search = Just search
|
||||
}
|
||||
|
||||
else
|
||||
Widget.tabBar style.tabBar
|
||||
{ title =
|
||||
"Title"
|
||||
|> Element.text
|
||||
|> Element.el Typography.h6
|
||||
, menu =
|
||||
{ selected = Just model.selected
|
||||
, options =
|
||||
[ "Home", "About" ]
|
||||
|> List.map
|
||||
(\string ->
|
||||
{ text = string
|
||||
, icon = always Element.none
|
||||
}
|
||||
)
|
||||
, onSelect = SetSelected >> msgMapper >> Just
|
||||
}
|
||||
, deviceClass = Phone
|
||||
, openRightSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
||||
, openTopSheet = Just <| msgMapper <| SetDesign (not model.isMenuBar)
|
||||
, primaryActions = primaryActions
|
||||
, search = Just search
|
||||
}
|
||||
|
||||
|
||||
)
|
||||
|> Element.el [ Element.width <| Element.minimum 400 <| Element.fill]
|
||||
|
||||
|
||||
main : Program () Model Msg
|
||||
main =
|
||||
Browser.element
|
||||
{ init = always init
|
||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
}
|
365
example/src/Example/Layout.elm
Normal file
365
example/src/Example/Layout.elm
Normal file
@ -0,0 +1,365 @@
|
||||
module Example.Layout exposing (Model, Msg, init, subscriptions, update, view)
|
||||
|
||||
import Browser
|
||||
import Element exposing (Element,Attribute,DeviceClass(..))
|
||||
import FeatherIcons
|
||||
import Widget exposing (TextInputStyle ,TextInput
|
||||
,Dialog,DialogStyle,ColumnStyle
|
||||
,ButtonStyle,Modal,AppBarStyle, SideSheetStyle,ItemStyle,HeaderStyle,InsetItemStyle)
|
||||
import Widget.Icon as Icon exposing (Icon)
|
||||
import Widget.Material as Material
|
||||
import Widget.Material.Typography as Typography
|
||||
import Widget.Layout as Layout
|
||||
import Widget.Snackbar as Snackbar exposing (Snackbar,Message,SnackbarStyle)
|
||||
import Browser.Events as Events
|
||||
import Widget.Material.Color as MaterialColor
|
||||
import Element.Font as Font
|
||||
import Element.Border as Border
|
||||
import Material.Icons.Types exposing (Coloring(..))
|
||||
import Material.Icons
|
||||
import Widget.Customize as Customize
|
||||
|
||||
type Part
|
||||
= LeftSheet
|
||||
| RightSheet
|
||||
| Search
|
||||
|
||||
type alias Style style msg =
|
||||
{ style
|
||||
| container : List (Attribute msg)
|
||||
, snackbar : SnackbarStyle msg
|
||||
, sideSheet : SideSheetStyle msg
|
||||
, sheetButton : ItemStyle (ButtonStyle msg) msg
|
||||
, searchFill : TextInputStyle msg
|
||||
, insetItem : ItemStyle (InsetItemStyle msg) msg
|
||||
, menuBar :
|
||||
AppBarStyle
|
||||
{ menuIcon : Icon msg
|
||||
, title : List (Attribute msg)
|
||||
}
|
||||
msg
|
||||
, tabBar :
|
||||
AppBarStyle
|
||||
{ menuTabButton : ButtonStyle msg
|
||||
, title : List (Attribute msg)
|
||||
}
|
||||
msg
|
||||
, dialog : DialogStyle msg
|
||||
, containedButton : ButtonStyle msg
|
||||
, column : ColumnStyle msg
|
||||
}
|
||||
|
||||
materialStyle : Style {} msg
|
||||
materialStyle =
|
||||
{ container =
|
||||
(Material.defaultPalette.background |> MaterialColor.textAndBackground)
|
||||
++ [ Font.family
|
||||
[ Font.typeface "Roboto"
|
||||
, Font.sansSerif
|
||||
]
|
||||
, Font.size 16
|
||||
, Font.letterSpacing 0.5
|
||||
]
|
||||
, menuBar = Material.menuBar Material.defaultPalette
|
||||
, tabBar = Material.tabBar Material.defaultPalette
|
||||
, snackbar = Material.snackbar Material.defaultPalette
|
||||
, sheetButton = Material.selectItem Material.defaultPalette
|
||||
, sideSheet = Material.sideSheet Material.defaultPalette
|
||||
, searchFill =
|
||||
{ elementRow =
|
||||
(Material.defaultPalette.surface
|
||||
|> MaterialColor.textAndBackground) ++
|
||||
[ Element.height <| Element.px 56 ]
|
||||
, content =
|
||||
{ chips =
|
||||
{ elementRow = [ Element.spacing 8 ]
|
||||
, content = Material.chip Material.defaultPalette
|
||||
}
|
||||
, text =
|
||||
{ elementTextInput =
|
||||
(Material.defaultPalette.surface
|
||||
|> MaterialColor.textAndBackground
|
||||
)
|
||||
++ [ Border.width 0
|
||||
, Element.mouseOver []
|
||||
, Element.focused []
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
, insetItem = Material.insetItem Material.defaultPalette
|
||||
, dialog = Material.alertDialog Material.defaultPalette
|
||||
, containedButton = Material.containedButton Material.defaultPalette
|
||||
, column = Material.column
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Events.onResize (\h w -> Resized { height = h, width = w })
|
||||
|
||||
{-| You can remove the msgMapper. But by doing so, make sure to also change `msg` to `Msg` in the line below.
|
||||
-}
|
||||
view : (Msg -> msg) -> Style style msg -> Model -> Element msg
|
||||
view msgMapper style {snackbar,searchText,selected, window, 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 <|
|
||||
msgMapper <|
|
||||
ShowDialog False
|
||||
}
|
||||
}
|
||||
|> Widget.dialog style.dialog
|
||||
|> Just
|
||||
else
|
||||
Nothing
|
||||
|
||||
onChangedSidebar =
|
||||
ChangedSidebar
|
||||
|
||||
menu =
|
||||
{ selected = Just selected
|
||||
, options =
|
||||
[ "Home", "About" ]
|
||||
|> List.map
|
||||
(\string ->
|
||||
{ text = string
|
||||
, icon = always Element.none
|
||||
}
|
||||
)
|
||||
, onSelect = SetSelected >> msgMapper >> Just
|
||||
}
|
||||
|
||||
actions =
|
||||
{ icon =
|
||||
Material.Icons.change_history
|
||||
|> Icon.elmMaterialIcons Color
|
||||
, text = "Action"
|
||||
, onPress = Nothing
|
||||
}
|
||||
|> List.repeat 5
|
||||
|
||||
{ primaryActions, moreActions } =
|
||||
Layout.partitionActions actions
|
||||
|
||||
title =
|
||||
"Title"
|
||||
|> Element.text
|
||||
|> Element.el (Typography.h6 ++ [ Element.paddingXY 8 0 ])
|
||||
|
||||
search : TextInput msg
|
||||
search =
|
||||
{ chips = []
|
||||
, text = searchText
|
||||
, placeholder = Nothing
|
||||
, label = "Search"
|
||||
, onChange = SetSearchText >> msgMapper
|
||||
}
|
||||
|
||||
nav : Element msg
|
||||
nav =
|
||||
if
|
||||
(deviceClass == Phone)
|
||||
|| (deviceClass == Tablet)
|
||||
then
|
||||
Widget.menuBar style.menuBar
|
||||
{ title = title
|
||||
, deviceClass = deviceClass
|
||||
, openLeftSheet = Just <| msgMapper <| ChangedSidebar <| Just LeftSheet
|
||||
, openRightSheet = Just <| msgMapper <| ChangedSidebar <| Just RightSheet
|
||||
, openTopSheet = Just <| msgMapper <| ChangedSidebar <| Just Search
|
||||
, primaryActions = primaryActions
|
||||
, search = Just search
|
||||
}
|
||||
|
||||
else
|
||||
Widget.tabBar style.tabBar
|
||||
{ title = title
|
||||
, menu =
|
||||
{ selected = Just selected
|
||||
, options =
|
||||
[ "Home", "About" ]
|
||||
|> List.map
|
||||
(\string ->
|
||||
{ text = string
|
||||
, icon = always Element.none
|
||||
}
|
||||
)
|
||||
, onSelect = SetSelected >> msgMapper >> Just
|
||||
}
|
||||
, deviceClass = deviceClass
|
||||
, openRightSheet = Just <|msgMapper <| ChangedSidebar <| Just RightSheet
|
||||
, openTopSheet = Nothing
|
||||
, primaryActions = primaryActions
|
||||
, search = Just search
|
||||
}
|
||||
|
||||
snackbarElem : Element msg
|
||||
snackbarElem =
|
||||
snackbar
|
||||
|> Snackbar.view style.snackbar
|
||||
(\text ->
|
||||
{ text = text
|
||||
, button = Nothing
|
||||
}
|
||||
)
|
||||
|> Maybe.map
|
||||
(Element.el
|
||||
[ Element.padding 8
|
||||
, Element.alignBottom
|
||||
, Element.alignRight
|
||||
]
|
||||
)
|
||||
|> Maybe.withDefault Element.none
|
||||
|
||||
onDismiss =
|
||||
Nothing
|
||||
|> ChangedSidebar
|
||||
|> msgMapper
|
||||
|
||||
modals =
|
||||
Layout.orderModals
|
||||
{ dialog = dialog
|
||||
, leftSheet =
|
||||
if active == Just LeftSheet then
|
||||
Layout.leftSheet
|
||||
{ button = style.sheetButton
|
||||
, sheet = style.sideSheet
|
||||
}
|
||||
{ title = title
|
||||
, menu = menu
|
||||
, onDismiss = onDismiss
|
||||
}
|
||||
|> Just
|
||||
|
||||
else
|
||||
Nothing
|
||||
, rightSheet =
|
||||
if active == Just RightSheet then
|
||||
Layout.rightSheet
|
||||
{ sheet = style.sideSheet
|
||||
, insetItem = style.insetItem
|
||||
}
|
||||
{ onDismiss = onDismiss
|
||||
, moreActions =moreActions
|
||||
}
|
||||
|> Just
|
||||
|
||||
else
|
||||
Nothing
|
||||
, topSheet =
|
||||
if active == Just Search then
|
||||
Layout.searchSheet style.searchFill
|
||||
{ search = search
|
||||
, onDismiss = onDismiss
|
||||
}
|
||||
|> Just
|
||||
|
||||
else
|
||||
Nothing
|
||||
, bottomSheet = Nothing
|
||||
}
|
||||
in
|
||||
[ nav
|
||||
, Widget.button style.containedButton
|
||||
{ onPress =
|
||||
Just <|
|
||||
msgMapper <|
|
||||
AddSnackbar
|
||||
, text = "Add Notification"
|
||||
, icon = always Element.none
|
||||
}
|
||||
]
|
||||
|> Element.column [Element.width <| Element.fill, Element.spacing 8]
|
||||
|> Element.el
|
||||
(List.concat
|
||||
[ style.container
|
||||
, [ Element.inFront snackbarElem ]
|
||||
, modals
|
||||
|> Widget.singleModal
|
||||
, [ Element.height <| Element.minimum 200 <| Element.fill
|
||||
, Element.width <| Element.minimum 400 <| Element.fill
|
||||
]
|
||||
]
|
||||
)
|
||||
|
||||
main : Program () Model Msg
|
||||
main =
|
||||
Browser.element
|
||||
{ init = always init
|
||||
, view = \model -> model |> view identity materialStyle |> Element.layout []
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
}
|
@ -267,11 +267,20 @@ update msg model =
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions _ =
|
||||
Sub.batch
|
||||
subscriptions model =
|
||||
(
|
||||
[ Time.every 50 (always (TimePassed 50))
|
||||
, Events.onResize (\h w -> Resized { height = h, width = w })
|
||||
]
|
||||
] ++
|
||||
( case model of
|
||||
Loading ->
|
||||
[]
|
||||
Loaded {stateless} ->
|
||||
Stateless.subscriptions stateless
|
||||
|> Sub.map StatelessSpecific
|
||||
|> List.singleton
|
||||
))
|
||||
|> Sub.batch
|
||||
|> Sub.map LoadedSpecific
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Stateless exposing (Model, Msg, init, update, view)
|
||||
module Stateless exposing (Model, Msg, init, update,subscriptions, view)
|
||||
|
||||
import Data.Example as Example
|
||||
import Data.Theme as Theme exposing (Theme)
|
||||
@ -45,6 +45,9 @@ update msg model =
|
||||
Idle ->
|
||||
( model, Cmd.none )
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
Example.subscriptions model.example |> Sub.map ExampleSpecific
|
||||
|
||||
view :
|
||||
{ theme : Theme
|
||||
|
@ -1,4 +1,4 @@
|
||||
module View.States exposing (button, sheet,dialog, icon, list, modal, multiSelect, progressIndicator, select, sortTable, switch, tab, textInput)
|
||||
module View.States exposing (button, sheet,dialog,layout, icon, list, modal,appBar, multiSelect, progressIndicator, select, sortTable, switch, tab, textInput)
|
||||
|
||||
import Data.Style exposing (Style)
|
||||
import Element exposing (Element)
|
||||
@ -550,4 +550,12 @@ icon _ style =
|
||||
|
||||
sheet : msg -> Style msg -> List ( String, Element msg )
|
||||
sheet _ style =
|
||||
[]
|
||||
|
||||
appBar : msg -> Style msg -> List ( String, Element msg )
|
||||
appBar _ style =
|
||||
[]
|
||||
|
||||
layout : msg -> Style msg -> List ( String, Element msg )
|
||||
layout _ style =
|
||||
[]
|
@ -45,18 +45,17 @@ menuBar :
|
||||
->
|
||||
{ title : Element msg
|
||||
, deviceClass : DeviceClass
|
||||
, openLeftSheet : msg
|
||||
, openRightSheet : msg
|
||||
, openTopSheet : msg
|
||||
, openLeftSheet : Maybe msg
|
||||
, openRightSheet : Maybe msg
|
||||
, openTopSheet : Maybe msg
|
||||
, primaryActions : List (Button msg)
|
||||
, moreActions : List (Button msg)
|
||||
, search : Maybe (TextInput msg)
|
||||
}
|
||||
-> Element msg
|
||||
menuBar style m =
|
||||
internalNav
|
||||
[ Button.iconButton style.content.actions.content.button
|
||||
{ onPress = Just <| m.openLeftSheet
|
||||
{ onPress = m.openLeftSheet
|
||||
, icon = style.content.menu.content.menuIcon
|
||||
, text = "Menu"
|
||||
}
|
||||
@ -86,10 +85,9 @@ tabBar :
|
||||
{ title : Element msg
|
||||
, menu : Select msg
|
||||
, deviceClass : DeviceClass
|
||||
, openRightSheet : msg
|
||||
, openTopSheet : msg
|
||||
, openRightSheet : Maybe msg
|
||||
, openTopSheet : Maybe msg
|
||||
, primaryActions : List (Button msg)
|
||||
, moreActions : List (Button msg)
|
||||
, search : Maybe (TextInput msg)
|
||||
}
|
||||
-> Element msg
|
||||
@ -138,14 +136,13 @@ internalNav :
|
||||
->
|
||||
{ model
|
||||
| deviceClass : DeviceClass
|
||||
, openRightSheet : msg
|
||||
, openTopSheet : msg
|
||||
, openRightSheet : Maybe msg
|
||||
, openTopSheet : Maybe msg
|
||||
, primaryActions : List (Button msg)
|
||||
, moreActions : List (Button msg)
|
||||
, search : Maybe (TextInput msg)
|
||||
}
|
||||
-> Element msg
|
||||
internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, primaryActions, moreActions, search } =
|
||||
internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, primaryActions, search } =
|
||||
[ menuElements
|
||||
|> Element.row style.content.menu.elementRow
|
||||
, if deviceClass == Phone || deviceClass == Tablet then
|
||||
@ -171,8 +168,12 @@ internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, prim
|
||||
|> Maybe.map
|
||||
(\{ label } ->
|
||||
if deviceClass == Tablet then
|
||||
[ Button.button style.content.actions.content.button
|
||||
{ onPress = Just <| openTopSheet
|
||||
[ Button.button
|
||||
( style.content.actions.content.button
|
||||
--FIX FOR ISSUE #30
|
||||
|> Customize.elementButton [ Element.width Element.shrink ]
|
||||
)
|
||||
{ onPress = openTopSheet
|
||||
, icon = style.content.actions.content.searchIcon
|
||||
, text = label
|
||||
}
|
||||
@ -180,7 +181,7 @@ internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, prim
|
||||
|
||||
else if deviceClass == Phone then
|
||||
[ Button.iconButton style.content.actions.content.button
|
||||
{ onPress = Just <| openTopSheet
|
||||
{ onPress = openTopSheet
|
||||
, icon = style.content.actions.content.searchIcon
|
||||
, text = label
|
||||
}
|
||||
@ -202,16 +203,16 @@ internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, prim
|
||||
|> Customize.elementButton [ Element.width Element.shrink ]
|
||||
)
|
||||
)
|
||||
, if moreActions |> List.isEmpty then
|
||||
[]
|
||||
|
||||
else
|
||||
[ Button.iconButton style.content.actions.content.button
|
||||
{ onPress = Just <| openRightSheet
|
||||
, icon = style.content.actions.content.moreVerticalIcon
|
||||
, text = "More"
|
||||
}
|
||||
]
|
||||
, case openRightSheet of
|
||||
Nothing ->
|
||||
[]
|
||||
Just _ ->
|
||||
[ Button.iconButton style.content.actions.content.button
|
||||
{ onPress = openRightSheet
|
||||
, icon = style.content.actions.content.moreVerticalIcon
|
||||
, text = "More"
|
||||
}
|
||||
]
|
||||
]
|
||||
|> List.concat
|
||||
|> Element.row style.content.actions.elementRow
|
||||
|
@ -17,7 +17,6 @@ import Svg
|
||||
import Svg.Attributes
|
||||
import Widget.Customize as Customize
|
||||
import Widget.Icon as Icon exposing (Icon)
|
||||
import Widget.Layout exposing (LayoutStyle)
|
||||
import Widget.Material.Color as MaterialColor
|
||||
import Widget.Material.Typography as Typography
|
||||
|
||||
|
@ -21,7 +21,7 @@ module Widget exposing
|
||||
, TextInputStyle, TextInput, textInput
|
||||
, TabStyle, Tab, tab
|
||||
, ProgressIndicatorStyle, ProgressIndicator, circularProgressIndicator
|
||||
, FullBleedItemStyle, InsetItem, InsetItemStyle, fullBleedItem, insetItem
|
||||
, FullBleedItemStyle, InsetItem, InsetItemStyle, fullBleedItem, insetItem,AppBarStyle
|
||||
)
|
||||
|
||||
{-| This module contains different stateless view functions. No wiring required.
|
||||
@ -124,7 +124,7 @@ You can create you own widgets by sticking widgets types together.
|
||||
|
||||
# App Bar
|
||||
|
||||
@docs menuBar, tabBar
|
||||
@docs AppBarStyle, menuBar, tabBar
|
||||
|
||||
|
||||
# Sheet
|
||||
@ -172,7 +172,7 @@ You can create you own widgets by sticking widgets types together.
|
||||
import Color exposing (Color)
|
||||
import Element exposing (Attribute, DeviceClass, Element, Length)
|
||||
import Element.Input exposing (Placeholder)
|
||||
import Internal.AppBar as AppBar exposing (AppBarStyle)
|
||||
import Internal.AppBar as AppBar
|
||||
import Internal.Button as Button
|
||||
import Internal.Dialog as Dialog
|
||||
import Internal.Item as Item
|
||||
@ -1417,7 +1417,31 @@ buttonColumn =
|
||||
-- APP BAR
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
{-|-}
|
||||
type alias AppBarStyle content msg =
|
||||
{ elementRow : List (Attribute msg)
|
||||
, content :
|
||||
{ menu :
|
||||
{ elementRow : List (Attribute msg)
|
||||
, content : content
|
||||
}
|
||||
, search : TextInputStyle msg
|
||||
, actions :
|
||||
{ elementRow : List (Attribute msg)
|
||||
, content :
|
||||
{ button : ButtonStyle msg
|
||||
, searchIcon : Icon msg
|
||||
, moreVerticalIcon : Icon msg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{-| A app bar with a menu button on the left side.
|
||||
|
||||
This should be the default way to display the app bar. Specially for Phone users.
|
||||
|
||||
-}
|
||||
menuBar :
|
||||
AppBarStyle
|
||||
{ menuIcon : Icon msg
|
||||
@ -1427,18 +1451,23 @@ menuBar :
|
||||
->
|
||||
{ title : Element msg
|
||||
, deviceClass : DeviceClass
|
||||
, openLeftSheet : msg
|
||||
, openRightSheet : msg
|
||||
, openTopSheet : msg
|
||||
, openLeftSheet : Maybe msg
|
||||
, openRightSheet : Maybe msg
|
||||
, openTopSheet : Maybe msg
|
||||
, primaryActions : List (Button msg)
|
||||
, moreActions : List (Button msg)
|
||||
, search : Maybe (TextInput msg)
|
||||
}
|
||||
-> Element msg
|
||||
menuBar =
|
||||
AppBar.menuBar
|
||||
|
||||
{-| A app bar with tabs instead of a menu.
|
||||
|
||||
This is should be used for big screens.
|
||||
|
||||
It should be avoided for smaller screens or if you have more then 4 tabs
|
||||
|
||||
-}
|
||||
tabBar :
|
||||
AppBarStyle
|
||||
{ menuTabButton : ButtonStyle msg
|
||||
@ -1449,10 +1478,9 @@ tabBar :
|
||||
{ title : Element msg
|
||||
, menu : Select msg
|
||||
, deviceClass : DeviceClass
|
||||
, openRightSheet : msg
|
||||
, openTopSheet : msg
|
||||
, openRightSheet : Maybe msg
|
||||
, openTopSheet : Maybe msg
|
||||
, primaryActions : List (Button msg)
|
||||
, moreActions : List (Button msg)
|
||||
, search : Maybe (TextInput msg)
|
||||
}
|
||||
-> Element msg
|
||||
|
@ -1,5 +1,5 @@
|
||||
module Widget.Layout exposing
|
||||
( LayoutStyle, Layout, Part(..), init, timePassed
|
||||
( LayoutStyle, Layout, Part, init, timePassed
|
||||
, activate, queueMessage
|
||||
, leftSheet, rightSheet, searchSheet
|
||||
, getDeviceClass, partitionActions, orderModals
|
||||
@ -29,9 +29,6 @@ It is responsive and changes view to apply to the [material design guidelines](h
|
||||
|
||||
# Views
|
||||
|
||||
@docs menuBar, tabBar
|
||||
|
||||
|
||||
## Sheets
|
||||
|
||||
@docs leftSheet, rightSheet, searchSheet
|
||||
@ -205,8 +202,7 @@ leftSheet :
|
||||
, sheet : SideSheetStyle msg
|
||||
}
|
||||
->
|
||||
{ window : { height : Int, width : Int }
|
||||
, title : Element msg
|
||||
{ title : Element msg
|
||||
, menu : Select msg
|
||||
, onDismiss : msg
|
||||
}
|
||||
@ -347,11 +343,14 @@ view style { search, title, onChangedSidebar, menu, actions, window, dialog, lay
|
||||
AppBar.menuBar style.menuBar
|
||||
{ title = title
|
||||
, deviceClass = deviceClass
|
||||
, openLeftSheet = onChangedSidebar <| Just LeftSheet
|
||||
, openRightSheet = onChangedSidebar <| Just RightSheet
|
||||
, openTopSheet = onChangedSidebar <| Just Search
|
||||
, openLeftSheet = Just <|onChangedSidebar <| Just LeftSheet
|
||||
, openRightSheet =
|
||||
if moreActions |> List.isEmpty then
|
||||
Nothing
|
||||
else
|
||||
Just <| onChangedSidebar <| Just RightSheet
|
||||
, openTopSheet = Just <|onChangedSidebar <| Just Search
|
||||
, primaryActions = primaryActions
|
||||
, moreActions = moreActions
|
||||
, search = search
|
||||
}
|
||||
|
||||
@ -360,10 +359,13 @@ view style { search, title, onChangedSidebar, menu, actions, window, dialog, lay
|
||||
{ title = title
|
||||
, menu = menu
|
||||
, deviceClass = deviceClass
|
||||
, openRightSheet = onChangedSidebar <| Just RightSheet
|
||||
, openTopSheet = onChangedSidebar <| Just Search
|
||||
, openRightSheet =
|
||||
if moreActions |> List.isEmpty then
|
||||
Nothing
|
||||
else
|
||||
Just <| onChangedSidebar <| Just RightSheet
|
||||
, openTopSheet = Just <| onChangedSidebar <| Just Search
|
||||
, primaryActions = primaryActions
|
||||
, moreActions = moreActions
|
||||
, search = search
|
||||
}
|
||||
|
||||
@ -393,8 +395,7 @@ view style { search, title, onChangedSidebar, menu, actions, window, dialog, lay
|
||||
{ button = style.sheetButton
|
||||
, sheet = style.sheet
|
||||
}
|
||||
{ window = window
|
||||
, title = title
|
||||
{ title = title
|
||||
, menu = menu
|
||||
, onDismiss = onDismiss
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user