WIP commit adding Progress Indicator

This commit is contained in:
chris 2020-08-11 12:28:29 -07:00
parent 2b981845d5
commit c3d9f70680
12 changed files with 268 additions and 3 deletions

View File

@ -8,6 +8,7 @@ import Example.ExpansionPanel as ExpansionPanel
import Example.List as List
import Example.Modal as Modal
import Example.MultiSelect as MultiSelect
import Example.ProgressIndicator as ProgressIndicator
import Example.Select as Select
import Example.SortTable as SortTable
import Example.Tab as Tab
@ -27,6 +28,7 @@ type Example
| DialogExample
| TextInputExample
| ListExample
| ProgressIndicatorExample
asList : List Example
@ -41,6 +43,7 @@ asList =
, DialogExample
, TextInputExample
, ListExample
, ProgressIndicatorExample
]
|> List.sortBy toString
@ -78,6 +81,9 @@ toString example =
ListExample ->
"List"
ProgressIndicatorExample ->
"ProgressIndicator"
fromString : String -> Maybe Example
fromString string =
@ -112,6 +118,9 @@ fromString string =
"List" ->
Just ListExample
"Progress Indicator" ->
Just ProgressIndicatorExample
_ ->
Nothing
@ -149,6 +158,9 @@ get example =
ListExample ->
.list
ProgressIndicatorExample ->
.progressIndicator
toTests : Example -> msg -> Style msg -> List ( String, Element msg )
toTests example =
@ -183,6 +195,9 @@ toTests example =
ListExample ->
Test.list
ProgressIndicatorExample ->
Test.progressIndicator
type Msg
= Button Button.Msg
@ -195,6 +210,7 @@ type Msg
| Dialog Dialog.Msg
| TextInput TextInput.Msg
| List List.Msg
| ProgressIndicator ProgressIndicator.Msg
type alias Model =
@ -208,6 +224,7 @@ type alias Model =
, dialog : Dialog.Model
, textInput : TextInput.Model
, list : List.Model
, progressIndicator : ProgressIndicator.Model
}
@ -231,6 +248,7 @@ type alias UpgradeCollection =
, dialog : UpgradeRecord Dialog.Model Dialog.Msg
, textInput : UpgradeRecord TextInput.Model TextInput.Msg
, list : UpgradeRecord List.Model List.Msg
, progressIndicator : UpgradeRecord ProgressIndicator.Model ProgressIndicator.Msg
}
@ -245,6 +263,7 @@ type alias ExampleView msg =
, dialog : Element msg
, textInput : Element msg
, list : Element msg
, progressIndicator : Element msg
}
@ -280,6 +299,9 @@ init =
( listModel, listMsg ) =
List.init
( progressIndicatorModel, progressIndicatorMsg ) =
ProgressIndicator.init
in
( { button = buttonModel
, select = selectModel
@ -291,6 +313,7 @@ init =
, dialog = dialogModel
, textInput = textInputModel
, list = listModel
, progressIndicator = progressIndicatorModel
}
, [ Cmd.map Button buttonMsg
, Cmd.map Select selectMsg
@ -302,6 +325,7 @@ init =
, Cmd.map Dialog dialogMsg
, Cmd.map TextInput textInputMsg
, Cmd.map List listMsg
, Cmd.map ProgressIndicator progressIndicatorMsg
]
|> Cmd.batch
)
@ -379,6 +403,13 @@ upgradeRecord =
, updateFun = List.update
, subscriptionsFun = List.subscriptions
}
, progressIndicator =
{ from = .progressIndicator
, to = \model a -> { model | progressIndicator = a }
, msgMapper = ProgressIndicator
, updateFun = ProgressIndicator.update
, subscriptionsFun = ProgressIndicator.subscriptions
}
}
@ -414,6 +445,9 @@ update msg model =
List m ->
updateField .list m
ProgressIndicator m ->
updateField .progressIndicator m
)
model
@ -434,6 +468,7 @@ subscriptions model =
, upgradeRecord.dialog |> subFun
, upgradeRecord.textInput |> subFun
, upgradeRecord.list |> subFun
, upgradeRecord.progressIndicator |> subFun
]
|> Sub.batch
@ -464,6 +499,8 @@ view msgMapper style model =
TextInput.view (TextInput >> msgMapper) style (.textInput model)
, list =
List.view (List >> msgMapper) style (.list model)
, progressIndicator =
ProgressIndicator.view (ProgressIndicator >> msgMapper) style (.progressIndicator model)
}

