Add AppBar Widget

This commit is contained in:
Lucas Payr 2021-02-03 19:44:23 +01:00
parent e5f120a18a
commit 7898a85bb2
7 changed files with 587 additions and 363 deletions

224
src/Internal/AppBar.elm Normal file
View File

@ -0,0 +1,224 @@
module Internal.AppBar exposing (AppBarStyle, menuBar, tabBar)
import Array
import Element exposing (Attribute, DeviceClass(..), Element)
import Element.Input as Input
import Html exposing (Html)
import Internal.Button as Button exposing (Button, ButtonStyle)
import Internal.Dialog as Dialog
import Internal.Item as Item exposing (InsetItemStyle, ItemStyle)
import Internal.Modal as Modal exposing (Modal)
import Internal.Select as Select exposing (Select)
import Internal.Sheet as Sheet exposing (SideSheetStyle)
import Internal.TextInput as TextInput exposing (TextInput, TextInputStyle)
import Widget.Customize as Customize
import Widget.Icon exposing (Icon)
import Widget.Snackbar as Snackbar exposing (Message, SnackbarStyle)
type alias AppBarStyle content msg =
{ elementRow : List (Attribute msg) --header
, content :
{ menu :
{ elementRow : List (Attribute msg)
, content : content
}
, search : TextInputStyle msg --search
, actions :
{ elementRow : List (Attribute msg)
, content :
{ button : ButtonStyle msg --menuButton
, searchIcon : Icon msg
, moreVerticalIcon : Icon msg
}
}
}
}
menuBar :
AppBarStyle
{ menuIcon : Icon msg
, title : List (Attribute msg)
}
msg
->
{ title : Element msg
, deviceClass : DeviceClass
, openLeftSheet : msg
, openRightSheet : msg
, openTopSheet : 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
, icon = style.content.menu.content.menuIcon
, text = "Menu"
}
, m.title |> Element.el style.content.menu.content.title
]
{ elementRow = style.elementRow
, content =
{ menu =
{ elementRow = style.content.menu.elementRow
}
, search = style.content.search
, actions = style.content.actions
}
}
m
{-| A top bar that displays the menu as tabs
-}
tabBar :
AppBarStyle
{ menuTabButton : ButtonStyle msg
, title : List (Attribute msg)
}
msg
->
{ title : Element msg
, menu : Select msg
, deviceClass : DeviceClass
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
tabBar style m =
internalNav
[ m.title |> Element.el style.content.menu.content.title
, m.menu
|> Select.select
|> List.map (Select.selectButton style.content.menu.content.menuTabButton)
|> Element.row
[ Element.width <| Element.shrink
]
]
{ elementRow = style.elementRow
, content =
{ menu =
{ elementRow = style.content.menu.elementRow
}
, search = style.content.search
, actions = style.content.actions
}
}
m
{-| -}
internalNav :
List (Element msg)
->
{ elementRow : List (Attribute msg) --header
, content :
{ menu :
{ elementRow : List (Attribute msg)
}
, search : TextInputStyle msg --search
, actions :
{ elementRow : List (Attribute msg)
, content :
{ button : ButtonStyle msg --menuButton
, searchIcon : Icon msg
, moreVerticalIcon : Icon msg
}
}
}
}
->
{ model
| deviceClass : DeviceClass
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, primaryActions, moreActions, search } =
[ menuElements
|> Element.row style.content.menu.elementRow
, if deviceClass == Phone || deviceClass == Tablet then
Element.none
else
search
|> Maybe.map
(\{ onChange, text, label } ->
TextInput.textInput style.content.search
{ chips = []
, onChange = onChange
, text = text
, placeholder =
Just <|
Input.placeholder [] <|
Element.text label
, label = label
}
)
|> Maybe.withDefault Element.none
, [ search
|> Maybe.map
(\{ label } ->
if deviceClass == Tablet then
[ Button.button style.content.actions.content.button
{ onPress = Just <| openTopSheet
, icon = style.content.actions.content.searchIcon
, text = label
}
]
else if deviceClass == Phone then
[ Button.iconButton style.content.actions.content.button
{ onPress = Just <| openTopSheet
, icon = style.content.actions.content.searchIcon
, text = label
}
]
else
[]
)
|> Maybe.withDefault []
, primaryActions
|> List.map
(if deviceClass == Phone then
Button.iconButton style.content.actions.content.button
else
Button.button
(style.content.actions.content.button
--FIX FOR ISSUE #30
|> 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"
}
]
]
|> List.concat
|> Element.row style.content.actions.elementRow
]
|> Element.row
(style.elementRow
++ [ Element.alignTop
, Element.width <| Element.fill
]
)

View File

@ -0,0 +1,192 @@
module Internal.Material.AppBar exposing (menuBar, tabBar)
import Element exposing (Attribute)
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Internal.AppBar exposing (AppBarStyle)
import Internal.Button exposing (ButtonStyle)
import Internal.Material.Button as Button
import Internal.Material.Icon as Icon
import Internal.Material.Item as Item
import Internal.Material.Palette exposing (Palette)
import Internal.Material.Sheet as Sheet
import Internal.Material.Snackbar as Snackbar
import Internal.Material.TextInput as TextInput
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
menuTabButton : Palette -> ButtonStyle msg
menuTabButton palette =
{ elementButton =
Typography.button
++ [ Element.height <| Element.px 56
, Element.fill
|> Element.maximum 360
|> Element.minimum 90
|> Element.width
, Element.paddingXY 12 16
, palette.primary
|> MaterialColor.accessibleTextColor
|> MaterialColor.fromColor
|> Font.color
, Element.alignBottom
, Element.mouseDown
[ palette.primary
|> MaterialColor.scaleOpacity MaterialColor.buttonPressedOpacity
|> MaterialColor.fromColor
|> Background.color
]
, Element.focused
[ palette.primary
|> MaterialColor.scaleOpacity MaterialColor.buttonFocusOpacity
|> MaterialColor.fromColor
|> Background.color
]
, Element.mouseOver
[ palette.primary
|> MaterialColor.scaleOpacity MaterialColor.buttonHoverOpacity
|> MaterialColor.fromColor
|> Background.color
]
]
, ifDisabled =
(Button.baseButton palette |> .ifDisabled)
++ [ MaterialColor.gray
|> MaterialColor.fromColor
|> Font.color
, Element.mouseDown []
, Element.mouseOver []
, Element.focused []
]
, ifActive =
[ Border.widthEach
{ bottom = 2
, left = 0
, right = 0
, top = 0
}
]
, otherwise =
[]
, content =
{ elementRow =
[ Element.spacing <| 8
, Element.centerY
, Element.centerX
]
, content =
{ text = { contentText = [] }
, icon =
{ ifActive =
{ size = 18
, color = palette.primary |> MaterialColor.accessibleTextColor
}
, ifDisabled =
{ size = 18
, color = MaterialColor.gray
}
, otherwise =
{ size = 18
, color = palette.primary |> MaterialColor.accessibleTextColor
}
}
}
}
}
menuBar :
Palette
->
AppBarStyle
{ menuIcon : Icon msg
, title : List (Attribute msg)
}
msg
menuBar =
internalBar
{ menuIcon = Icon.menu
, title = Typography.h6 ++ [ Element.paddingXY 8 0 ]
}
tabBar :
Palette
->
AppBarStyle
{ menuTabButton : ButtonStyle msg
, title : List (Attribute msg)
}
msg
tabBar palette =
internalBar
{ menuTabButton = menuTabButton palette
, title = Typography.h6 ++ [ Element.paddingXY 8 0 ]
}
palette
internalBar : content -> Palette -> AppBarStyle content msg
internalBar content palette =
{ elementRow =
(palette.primary
|> MaterialColor.textAndBackground
)
++ [ Element.padding 0
, Element.spacing 8
, Element.height <| Element.px 56
, Element.width <| Element.minimum 360 <| Element.fill
]
, content =
{ menu =
{ elementRow =
[ Element.width <| Element.shrink
, Element.spacing 8
]
, content = content
}
, search = TextInput.searchInput palette
, actions =
{ elementRow =
[ Element.alignRight
, Element.width Element.shrink
]
, content =
{ button =
Button.iconButton palette
|> Customize.mapContent
(Customize.mapContent
(\record ->
{ record
| icon =
{ ifActive =
{ size = record.icon.ifActive.size
, color =
palette.primary
|> MaterialColor.accessibleTextColor
}
, ifDisabled =
record.icon.ifDisabled
, otherwise =
{ size = record.icon.otherwise.size
, color =
palette.primary
|> MaterialColor.accessibleTextColor
}
}
}
)
)
, searchIcon = Icon.search
, moreVerticalIcon = Icon.more_vert
}
}
}
}

View File

@ -1,4 +1,4 @@
module Internal.Material.Icon exposing (expand_less, expand_more, icon)
module Internal.Material.Icon exposing (expand_less, expand_more, icon, menu, more_vert, search)
import Color exposing (Color)
import Element exposing (Element)
@ -24,6 +24,48 @@ icon { viewBox, size, color } =
>> Element.el []
menu : Icon msg
menu { size, color } =
icon
{ viewBox = "0 0 48 48"
, size = size
, color = color
}
[ Svg.path
[ Svg.Attributes.d "M6 36h36v-4H6v4zm0-10h36v-4H6v4zm0-14v4h36v-4H6z"
]
[]
]
more_vert : Icon msg
more_vert { size, color } =
icon
{ viewBox = "0 0 48 48"
, size = size
, color = color
}
[ Svg.path
[ Svg.Attributes.d "M24 16c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 4c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 12c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"
]
[]
]
search : Icon msg
search { size, color } =
icon
{ viewBox = "0 0 48 48"
, size = size
, color = color
}
[ Svg.path
[ Svg.Attributes.d "M31 28h-1.59l-.55-.55C30.82 25.18 32 22.23 32 19c0-7.18-5.82-13-13-13S6 11.82 6 19s5.82 13 13 13c3.23 0 6.18-1.18 8.45-3.13l.55.55V31l10 9.98L40.98 38 31 28zm-12 0c-4.97 0-9-4.03-9-9s4.03-9 9-9 9 4.03 9 9-4.03 9-9 9z"
]
[]
]
expand_less : Icon msg
expand_less { size, color } =
icon

View File

@ -1,10 +1,11 @@
module Internal.Material.Layout exposing (layout, menu, menuTabButton, more_vert, search)
module Internal.Material.Layout exposing (layout)
import Element
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Internal.Button exposing (ButtonStyle)
import Internal.Material.AppBar as AppBar
import Internal.Material.Button as Button
import Internal.Material.Icon as Icon
import Internal.Material.Item as Item
@ -21,128 +22,6 @@ import Widget.Material.Color as MaterialColor
import Widget.Material.Typography as Typography
more_vert : Icon msg
more_vert { size, color } =
Icon.icon
{ viewBox = "0 0 48 48"
, size = size
, color = color
}
[ Svg.path
[ Svg.Attributes.d "M24 16c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 4c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 12c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"
]
[]
]
search : Icon msg
search { size, color } =
Icon.icon
{ viewBox = "0 0 48 48"
, size = size
, color = color
}
[ Svg.path
[ Svg.Attributes.d "M31 28h-1.59l-.55-.55C30.82 25.18 32 22.23 32 19c0-7.18-5.82-13-13-13S6 11.82 6 19s5.82 13 13 13c3.23 0 6.18-1.18 8.45-3.13l.55.55V31l10 9.98L40.98 38 31 28zm-12 0c-4.97 0-9-4.03-9-9s4.03-9 9-9 9 4.03 9 9-4.03 9-9 9z"
]
[]
]
menu : Icon msg
menu { size, color } =
Icon.icon
{ viewBox = "0 0 48 48"
, size = size
, color = color
}
[ Svg.path
[ Svg.Attributes.d "M6 36h36v-4H6v4zm0-10h36v-4H6v4zm0-14v4h36v-4H6z"
]
[]
]
menuTabButton : Palette -> ButtonStyle msg
menuTabButton palette =
{ elementButton =
Typography.button
++ [ Element.height <| Element.px 56
, Element.fill
|> Element.maximum 360
|> Element.minimum 90
|> Element.width
, Element.paddingXY 12 16
, palette.primary
|> MaterialColor.accessibleTextColor
|> MaterialColor.fromColor
|> Font.color
, Element.alignBottom
, Element.mouseDown
[ palette.primary
|> MaterialColor.scaleOpacity MaterialColor.buttonPressedOpacity
|> MaterialColor.fromColor
|> Background.color
]
, Element.focused
[ palette.primary
|> MaterialColor.scaleOpacity MaterialColor.buttonFocusOpacity
|> MaterialColor.fromColor
|> Background.color
]
, Element.mouseOver
[ palette.primary
|> MaterialColor.scaleOpacity MaterialColor.buttonHoverOpacity
|> MaterialColor.fromColor
|> Background.color
]
]
, ifDisabled =
(Button.baseButton palette |> .ifDisabled)
++ [ MaterialColor.gray
|> MaterialColor.fromColor
|> Font.color
, Element.mouseDown []
, Element.mouseOver []
, Element.focused []
]
, ifActive =
[ Border.widthEach
{ bottom = 2
, left = 0
, right = 0
, top = 0
}
]
, otherwise =
[]
, content =
{ elementRow =
[ Element.spacing <| 8
, Element.centerY
, Element.centerX
]
, content =
{ text = { contentText = [] }
, icon =
{ ifActive =
{ size = 18
, color = palette.primary |> MaterialColor.accessibleTextColor
}
, ifDisabled =
{ size = 18
, color = MaterialColor.gray
}
, otherwise =
{ size = 18
, color = palette.primary |> MaterialColor.accessibleTextColor
}
}
}
}
}
layout : Palette -> LayoutStyle msg
layout palette =
{ container =
@ -154,49 +33,13 @@ layout palette =
, Font.size 16
, Font.letterSpacing 0.5
]
, menuBar = AppBar.menuBar palette
, tabBar = AppBar.tabBar palette
, snackbar = Snackbar.snackbar palette
, header =
(palette.primary
|> MaterialColor.textAndBackground
)
++ [ Element.height <| Element.px 56
, Element.padding 16
, Element.width <| Element.minimum 360 <| Element.fill
]
, menuButton =
Button.iconButton palette
|> Customize.mapContent
(Customize.mapContent
(\record ->
{ record
| icon =
{ ifActive =
{ size = record.icon.ifActive.size
, color =
palette.primary
|> MaterialColor.accessibleTextColor
}
, ifDisabled =
record.icon.ifDisabled
, otherwise =
{ size = record.icon.otherwise.size
, color =
palette.primary
|> MaterialColor.accessibleTextColor
}
}
}
)
)
, sheetButton = Item.selectItem palette
, menuTabButton = menuTabButton palette
, sheet = Sheet.sideSheet palette
, menuIcon = menu
, moreVerticalIcon = more_vert
, spacing = 8
, title = Typography.h6 ++ [ Element.paddingXY 8 0 ]
, searchIcon = search
, search = TextInput.searchInput palette
, searchFill =
TextInput.textInputBase palette
|> Customize.elementRow [ Element.height <| Element.px 56 ]

View File

@ -8,7 +8,6 @@ module Widget exposing
, RowStyle, row, buttonRow
, ColumnStyle, column, buttonColumn
, ItemStyle, Item
, InsetItemStyle, InsetItem, insetItem
, ExpansionItemStyle, ExpansionItem, expansionItem
, ImageItemStyle, ImageItem, imageItem
, MultiLineItemStyle, MultiLineItem, multiLineItem
@ -16,12 +15,13 @@ module Widget exposing
, DividerStyle, divider
, selectItem, asItem
, itemList
, menuBar, tabBar
, SideSheetStyle, sideSheet
, SortTableStyle, SortTable, Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
, TextInputStyle, TextInput, textInput
, TabStyle, Tab, tab
, ProgressIndicatorStyle, ProgressIndicator, circularProgressIndicator
, FullBleedItemStyle, fullBleedItem
, FullBleedItemStyle, InsetItem, InsetItemStyle, fullBleedItem, insetItem
)
{-| This module contains different stateless view functions. No wiring required.
@ -122,6 +122,11 @@ You can create you own widgets by sticking widgets types together.
@docs itemList
# App Bar
@docs menuBar, tabBar
# Sheet
@docs SideSheetStyle, sideSheet
@ -165,8 +170,9 @@ You can create you own widgets by sticking widgets types together.
-}
import Color exposing (Color)
import Element exposing (Attribute, Element, Length)
import Element exposing (Attribute, DeviceClass, Element, Length)
import Element.Input exposing (Placeholder)
import Internal.AppBar as AppBar exposing (AppBarStyle)
import Internal.Button as Button
import Internal.Dialog as Dialog
import Internal.Item as Item
@ -1407,6 +1413,54 @@ buttonColumn =
--------------------------------------------------------------------------------
-- APP BAR
--------------------------------------------------------------------------------
menuBar :
AppBarStyle
{ menuIcon : Icon msg
, title : List (Attribute msg)
}
msg
->
{ title : Element msg
, deviceClass : DeviceClass
, openLeftSheet : msg
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
menuBar =
AppBar.menuBar
tabBar :
AppBarStyle
{ menuTabButton : ButtonStyle msg
, title : List (Attribute msg)
}
msg
->
{ title : Element msg
, menu : Select msg
, deviceClass : DeviceClass
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
tabBar =
AppBar.tabBar
--------------------------------------------------------------------------------
-- SHEET
--------------------------------------------------------------------------------

View File

@ -1,7 +1,6 @@
module Widget.Layout exposing
( LayoutStyle, Layout, Part(..), init, timePassed
, activate, queueMessage
, menuBar, tabBar
, leftSheet, rightSheet, searchSheet
, getDeviceClass, partitionActions, orderModals
, view
@ -48,6 +47,7 @@ import Array
import Element exposing (Attribute, DeviceClass(..), Element)
import Element.Input as Input
import Html exposing (Html)
import Internal.AppBar as AppBar exposing (AppBarStyle)
import Internal.Button as Button exposing (Button, ButtonStyle)
import Internal.Dialog as Dialog
import Internal.Item as Item exposing (InsetItemStyle, ItemStyle)
@ -64,19 +64,24 @@ import Widget.Snackbar as Snackbar exposing (Message, SnackbarStyle)
type alias LayoutStyle msg =
{ container : List (Attribute msg)
, snackbar : SnackbarStyle msg
, header : List (Attribute msg)
, sheet : SideSheetStyle msg
, sheetButton : ItemStyle (ButtonStyle msg) msg
, menuButton : ButtonStyle msg
, menuTabButton : ButtonStyle msg
, menuIcon : Icon msg
, moreVerticalIcon : Icon msg
, spacing : Int
, title : List (Attribute msg)
, searchIcon : Icon msg
, search : TextInputStyle 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
}
@ -193,191 +198,6 @@ partitionActions actions =
}
{-| A top bar that displays a menu icon on the left side.
-}
menuBar :
{ style
| menuIcon : Icon msg
, title : List (Attribute msg)
, header : List (Attribute msg)
, menuButton : ButtonStyle msg
, moreVerticalIcon : Icon msg
, spacing : Int
, searchIcon : Icon msg
, search : TextInputStyle msg
}
->
{ title : Element msg
, deviceClass : DeviceClass
, openLeftSheet : msg
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
menuBar style m =
internalNav
[ Button.iconButton style.menuButton
{ onPress = Just <| m.openLeftSheet
, icon = style.menuIcon
, text = "Menu"
}
, m.title |> Element.el style.title
]
style
m
{-| A top bar that displays the menu as tabs
-}
tabBar :
{ style
| menuTabButton : ButtonStyle msg
, title : List (Attribute msg)
, header : List (Attribute msg)
, menuButton : ButtonStyle msg
, moreVerticalIcon : Icon msg
, spacing : Int
, searchIcon : Icon msg
, search : TextInputStyle msg
}
->
{ title : Element msg
, menu : Select msg
, deviceClass : DeviceClass
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
tabBar style m =
internalNav
[ m.title |> Element.el style.title
, m.menu
|> Select.select
|> List.map (Select.selectButton style.menuTabButton)
|> Element.row
[ Element.width <| Element.shrink
]
]
style
m
{-| -}
internalNav :
List (Element msg)
->
{ style
| header : List (Attribute msg)
, menuButton : ButtonStyle msg
, moreVerticalIcon : Icon msg
, spacing : Int
, searchIcon : Icon msg
, search : TextInputStyle msg
}
->
{ model
| deviceClass : DeviceClass
, openRightSheet : msg
, openTopSheet : msg
, primaryActions : List (Button msg)
, moreActions : List (Button msg)
, search : Maybe (TextInput msg)
}
-> Element msg
internalNav menuElements style { deviceClass, openRightSheet, openTopSheet, primaryActions, moreActions, search } =
[ menuElements
|> Element.row
[ Element.width <| Element.shrink
, Element.spacing style.spacing
]
, if deviceClass == Phone || deviceClass == Tablet then
Element.none
else
search
|> Maybe.map
(\{ onChange, text, label } ->
TextInput.textInput style.search
{ chips = []
, onChange = onChange
, text = text
, placeholder =
Just <|
Input.placeholder [] <|
Element.text label
, label = label
}
)
|> Maybe.withDefault Element.none
, [ search
|> Maybe.map
(\{ label } ->
if deviceClass == Tablet then
[ Button.button style.menuButton
{ onPress = Just <| openTopSheet
, icon = style.searchIcon
, text = label
}
]
else if deviceClass == Phone then
[ Button.iconButton style.menuButton
{ onPress = Just <| openTopSheet
, icon = style.searchIcon
, text = label
}
]
else
[]
)
|> Maybe.withDefault []
, primaryActions
|> List.map
(if deviceClass == Phone then
Button.iconButton style.menuButton
else
Button.button
(style.menuButton
--FIX FOR ISSUE #30
|> Customize.elementButton [ Element.width Element.shrink ]
)
)
, if moreActions |> List.isEmpty then
[]
else
[ Button.iconButton style.menuButton
{ onPress = Just <| openRightSheet
, icon = style.moreVerticalIcon
, text = "More"
}
]
]
|> List.concat
|> Element.row
[ Element.alignRight
, Element.width Element.shrink
]
]
|> Element.row
(style.header
++ [ Element.padding 0
, Element.centerX
, Element.spacing style.spacing
, Element.alignTop
, Element.width <| Element.fill
]
)
{-| Left sheet containing a title and a menu.
-}
leftSheet :
@ -524,7 +344,7 @@ view style { search, title, onChangedSidebar, menu, actions, window, dialog, lay
|| (deviceClass == Tablet)
|| ((menu.options |> List.length) > 5)
then
menuBar style
AppBar.menuBar style.menuBar
{ title = title
, deviceClass = deviceClass
, openLeftSheet = onChangedSidebar <| Just LeftSheet
@ -536,7 +356,7 @@ view style { search, title, onChangedSidebar, menu, actions, window, dialog, lay
}
else
tabBar style
AppBar.tabBar style.tabBar
{ title = title
, menu = menu
, deviceClass = deviceClass

View File

@ -7,10 +7,11 @@ module Widget.Material exposing
, chip, textInput
, alertDialog
, row, column
, menuBar, tabBar
, sideSheet
, fullBleedItem, insetItem, multiLineItem, imageItem, expansionItem, selectItem
, fullBleedDivider, insetDivider, middleDivider
, insetHeader, fullBleedHeader
, fullBleedHeader, insetHeader
, progressIndicator
, sortTable
, snackbar
@ -81,6 +82,11 @@ Thus for now we only provide a card containing a list.
@docs row, column
# App Bar
@docs menuBar, tabBar
# Sheet
@docs sideSheet
@ -129,11 +135,23 @@ Note that you might want to checkout the [file on GitHub](https://github.com/Ora
-}
import Color exposing (Color)
import Element exposing (Attribute)
import Internal.AppBar exposing (AppBarStyle)
import Internal.Button exposing (ButtonStyle)
import Internal.Dialog exposing (DialogStyle)
import Internal.Item exposing (DividerStyle
, ExpansionItemStyle, FullBleedItemStyle, HeaderStyle, ImageItemStyle, ItemStyle, MultiLineItemStyle, InsetItemStyle)
import Internal.Item
exposing
( DividerStyle
, ExpansionItemStyle
, FullBleedItemStyle
, HeaderStyle
, ImageItemStyle
, InsetItemStyle
, ItemStyle
, MultiLineItemStyle
)
import Internal.List exposing (ColumnStyle, RowStyle)
import Internal.Material.AppBar as AppBar
import Internal.Material.Button as Button
import Internal.Material.Chip as Chip
import Internal.Material.Dialog as Dialog
@ -154,6 +172,7 @@ import Internal.SortTable exposing (SortTableStyle)
import Internal.Switch exposing (SwitchStyle)
import Internal.Tab exposing (TabStyle)
import Internal.TextInput exposing (TextInputStyle)
import Widget.Icon exposing (Icon)
import Widget.Layout exposing (LayoutStyle)
import Widget.Snackbar exposing (SnackbarStyle)
@ -312,6 +331,36 @@ chip =
--------------------------------------------------------------------------------
-- APP BAR
--------------------------------------------------------------------------------
menuBar :
Palette
->
AppBarStyle
{ menuIcon : Icon msg
, title : List (Attribute msg)
}
msg
menuBar =
AppBar.menuBar
tabBar :
Palette
->
AppBarStyle
{ menuTabButton : ButtonStyle msg
, title : List (Attribute msg)
}
msg
tabBar =
AppBar.tabBar
{-------------------------------------------------------------------------------
-- SHEET
-------------------------------------------------------------------------------}