Added Layout Example

This commit is contained in:
Lucas Payr 2021-02-04 21:48:25 +01:00
parent 7898a85bb2
commit 5e3847cdda
11 changed files with 753 additions and 62 deletions

View File

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

View File

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

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

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

View File

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

View File

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

View File

@ -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 =
[]

View File

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

View File

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

View File

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

View File

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