View File

@ -7,6 +7,7 @@ import Widget.Style
, DialogStyle
, ExpansionPanelStyle
, LayoutStyle
, ProgressIndicatorStyle
, RowStyle
, SortTableStyle
, TabStyle
@ -28,5 +29,6 @@ type alias Style msg =
, cardColumn : ColumnStyle msg
, sortTable : SortTableStyle msg
, selectButton : ButtonStyle msg
, progressIndicator : ProgressIndicatorStyle msg
, layout : LayoutStyle msg
}

View File

@ -20,6 +20,7 @@ import Widget.Style
, DialogStyle
, ExpansionPanelStyle
, LayoutStyle
, ProgressIndicatorStyle
, RowStyle
, SnackbarStyle
, SortTableStyle
@ -283,6 +284,12 @@ sortTable =
}
progressIndicatorStyle : ProgressIndicatorStyle msg
progressIndicatorStyle =
{ icon = Element.none
}
layout : LayoutStyle msg
layout =
{ container = []
@ -335,5 +342,6 @@ style =
, expansionPanel = expansionPanelStyle
, dialog = dialog
, selectButton = buttonStyle
, progressIndicator = progressIndicatorStyle
, layout = layout
}

View File

@ -52,5 +52,6 @@ style palette =
, chipButton = Material.chip palette
, expansionPanel = Material.expansionPanel palette
, dialog = Material.alertDialog palette
, progressIndicator = Material.progressIndicator palette
, layout = Material.layout palette
}

View File

@ -23,5 +23,6 @@ style =
, expansionPanel = Template.expansionPanel "expansionPanel"
, selectButton = Template.button "selectButton"
, dialog = Template.dialog "dialog"
, progressIndicator = Template.progressIndicator "progressIndicator"
, layout = Template.layout "layout"
}

View File

@ -0,0 +1,67 @@
module Example.ProgressIndicator exposing (Model, Msg, init, subscriptions, update, view)
import Browser
import Element exposing (Element)
import Widget
import Widget.Style exposing (ProgressIndicatorStyle)
import Widget.Style.Material as Material
type alias Style style msg =
{ style
| progressIndicator : ProgressIndicatorStyle msg
}
materialStyle : Style {} msg
materialStyle =
{ progressIndicator = Material.progressIndicator Material.defaultPalette
}
type Model
= ProgressPercent (Maybe Int)
type Msg
= ChangedProgressPercent (Maybe Int)
init : ( Model, Cmd Msg )
init =
( ProgressPercent Nothing
, Cmd.none
)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg _ =
case msg of
ChangedProgressPercent maybeInt ->
( ProgressPercent maybeInt
, 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 (ProgressPercent progressPercent) =
Widget.circularProgressIndicator style.progressIndicator
{ progressPercent = progressPercent
}
main : Program () Model Msg
main =
Browser.element
{ init = always init
, view = view identity materialStyle >> Element.layout []
, update = update
, subscriptions = subscriptions
}

View File

@ -1,4 +1,4 @@
module View.Test exposing (button, dialog, expansionPanel, list, modal, multiSelect, select, sortTable, tab, textInput)
module View.Test exposing (button, dialog, expansionPanel, list, modal, multiSelect, progressIndicator, select, sortTable, tab, textInput)
import Data.Style exposing (Style)
import Element exposing (Element)
@ -511,3 +511,11 @@ list _ style =
|> Widget.column style.cardColumn
)
]
progressIndicator : msg -> Style msg -> List ( String, Element msg )
progressIndicator _ style =
[ ( "Circular Progress Indicator"
, Widget.circularProgressIndicator style.progressIndicator { progressPercent = Nothing }
)
]

View File

@ -0,0 +1,17 @@
module Internal.ProgressIndicator exposing (circularProgressIndicator)
import Element exposing (Element)
import Widget.Style exposing (ProgressIndicatorStyle)
circularProgressIndicator :
ProgressIndicatorStyle msg
-> { progressPercent : Maybe Int }
-> Element msg
circularProgressIndicator style { progressPercent } =
-- TODO determinate indicator based on progressPercent
style.icon
-- TODO linear progress indicator

View File

@ -9,6 +9,7 @@ module Widget exposing
, TextInput, textInput
, Tab, tab
, Dialog, ExpansionPanel
, circularProgressIndicator
)
{-| This module contains different stateless view functions. No wiring required.
@ -126,12 +127,13 @@ import Internal.Button as Button
import Internal.Dialog as Dialog
import Internal.ExpansionPanel as ExpansionPanel
import Internal.List as List
import Internal.ProgressIndicator as ProgressIndicator
import Internal.Select as Select
import Internal.SortTable as SortTable
import Internal.Tab as Tab
import Internal.TextInput as TextInput
import Set exposing (Set)
import Widget.Style exposing (ButtonStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, RowStyle, SortTableStyle, TabStyle, TextInputStyle)
import Widget.Style exposing (ButtonStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, ProgressIndicatorStyle, RowStyle, SortTableStyle, TabStyle, TextInputStyle)
@ -616,3 +618,21 @@ tab =
Tab.tab
in
fun
{----------------------------------------------------------
- PROGRESS INDICATOR
----------------------------------------------------------}
type alias ProgressIndicator =
{ progressPercent : Maybe Int }
circularProgressIndicator :
ProgressIndicatorStyle msg
-> { progressPercent : Maybe Int }
-> Element msg
circularProgressIndicator =
ProgressIndicator.circularProgressIndicator

View File

@ -1,4 +1,6 @@
module Widget.Style exposing (ButtonStyle,ColumnStyle, DialogStyle, ExpansionPanelStyle, LayoutStyle, RowStyle, SnackbarStyle, SortTableStyle, TabStyle, TextInputStyle)
module Widget.Style exposing
( ButtonStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, LayoutStyle, RowStyle, SnackbarStyle, SortTableStyle, TabStyle, TextInputStyle, ProgressIndicatorStyle
)
{-| This module contains style types for every widget.
@ -132,3 +134,8 @@ type alias LayoutStyle msg =
, search : List (Attribute msg)
, searchFill : List (Attribute msg)
}
type alias ProgressIndicatorStyle msg =
{ icon : Element msg
}

View File

@ -7,6 +7,7 @@ module Widget.Style.Material exposing
, alertDialog
, expansionPanel
, row, column
, progressIndicator
, snackbar
, tab, tabButton
, layout
@ -42,6 +43,7 @@ You can use the theme by copying the following code:
, cardColumn : ColumnStyle msg
, sortTable : SortTableStyle msg
, selectButton : ButtonStyle msg
, progressIndicator : ProgressIndicatorStyle msg
, layout : LayoutStyle msg
}
@ -69,6 +71,7 @@ You can use the theme by copying the following code:
, chipButton = Material.chip palette
, expansionPanel = Material.expansionPanel palette
, dialog = Material.alertDialog palette
, progressIndicator = Material.progressIndicator palette
, layout = Material.layout palette
}
@ -123,6 +126,11 @@ The [List widget](https://material.io/components/lists) is a very complex widget
@docs row, column
# Progress Indicator
@docs progressIndicator
# Snackbar
@docs snackbar
@ -156,6 +164,7 @@ import Widget.Style
, DialogStyle
, ExpansionPanelStyle
, LayoutStyle
, ProgressIndicatorStyle
, RowStyle
, SnackbarStyle
, TabStyle
@ -1201,6 +1210,75 @@ expansionPanel palette =
{-------------------------------------------------------------------------------
-- P R O G R E S S I N D I C A T O R
-------------------------------------------------------------------------------}
indeterminateCircIcon : Color.Color -> List (Attribute msg) -> Element msg
indeterminateCircIcon color attribs =
-- Based on example at https://codepen.io/FezVrasta/pen/oXrgdR
Svg.svg
[ Svg.Attributes.height "48px"
, Svg.Attributes.width "48px"
, Svg.Attributes.viewBox "0 0 66 66"
, Svg.Attributes.xmlSpace "http://www.w3.org/2000/svg"
]
[ Svg.g []
[ Svg.animateTransform
[ Svg.Attributes.attributeName "transform"
, Svg.Attributes.type_ "rotate"
, Svg.Attributes.values "0 33 33;270 33 33"
, Svg.Attributes.begin "0s"
, Svg.Attributes.dur "1.4s"
, Svg.Attributes.fill "freeze"
, Svg.Attributes.repeatCount "indefinite"
]
[]
, Svg.circle
[ Svg.Attributes.fill "none"
, Svg.Attributes.stroke (Color.toCssString color)
, Svg.Attributes.strokeWidth "5"
, Svg.Attributes.strokeLinecap "square"
, Svg.Attributes.cx "33"
, Svg.Attributes.cy "33"
, Svg.Attributes.r "30"
, Svg.Attributes.strokeDasharray "187"
, Svg.Attributes.strokeDashoffset "610"
]
[ Svg.animateTransform
[ Svg.Attributes.attributeName "transform"
, Svg.Attributes.type_ "rotate"
, Svg.Attributes.values "0 33 33;135 33 33;450 33 33"
, Svg.Attributes.begin "0s"
, Svg.Attributes.dur "1.4s"
, Svg.Attributes.fill "freeze"
, Svg.Attributes.repeatCount "indefinite"
]
[]
, Svg.animate
[ Svg.Attributes.attributeName "stroke-dashoffset"
, Svg.Attributes.values "187;46.75;187"
, Svg.Attributes.begin "0s"
, Svg.Attributes.dur "1.4s"
, Svg.Attributes.fill "freeze"
, Svg.Attributes.repeatCount "indefinite"
]
[]
]
]
]
|> Element.html
|> Element.el attribs
progressIndicator : Palette -> ProgressIndicatorStyle msg
progressIndicator palette =
{ icon = indeterminateCircIcon palette.primary []
}
{-------------------------------------------------------------------------------
-- S N A C K B A R
-------------------------------------------------------------------------------}

View File

@ -1,6 +1,7 @@
module Widget.Style.Template exposing
( box, decoration, icon
, button, column, dialog, expansionPanel, layout, row, snackbar, sortTable, tab, textInput
, progressIndicator
)
{-| ![Example using the Template style](https://orasund.github.io/elm-ui-widgets/assets/template-style.png)
@ -69,6 +70,7 @@ import Widget.Style
, DialogStyle
, ExpansionPanelStyle
, LayoutStyle
, ProgressIndicatorStyle
, RowStyle
, SnackbarStyle
, SortTableStyle
@ -339,6 +341,23 @@ sortTable string =
}
{-|
```
progressIndicator : String -> ProgressIndicatorStyle msg
progressIndicator string =
{ track = box <| string ++ ":track"
, indicator = box <| string ++ ":box"
}
```
-}
progressIndicator : String -> ProgressIndicatorStyle msg
progressIndicator string =
{ icon = icon <| string ++ ":icon"
}
{-|
```