diff --git a/README.md b/README.md index fcdff6f..b99e139 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,139 @@ # Elm-Ui-Widgets -Usefull Widgets written for Elm-ui. -These include: +This package contains **independend** widgets (no components) written for [Elm-Ui](https://dark.elm.dmy.fr/packages/mdgriffith/elm-ui/latest/). These widgets have no dependencies to other parts of this package. So you can just use as much as you need. -* Select -* Tab -* Multi Select -* Collapsable -* Dialog -* Carousel -* Snackbar -* Sort Table -* Filter Select -* Validated Input -* Scrolling Nav +It also supports custom themes and has a material design theme already ready to use. -Examples of all widgets can be found [here](https://orasund.github.io/elm-ui-widgets/). For styling, I used my own [Orasund/elm-ui-framework](https://package.elm-lang.org/packages/Orasund/elm-ui-framework/latest/). +[Examples of all widgets can be found here](https://orasund.github.io/elm-ui-widgets/). -## Why create such a package? +![Example using the Material Design style](https://orasund.github.io/elm-ui-widgets/assets/material-style.png) + +## Concept + +**Summary** + +* Each widget comes with a _Widget Type_ and a _Style Type_. The Widget Type is an abstract representation of the widget and the Style Type has all styling attributes. +* Widget Types can be used as building Blocks for more complicated Widgets + (Button -> Select Buttons -> Menu -> Layout) + +**Example** + +Let's look at the button widget. + +```elm +button: ButtonStyle msg + -> + { text : String + , icon : Element Never + , onPress : Maybe msg + } + -> Element msg +``` + +In comparison to Elm-Ui's button, we see that `List (Attribute msg)` has changed into a _Style Type_. + ``` + type alias ButtonStyle msg = + { container : List (Attribute msg) + , labelRow : List (Attribute msg) + , ifDisabled : List (Attribute msg) + , ifActive : List (Attribute msg) + } + ``` + +For actually displaying the button we have a few different implementations: + +``` elm +{-| Button with only an icon and no text -} +iconButton : + ButtonStyle msg + -> + { text : String --for screen readers + , icon : Element Never + , onPress : Maybe msg + } + -> Element msg + +{-| Button with a text but no icon -} +textButton : + ButtonStyle msg + -> + { textButton + | text : String + , onPress : Maybe msg + } + -> Element msg + +{-| Button with both icon and text -} +button : + ButtonStyle msg + -> + { text : String + , icon : Element Never + , onPress : Maybe msg + } + -> Element msg +``` + +We also have a `Widget Type` for the button: + +``` +type alias Button msg = + { text : String + , icon : Element Never + , onPress : Maybe msg + } +``` + +We can use it to build more complex widgets, for example a select button: + +``` +type alias Select msg = + { selected : Maybe Int + , options : + List + { text : String + , icon : Element Never + } + , onSelect : Int -> Maybe msg + } + +select : + Select msg + -> List ( Bool, Button msg ) + +selectButton : + ButtonStyle msg + -> ( Bool, Button msg ) + -> Element msg +``` + +## Reusable Views vs. Components + +In Elm we like to use reusable views instead of components. +At first this packages had a few components, but they where so complicated to use in comparison, so they got slowly turned into reusable views one by one. + +Most could be reduced even further into _view functions_: reusable views without a model. +Currently we have only three reusable views: `Widget.Layout`, `Widget.ScrollingNav` and `Widget.Snackbar`. + +## Alternatives + +For comparison, here are some alternative packages for creating UIs: + +* **Using Elm-Ui** + * [lucamug/style-framework](https://dark.elm.dmy.fr/packages/lucamug/style-framework/latest/) - Full customization requires the cloning of the package. + * [jxxcarlson/elm-widget](https://dark.elm.dmy.fr/packages/jxxcarlson/elm-widget/latest/Widget-Button) - Uses a Builder pattern. Has some redefined customizations. + * [QiTASC/hatchinq](https://dark.elm.dmy.fr/packages/QiTASC/hatchinq/latest/) - Similar Arroach but still in experimental phase +* **Using Elm/Html** + * [nathanjohnson320/elm-ui-components](https://dark.elm.dmy.fr/packages/nathanjohnson320/elm-ui-components/latest/) - Uses the elm/html way of styling. + * [NoRedInk/noredink-ui](https://dark.elm.dmy.fr/packages/NoRedInk/noredink-ui/latest/) - Similar Approach but no customization options. + * [peterszerzo/elm-natural-ui](https://dark.elm.dmy.fr/packages/peterszerzo/elm-natural-ui/latest) - Uses custom Attributes with some customization. +* **Ui Frameworks** + * [aforemny/material-components-web-elm](https://dark.elm.dmy.fr/packages/aforemny/material-components-web-elm/latest/) - Wrapper of Material design using custom elements. + * [afidegnum/elm-tailwind](https://dark.elm.dmy.fr/packages/afidegnum/elm-tailwind/latest/) - Wrapper of Tailwind by including the tailwind stylesheet. + * [surprisetalk/elm-bulma](https://dark.elm.dmy.fr/packages/surprisetalk/elm-bulma/latest/) - Wrapper for Bulma by including the bulma stylesheet. + * [rundis/elm-bootstrap](https://dark.elm.dmy.fr/packages/rundis/elm-bootstrap/latest/) - Wrapper for Bootstrap by including the bootstrap stylesheet. + +## Motivation After looking at the current packages that implement various reusable views (and components) I noticed two things: @@ -26,10 +142,6 @@ After looking at the current packages that implement various reusable views (and This package tries to solve both of these problems. -## Why does this package also include components? +## Changelog -I wrote a component whenever the boilerplate of a similar reusable view is less than just include the wiring in the package. - -## Where will it go from here - -I really would like to write a native material-design implementation in Elm. But after doing this package as a first step, (Which I already wrote while having the material.io docs as reference) I am not quite sure how I can avoid a lot of boilerplating. It seems like a [Master View Type](https://www.freecodecamp.org/news/scaling-elm-views-with-master-view-types/) would be the solution, but I'm not quite sure how I can ensure the customizability when my entire page can be described as a single type. (I don't want to know how many parameters such a type would need). \ No newline at end of file +* **Version 2.0** - Complete rewrite of the package. Now including a material design implementation. \ No newline at end of file diff --git a/docs.json b/docs.json index 89b845a..8048680 100644 --- a/docs.json +++ b/docs.json @@ -1 +1 @@ -[{"name":"Framework","comment":" This module includes the basic building bocks.\r\nMaybe start by copying the follow code into your project:\r\n\r\n```\r\nview : Html msg\r\nview =\r\n Framework.layout [] <|\r\n Element.el Framework.container <|\r\n Element.text \"the first element should be a container.\"\r\n```\r\n\r\n@docs layout, container, layoutOptions, layoutAttributes\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"container","comment":" The container should be the outer most element.\r\nIt centers the content and sets the background to white.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"layout","comment":" A replacement of Element.layout adding both the Framework.layoutOptions and the Framework.layoutAttributes.\r\n","type":"List.List (Element.Attribute msg) -> Element.Element msg -> Html.Html msg"},{"name":"layoutAttributes","comment":" The default Attributes. Check the source code if you want to know more.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"layoutOptions","comment":" The default layoutOptions. Check the source code if you want to know more.\r\n","type":"List.List Element.Option"}],"binops":[]},{"name":"Framework.Button","comment":" This module contains a attribute to style buttons.\r\n\r\n```\r\nInput.button (Button.simple ++ Color.primary) <|\r\n { onPress = Nothing\r\n , label = Element.text \"Button.simple ++ Color.primary\"\r\n }\r\n```\r\n\r\nThe attribute can only be used on `Input.button` but it may be with additional attibutes from this package.\r\n\r\n@docs simple\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"simple","comment":" a simple Button styling. Check the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"}],"binops":[]},{"name":"Framework.Card","comment":" The Card attributes can be used almost anywere in the elm-ui elements.\r\n\r\nHere are some examples:\r\n\r\n```\r\nElement.column (Card.simple ++ Grid.simple) <|\r\n [ Element.text <| \"adds a border around the column\"\r\n ]\r\n```\r\n\r\n```\r\nElement.el Card.small <|\r\n Element.text \"a basic card\"\r\n```\r\n\r\n```\r\nInput.button (Button.simple ++ Card.large) <|\r\n { onPress = Nothing\r\n , label = Element.text \"a clickable card\"\r\n }\r\n```\r\n\r\n@docs simple, small, large, fill\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"fill","comment":" A card filling all the avaiable space.\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"large","comment":" A 480px wide card.\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"simple","comment":" A basic card.\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"small","comment":" A 240px wide card.\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"}],"binops":[]},{"name":"Framework.Color","comment":" This module contains the colors used in the framework.\r\n\r\n@docs cyan, green, lighterGrey, lightGrey, grey, darkGrey, darkerGrey, red, turquoise, yellow\r\n\r\nSome colors also have a Attribute that can be used nearly everywhere.\r\n\r\n@docs danger, light, dark, disabled, info, primary, success, warning\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"cyan","comment":" ","type":"Element.Color"},{"name":"danger","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"dark","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"darkGrey","comment":" ","type":"Element.Color"},{"name":"darkerGrey","comment":" ","type":"Element.Color"},{"name":"disabled","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"green","comment":" ","type":"Element.Color"},{"name":"grey","comment":" ","type":"Element.Color"},{"name":"info","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"light","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"lightGrey","comment":" ","type":"Element.Color"},{"name":"lighterGrey","comment":" ","type":"Element.Color"},{"name":"primary","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"red","comment":" ","type":"Element.Color"},{"name":"success","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"turquoise","comment":" ","type":"Element.Color"},{"name":"warning","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"yellow","comment":" ","type":"Element.Color"}],"binops":[]},{"name":"Framework.Grid","comment":" This module include the basic attributes for columns and rows and two variants.\r\nAny of these Attributes can be used for columns and rows.\r\n\r\n```\r\nElement.row Grid.spacedEvenly <|\r\n [ Element.text \"left item\"\r\n , Element.text \"center item\"\r\n , Element.text \"right item\"\r\n ]\r\n```\r\n\r\n@docs simple, spacedEvenly, section\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"section","comment":" The simple attributes but with a horizontal line at the top\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"simple","comment":" The basic attributes for columns and rows.\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"},{"name":"spacedEvenly","comment":" The simple attibutes but with evenly spaced elements.\r\nCheck the source-code for more information.\r\n","type":"List.List (Element.Attribute msg)"}],"binops":[]},{"name":"Framework.Heading","comment":" Styling for heading\r\n\r\n```\r\nElement.el Heading.h1 <| Element.text \"Only Element.el may be styled as a heading\"\r\n```\r\n\r\n@docs h1, h2, h3, h4, h5, h6\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"h1","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"h2","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"h3","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"h4","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"h5","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"h6","comment":" ","type":"List.List (Element.Attribute msg)"}],"binops":[]},{"name":"Framework.Input","comment":" This module exposes simple attibutes for Inputs (beside Buttons) and\r\nstyling for labels.\r\n\r\n```\r\nInput.text Input.simple\r\n { onChange = always ()\r\n , text = \"Input.simple\"\r\n , placeholder = Nothing\r\n , label = Input.labelLeft Input.label <| Element.text \"Input.label\"\r\n }\r\n```\r\n\r\n@docs simple, label\r\n\r\n","unions":[],"aliases":[],"values":[{"name":"label","comment":" ","type":"List.List (Element.Attribute msg)"},{"name":"simple","comment":" ","type":"List.List (Element.Attribute msg)"}],"binops":[]}] \ No newline at end of file +[{"name":"Widget","comment":" This module contains different stateless view functions. No wiring required.\n\nThese widgets should be used by defining the styling seperately:\n\n```\nWidget.button Material.primaryButton\n { text = \"disable me\"\n , icon =\n FeatherIcons.slash\n |> FeatherIcons.withSize 16\n |> FeatherIcons.toHtml []\n |> Element.html\n |> Element.el []\n , onPress =\n if isButtonEnabled then\n ChangedButtonStatus False\n |> Just\n\n else\n Nothing\n }\n```\n\nEvery widgets comes with a type. You can think of the widgets as building blocks.\nYou can create you own widgets by sticking widgets types together.\n\n# Buttons\n\n![Button](https://orasund.github.io/elm-ui-widgets/assets/button.png)\n\n@docs Button, TextButton, iconButton, textButton, button\n\n\n# Select\n\n![Select](https://orasund.github.io/elm-ui-widgets/assets/select.png)\n\n@docs Select, selectButton, select\n\n![multiSelect](https://orasund.github.io/elm-ui-widgets/assets/multiSelect.png)\n\n@docs MultiSelect, multiSelect\n\n\n# Dialog\n\n![dialog](https://orasund.github.io/elm-ui-widgets/assets/dialog.png)\n\n@docs Dialog, modal, dialog\n\n\n# Expansion Panel\n\n![expansionPanel](https://orasund.github.io/elm-ui-widgets/assets/expansionPanel.png)\n\n@docs ExpansionPanel, expansionPanel\n\n\n# List\n\n![list](https://orasund.github.io/elm-ui-widgets/assets/list.png)\n\n@docs row, column, buttonRow, buttonColumn\n\n\n# Sort Table\n\n![sortTable](https://orasund.github.io/elm-ui-widgets/assets/sortTable.png)\n\n@docs SortTable,Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn\n\n\n# Text Input\n\n![textInput](https://orasund.github.io/elm-ui-widgets/assets/textInput.png)\n\n@docs TextInput, textInput\n\n\n# Tab\n\n![tab](https://orasund.github.io/elm-ui-widgets/assets/textInput.png)\n\n@docs Tab, tab\n\n","unions":[],"aliases":[{"name":"Button","comment":" Button widget type\n","args":["msg"],"type":"{ text : String.String, icon : Element.Element Basics.Never, onPress : Maybe.Maybe msg }"},{"name":"Column","comment":" Column for the Sort Table widget type\n","args":["a"],"type":"Internal.SortTable.Column a"},{"name":"Dialog","comment":" Dialog widget type\n","args":["msg"],"type":"{ title : Maybe.Maybe String.String, body : Element.Element msg, accept : Maybe.Maybe (Widget.TextButton msg), dismiss : Maybe.Maybe (Widget.TextButton msg) }"},{"name":"ExpansionPanel","comment":" Expansion Panel widget type\n","args":["msg"],"type":"{ onToggle : Basics.Bool -> msg, icon : Element.Element Basics.Never, text : String.String, expandIcon : Element.Element Basics.Never, collapseIcon : Element.Element Basics.Never, content : Element.Element msg, isExpanded : Basics.Bool }"},{"name":"MultiSelect","comment":" Multi Select widget type\n\nTechnical Remark:\n\n* A more suitable name would be \"Options\"\n\n","args":["msg"],"type":"{ selected : Set.Set Basics.Int, options : List.List { text : String.String, icon : Element.Element Basics.Never }, onSelect : Basics.Int -> Maybe.Maybe msg }"},{"name":"Select","comment":" Select widget type\n\nTechnical Remark:\n\n* A more suitable name would be \"Choice\"\n\n","args":["msg"],"type":"{ selected : Maybe.Maybe Basics.Int, options : List.List { text : String.String, icon : Element.Element Basics.Never }, onSelect : Basics.Int -> Maybe.Maybe msg }"},{"name":"SortTable","comment":" Sort Table widget type\n","args":["a","msg"],"type":"{ content : List.List a, columns : List.List (Widget.Column a), sortBy : String.String, asc : Basics.Bool, onChange : String.String -> msg }"},{"name":"Tab","comment":" Tab widget type\n","args":["msg"],"type":"{ tabs : Widget.Select msg, content : Maybe.Maybe Basics.Int -> Element.Element msg }"},{"name":"TextButton","comment":" Button widget type with no icon\n","args":["msg"],"type":"{ text : String.String, onPress : Maybe.Maybe msg }"},{"name":"TextInput","comment":" Text Input widget type\n","args":["msg"],"type":"{ chips : List.List (Widget.Button msg), text : String.String, placeholder : Maybe.Maybe (Element.Input.Placeholder msg), label : String.String, onChange : String.String -> msg }"}],"values":[{"name":"button","comment":" A button containing a text and an icon.\n","type":"Widget.Style.ButtonStyle msg -> { text : String.String, icon : Element.Element Basics.Never, onPress : Maybe.Maybe msg } -> Element.Element msg"},{"name":"buttonColumn","comment":" A column of buttons\n","type":"{ list : Widget.Style.ColumnStyle msg, button : Widget.Style.ButtonStyle msg } -> List.List ( Basics.Bool, Widget.Button msg ) -> Element.Element msg"},{"name":"buttonRow","comment":" A row of buttons\n","type":"{ list : Widget.Style.RowStyle msg, button : Widget.Style.ButtonStyle msg } -> List.List ( Basics.Bool, Widget.Button msg ) -> Element.Element msg"},{"name":"column","comment":" Replacement of `Element.column`\n","type":"Widget.Style.ColumnStyle msg -> List.List (Element.Element msg) -> Element.Element msg"},{"name":"dialog","comment":" A Dialog Window.\n","type":"Widget.Style.DialogStyle msg -> { title : Maybe.Maybe String.String, text : String.String, accept : Maybe.Maybe (Widget.TextButton msg), dismiss : Maybe.Maybe (Widget.TextButton msg) } -> List.List (Element.Attribute msg)"},{"name":"expansionPanel","comment":" An expansion Panel\n","type":"Widget.Style.ExpansionPanelStyle msg -> { onToggle : Basics.Bool -> msg, icon : Element.Element Basics.Never, text : String.String, content : Element.Element msg, isExpanded : Basics.Bool } -> Element.Element msg"},{"name":"floatColumn","comment":" A Column containing a Float\n","type":"{ title : String.String, value : a -> Basics.Float, toString : Basics.Float -> String.String, width : Element.Length } -> Widget.Column a"},{"name":"iconButton","comment":" A button containing only an icon, the text is used for screenreaders.\n","type":"Widget.Style.ButtonStyle msg -> { text : String.String, icon : Element.Element Basics.Never, onPress : Maybe.Maybe msg } -> Element.Element msg"},{"name":"intColumn","comment":" A Column containing a Int\n","type":"{ title : String.String, value : a -> Basics.Int, toString : Basics.Int -> String.String, width : Element.Length } -> Widget.Column a"},{"name":"modal","comment":" A modal.\n\nTechnical Remark:\n\n* To stop the screen from scrolling, set the height of the layout to the height of the screen.\n\n","type":"{ onDismiss : Maybe.Maybe msg, content : Element.Element msg } -> List.List (Element.Attribute msg)"},{"name":"multiSelect","comment":" Selects multible options. This can be used for checkboxes.\n","type":"Widget.MultiSelect msg -> List.List ( Basics.Bool, Widget.Button msg )"},{"name":"row","comment":" Replacement of `Element.row`\n","type":"Widget.Style.RowStyle msg -> List.List (Element.Element msg) -> Element.Element msg"},{"name":"select","comment":" Selects one out of multiple options. This can be used for radio buttons or Menus.\n","type":"Widget.Select msg -> List.List ( Basics.Bool, Widget.Button msg )"},{"name":"selectButton","comment":" A simple button that can be selected.\n","type":"Widget.Style.ButtonStyle msg -> ( Basics.Bool, Widget.Button msg ) -> Element.Element msg"},{"name":"sortTable","comment":" The View\n","type":"Widget.Style.SortTableStyle msg -> { content : List.List a, columns : List.List (Widget.Column a), sortBy : String.String, asc : Basics.Bool, onChange : String.String -> msg } -> Element.Element msg"},{"name":"stringColumn","comment":" A Column containing a String\n","type":"{ title : String.String, value : a -> String.String, toString : String.String -> String.String, width : Element.Length } -> Widget.Column a"},{"name":"tab","comment":" Displayes a list of contents in a tab\n","type":"Widget.Style.TabStyle msg -> { tabs : Widget.Select msg, content : Maybe.Maybe Basics.Int -> Element.Element msg } -> Element.Element msg"},{"name":"textButton","comment":" A button with just text and not icon.\n","type":"Widget.Style.ButtonStyle msg -> { textButton | text : String.String, onPress : Maybe.Maybe msg } -> Element.Element msg"},{"name":"textInput","comment":" A text Input that allows to include chips. ","type":"Widget.Style.TextInputStyle msg -> { chips : List.List (Widget.Button msg), text : String.String, placeholder : Maybe.Maybe (Element.Input.Placeholder msg), label : String.String, onChange : String.String -> msg } -> Element.Element msg"},{"name":"unsortableColumn","comment":" An unsortable Column, when trying to sort by this column, nothing will change.\n","type":"{ title : String.String, toString : a -> String.String, width : Element.Length } -> Widget.Column a"}],"binops":[]},{"name":"Widget.Layout","comment":" Combines multiple concepts from the [material design specification](https://material.io/components/), namely:\n\n* Top App Bar\n* Navigation Draw\n* Side Panel\n* Dialog\n* Snackbar\n\nIt is responsive and changes view to apply to the [material design guidelines](https://material.io/components/app-bars-top).\n\n# Basics\n\n@docs Layout, Part, init, timePassed, view\n\n# Actions\n\n@docs activate, queueMessage\n\n\n","unions":[{"name":"Part","comment":" The currently visible part: either the left sheet, right sheet or the search bar\n","args":[],"cases":[["LeftSheet",[]],["RightSheet",[]],["Search",[]]]}],"aliases":[{"name":"Layout","comment":" The model of the layout containing the snackbar and the currently active side sheet (or search bar)\n","args":["msg"],"type":"{ snackbar : Widget.Snackbar.Snackbar (Widget.Snackbar.Message msg), active : Maybe.Maybe Widget.Layout.Part }"}],"values":[{"name":"activate","comment":" Open either a side sheet or the search bar.\n","type":"Maybe.Maybe Widget.Layout.Part -> Widget.Layout.Layout msg -> Widget.Layout.Layout msg"},{"name":"init","comment":" The initial state of the layout\n","type":"Widget.Layout.Layout msg"},{"name":"queueMessage","comment":" Queues a message and displayes it as a snackbar once no other snackbar is visible.\n","type":"Widget.Snackbar.Message msg -> Widget.Layout.Layout msg -> Widget.Layout.Layout msg"},{"name":"timePassed","comment":" Update the model, put this function into your subscription.\nThe first argument is the seconds that have passed sice the function was called last.\n","type":"Basics.Int -> Widget.Layout.Layout msg -> Widget.Layout.Layout msg"},{"name":"view","comment":" View the layout. Replacement of `Element.layout`.\n","type":"Widget.Style.LayoutStyle msg -> { window : { height : Basics.Int, width : Basics.Int }, dialog : Maybe.Maybe (List.List (Element.Attribute msg)), layout : Widget.Layout.Layout msg, title : Element.Element msg, menu : Widget.Select msg, search : Maybe.Maybe { onChange : String.String -> msg, text : String.String, label : String.String }, actions : List.List (Widget.Button msg), onChangedSidebar : Maybe.Maybe Widget.Layout.Part -> msg } -> Element.Element msg -> Html.Html msg"}],"binops":[]},{"name":"Widget.ScrollingNav","comment":" The Scrolling Nav is a navigation bar thats updates while you scroll through\nthe page. Clicking on a navigation button will scroll directly to that section.\n\n\n# Basics\n\n@docs ScrollingNav, init, view, current, toSelect\n\n\n# Operations\n\n@docs jumpTo, jumpToWithOffset, syncPositions, getPos, setPos\n\n","unions":[],"aliases":[{"name":"ScrollingNav","comment":" ","args":["section"],"type":"{ toString : section -> String.String, fromString : String.String -> Maybe.Maybe section, positions : IntDict.IntDict String.String, arrangement : List.List section, scrollPos : Basics.Int }"}],"values":[{"name":"current","comment":" Returns the current section\n","type":"(String.String -> Maybe.Maybe section) -> Widget.ScrollingNav.ScrollingNav section -> Maybe.Maybe section"},{"name":"getPos","comment":" Syncs the position of of the viewport\n","type":"Task.Task x (Widget.ScrollingNav.ScrollingNav selection -> Widget.ScrollingNav.ScrollingNav selection)"},{"name":"init","comment":" The intial state include the labels and the arrangement of the sections\n","type":"{ toString : section -> String.String, fromString : String.String -> Maybe.Maybe section, arrangement : List.List section, toMsg : Result.Result Browser.Dom.Error (Widget.ScrollingNav.ScrollingNav section -> Widget.ScrollingNav.ScrollingNav section) -> msg } -> ( Widget.ScrollingNav.ScrollingNav section, Platform.Cmd.Cmd msg )"},{"name":"jumpTo","comment":" Scrolls the screen to the respective section\n","type":"{ section : section, onChange : Result.Result Browser.Dom.Error () -> msg } -> Widget.ScrollingNav.ScrollingNav section -> Platform.Cmd.Cmd msg"},{"name":"jumpToWithOffset","comment":" Scrolls the screen to the respective section with some offset\n","type":"{ offset : Basics.Float, section : section, onChange : Result.Result Browser.Dom.Error () -> msg } -> Widget.ScrollingNav.ScrollingNav section -> Platform.Cmd.Cmd msg"},{"name":"setPos","comment":" sets the position of the viewport to show a specific section\n","type":"Basics.Int -> Widget.ScrollingNav.ScrollingNav section -> Widget.ScrollingNav.ScrollingNav section"},{"name":"syncPositions","comment":" Updates the positions of all sections.\nThis functions should be called regularly if the height of elements on your page can change during time.\n","type":"Widget.ScrollingNav.ScrollingNav section -> Task.Task Browser.Dom.Error (Widget.ScrollingNav.ScrollingNav section -> Widget.ScrollingNav.ScrollingNav section)"},{"name":"toSelect","comment":" Returns a select widget containing all section, with the current section selected.\n","type":"(Basics.Int -> Maybe.Maybe msg) -> Widget.ScrollingNav.ScrollingNav section -> Widget.Select msg"},{"name":"view","comment":" Opinionated way of viewing the section.\n\nThis might be useful at first, but you should consider writing your own view function.\n\n```\nview :\n (section -> Element msg)\n -> Model section\n -> List (Element msg)\nview asElement { toString, arrangement } =\n arrangement\n |> List.map\n (\\header ->\n Element.el\n [ header\n |> toString\n |> Attributes.id\n |> Element.htmlAttribute\n , Element.width <| Element.fill\n ]\n <|\n asElement <|\n header\n )\n```\n\n","type":"(section -> Element.Element msg) -> Widget.ScrollingNav.ScrollingNav section -> List.List (Element.Element msg)"}],"binops":[]},{"name":"Widget.Snackbar","comment":" ![Snackbar](https://orasund.github.io/elm-ui-widgets/assets/snackbar.png)\n\nA [snackbar](https://material.io/components/snackbars/) shows notification, one at a time.\n\n\n# Basics\n\n@docs Snackbar, Message, init, current, timePassed, view\n\n\n# Operations\n\n@docs insert, insertFor, dismiss\n\n","unions":[],"aliases":[{"name":"Message","comment":" A message with maybe some action button\n","args":["msg"],"type":"{ text : String.String, button : Maybe.Maybe (Widget.TextButton msg) }"},{"name":"Snackbar","comment":" A snackbar has a queue of Notifications, each with the amount of ms the message should be displayed\n","args":["a"],"type":"{ queue : Queue.Queue ( a, Basics.Int ), current : Maybe.Maybe ( a, Basics.Int ) }"}],"values":[{"name":"current","comment":" Returns the current element.\n","type":"Widget.Snackbar.Snackbar a -> Maybe.Maybe a"},{"name":"dismiss","comment":" Dismiss the current message.\n","type":"Widget.Snackbar.Snackbar a -> Widget.Snackbar.Snackbar a"},{"name":"init","comment":" Inital state\n","type":"Widget.Snackbar.Snackbar a"},{"name":"insert","comment":" Insert a message that will last for 10 seconds.\n","type":"a -> Widget.Snackbar.Snackbar a -> Widget.Snackbar.Snackbar a"},{"name":"insertFor","comment":" Insert a message for a specific amount of milli seconds.\n","type":"Basics.Int -> a -> Widget.Snackbar.Snackbar a -> Widget.Snackbar.Snackbar a"},{"name":"timePassed","comment":" Updates the model. This functions should be called regularly.\nThe first argument is the milli seconds that passed since the last time the function was called.\n","type":"Basics.Int -> Widget.Snackbar.Snackbar a -> Widget.Snackbar.Snackbar a"},{"name":"view","comment":" Views the current Message. (only one at a time)\n","type":"Widget.Style.SnackbarStyle msg -> (a -> Widget.Snackbar.Message msg) -> Widget.Snackbar.Snackbar a -> Maybe.Maybe (Element.Element msg)"}],"binops":[]},{"name":"Widget.Style","comment":" This module contains style types for every widget.\n\n@docs ButtonStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, LayoutStyle, RowStyle, SnackbarStyle, SortTableStyle, TabStyle, TextInputStyle\n\n","unions":[],"aliases":[{"name":"ButtonStyle","comment":" ","args":["msg"],"type":"{ container : List.List (Element.Attribute msg), labelRow : List.List (Element.Attribute msg), text : List.List (Element.Attribute msg), ifDisabled : List.List (Element.Attribute msg), ifActive : List.List (Element.Attribute msg), otherwise : List.List (Element.Attribute msg) }"},{"name":"ColumnStyle","comment":" ","args":["msg"],"type":"{ containerColumn : List.List (Element.Attribute msg), element : List.List (Element.Attribute msg), ifFirst : List.List (Element.Attribute msg), ifLast : List.List (Element.Attribute msg), otherwise : List.List (Element.Attribute msg) }"},{"name":"DialogStyle","comment":" ","args":["msg"],"type":"{ containerColumn : List.List (Element.Attribute msg), title : List.List (Element.Attribute msg), buttonRow : List.List (Element.Attribute msg), acceptButton : Widget.Style.ButtonStyle msg, dismissButton : Widget.Style.ButtonStyle msg, text : List.List (Element.Attribute msg) }"},{"name":"ExpansionPanelStyle","comment":" Technical Remark:\n\n - If icons are defined in Svg, they might not display correctly.\n To avoid that, make sure to wrap them in `Element.html >> Element.el []`\n\n","args":["msg"],"type":"{ containerColumn : List.List (Element.Attribute msg), panelRow : List.List (Element.Attribute msg), labelRow : List.List (Element.Attribute msg), content : List.List (Element.Attribute msg), expandIcon : Element.Element Basics.Never, collapseIcon : Element.Element Basics.Never }"},{"name":"LayoutStyle","comment":" Technical Remark:\n\n - If icons are defined in Svg, they might not display correctly.\n To avoid that, make sure to wrap them in `Element.html >> Element.el []`\n\n","args":["msg"],"type":"{ container : List.List (Element.Attribute msg), snackbar : Widget.Style.SnackbarStyle msg, layout : List.List (Element.Attribute msg) -> Element.Element msg -> Html.Html msg, header : List.List (Element.Attribute msg), sheet : List.List (Element.Attribute msg), sheetButton : Widget.Style.ButtonStyle msg, menuButton : Widget.Style.ButtonStyle msg, menuTabButton : Widget.Style.ButtonStyle msg, menuIcon : Element.Element Basics.Never, moreVerticalIcon : Element.Element Basics.Never, spacing : Basics.Int, title : List.List (Element.Attribute msg), searchIcon : Element.Element Basics.Never, search : List.List (Element.Attribute msg), searchFill : List.List (Element.Attribute msg) }"},{"name":"RowStyle","comment":" ","args":["msg"],"type":"{ containerRow : List.List (Element.Attribute msg), element : List.List (Element.Attribute msg), ifFirst : List.List (Element.Attribute msg), ifLast : List.List (Element.Attribute msg), otherwise : List.List (Element.Attribute msg) }"},{"name":"SnackbarStyle","comment":" ","args":["msg"],"type":"{ containerRow : List.List (Element.Attribute msg), text : List.List (Element.Attribute msg), button : Widget.Style.ButtonStyle msg }"},{"name":"SortTableStyle","comment":" Technical Remark:\n\n - If icons are defined in Svg, they might not display correctly.\n To avoid that, make sure to wrap them in `Element.html >> Element.el []`\n\n","args":["msg"],"type":"{ containerTable : List.List (Element.Attribute msg), headerButton : Widget.Style.ButtonStyle msg, ascIcon : Element.Element Basics.Never, descIcon : Element.Element Basics.Never, defaultIcon : Element.Element Basics.Never }"},{"name":"TabStyle","comment":" ","args":["msg"],"type":"{ button : Widget.Style.ButtonStyle msg, optionRow : List.List (Element.Attribute msg), containerColumn : List.List (Element.Attribute msg), content : List.List (Element.Attribute msg) }"},{"name":"TextInputStyle","comment":" ","args":["msg"],"type":"{ chipButton : Widget.Style.ButtonStyle msg, containerRow : List.List (Element.Attribute msg), chipsRow : List.List (Element.Attribute msg), input : List.List (Element.Attribute msg) }"}],"values":[],"binops":[]},{"name":"Widget.Style.Material","comment":" ![Example using the Material Design style](https://orasund.github.io/elm-ui-widgets/assets/material-style.png)\n\nThis module implements a Material design theme for all widgets.\n\nThe stylings are following [the official Material Design guidelines](https://material.io/components) as close as possible.\nPlease use these widgets in combination with the official guidelines.\n\nThe typograpahy is taken from [the material design guidelines](https://material.io/design/typography/the-type-system.html#type-scale).\nIts recommended to use a font size of 16px width and the [Roboto Font](https://fonts.google.com/specimen/Roboto?query=Ro).\n\nThe style are not opaque, so you can change every styling to your needs.\n\nIf you have any suggestions or improvements, be sure to leave a PR or a Issue over at the github repos.\n\nYou can use the theme by copying the following code:\n\n```\ntype alias Style msg =\n { dialog : DialogStyle msg\n , expansionPanel : ExpansionPanelStyle msg\n , button : ButtonStyle msg\n , primaryButton : ButtonStyle msg\n , tab : TabStyle msg\n , textInput : TextInputStyle msg\n , chipButton : ButtonStyle msg\n , row : RowStyle msg\n , buttonRow : RowStyle msg\n , column : ColumnStyle msg\n , cardColumn : ColumnStyle msg\n , sortTable : SortTableStyle msg\n , selectButton : ButtonStyle msg\n , layout : LayoutStyle msg\n }\n\nsortTable : Palette -> SortTableStyle msg\nsortTable palette =\n { containerTable = []\n , headerButton = Material.textButton palette\n , ascIcon = Icons.chevronUp |> Element.html |> Element.el []\n , descIcon = Icons.chevronDown |> Element.html |> Element.el []\n , defaultIcon = Element.none\n }\n\n\nstyle : Palette -> Style msg\nstyle palette =\n { sortTable = sortTable palette\n , row = Material.row\n , buttonRow = Material.buttonRow\n , cardColumn = Material.cardColumn palette\n , column = Material.column\n , button = Material.outlinedButton palette\n , primaryButton = Material.containedButton palette\n , selectButton = Material.toggleButton palette\n , tab = Material.tab palette\n , textInput = Material.textInput palette\n , chipButton = Material.chip palette\n , expansionPanel = Material.expansionPanel palette\n , dialog = Material.alertDialog palette\n , layout = Material.layout palette\n }\n```\n\n# Palette\n\n@docs Palette, defaultPalette, darkPalette\n\n\n# Button\n\nDifferent styles for buttons have different meanings.\n\n - Use `textButton` as your default button\n - Use `containedButton` for any important action\n - Use `outlinedButton` if you have more then one important action.\n Use `containedButton` for **the most** important action of the group.\n\n@docs containedButton, outlinedButton, textButton\n\n@docs iconButton, toggleButton, buttonRow\n\n# Card\n\nIn the material design specification the card is not really specified at all.\nIm practice the List seams more useful then a own card widget.\nThus for now we only provide a card containing a list.\n\n@docs cardColumn\n\n# Chip\n\n@docs chip, textInput\n\n# Dialog\n\n@docs alertDialog\n\n\n# Expansion Panel\n\n@docs expansionPanel\n\n\n# List\n\nThe [List widget](https://material.io/components/lists) is a very complex widget that sadly only particially made it into this package.\n\n@docs row, column\n\n# Snackbar\n\n@docs snackbar\n\n# Tab\n\n@docs tab, tabButton\n\n# Layout\n\n@docs layout\n","unions":[],"aliases":[{"name":"Palette","comment":" The material design comes with customizable color palettes.\n\nCheck out [the official documentation about the color system](https://material.io/design/color/the-color-system.html#color-theme-creation) to see how these colors are used.\n\nFor the `-on` colors you can use white, for transitions into white, or black,for transitions into black. Other colors are also possible, but i've not seen any website acutally using a different color.\n\n","args":[],"type":"{ primary : Color.Color, secondary : Color.Color, background : Color.Color, surface : Color.Color, error : Color.Color, on : { primary : Color.Color, secondary : Color.Color, background : Color.Color, surface : Color.Color, error : Color.Color } }"}],"values":[{"name":"alertDialog","comment":" An alert dialog for important decisions. Use a snackbar for less important notification.\n\n![Alert Dialog](https://material.io/develop/images/content/9d61e2d1bd60599344c7fae5e71c9667.png)\n\n_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_\n\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.DialogStyle msg"},{"name":"buttonRow","comment":" a Row of buttons.\n\nOnly use in combination with `toggleButton`\n\n","type":"Widget.Style.RowStyle msg"},{"name":"cardColumn","comment":" A List styled like a card.\n\nTechnical Remark:\n\nThis is a simplification of the [Material Design Card\n](https://material.io/components/cards) and might get replaced at a later date.\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ColumnStyle msg"},{"name":"chip","comment":" Chips have the same behaviour as buttons but are visually less important.\n\nIn the [official documentation](https://material.io/components/chips#types) chips have different names depending on where they are used:\n\n - **Input Chips** are used inside a text field. Use `textInput` for this feature.\n - **Choice Chips** are used for selcting an option.\n The material design guidelines recommend using `toggleButton` for icons with no text and chips for text with no icons.\n - **Filter Chips** are used for selecting multiple options. They typically have a done-icon when selected.\n - **Action chips** are like button. Make sure to include an icon when using action chips.\n\nTechnical Remark:\n\n - There seems to be a bug, where in the mouseOver effects are now visible.\n This might have something to do with .\n This needs to be investigated, but for now i leave it at that.\n\n - Desided against the implementation of an outlined chip.\n Please open a new issue or a PR if you want to have it implemented.\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"},{"name":"column","comment":" A simple styling for a column.\n","type":"Widget.Style.ColumnStyle msg"},{"name":"containedButton","comment":" A contained button representing the most important action of a group.\n\n![Contained Button](https://material.io/develop/images/content/79e62add1830d33fc90edb22212bce53.svg)\n\n_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"},{"name":"darkPalette","comment":" The offical dark theme of google.\n\n![The dark theme](https://lh3.googleusercontent.com/tv7J2o4ZiSmLYwyBslBs_PLzKyzI8QUV5qdvHGfoAQn9r7pY4Hj5SmW27m3zUWeDtRSE8Cb5_5PQmkbavDfw7XbIL8EodIKZhilRdg=w1064-v0)\n\n_Image take from [material.io](https://material.io/design/color/dark-theme.html#ui-application)_\n\n","type":"Widget.Style.Material.Palette"},{"name":"defaultPalette","comment":" The default color theme.\n\n![The default theme](https://lh3.googleusercontent.com/k6WO1fd7T40A9JvSVfHqs0CPLFyTEDCecsVGxEDhOaTP0wUTPYOVVkxt60hKxBprgNoMqs8OyKqtlaQ4tDBtQJs-fTcZrpZEjxhUVQ=w1064-v0)\n\n_Image take from [material.io](https://material.io/design/color/the-color-system.html#color-theme-creation)_\n\n","type":"Widget.Style.Material.Palette"},{"name":"expansionPanel","comment":" The expansion Panel is an outdated part of the material design specification.\nIn modern implementation it gets replaced with a very sophisticated list widget.\n\nTechnical Remarks:\n\n - The expansion panel is part of an [older version](https://material.io/archive/guidelines/components/expansion-panels.html) of the Material Design.\n The newer version is part of the List component.\n The styling is taken from the [new specification](https://material.io/components/lists#specs).\n - The Icons are taken from [danmarcab/material-icons](https://dark.elm.dmy.fr/packages/danmarcab/material-icons/latest/).\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ExpansionPanelStyle msg"},{"name":"iconButton","comment":" An single selectable icon.\n\n![Icon Button](https://material.io/develop/images/content/9bc212d8a3ef79bb7ed83a5359651505.png)\n\n_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_\n\nTechnical Remark:\n\n - Could not find any specification details\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"},{"name":"layout","comment":" The Layout Widget combines the following Material design concepts:\n\n* Top bar\n* Navigation drawer\n* Side Sheet\n* Dialog\n* Snackbar\n\nFuture updates might try to seperate them into there own widgets.\nBut for now they are only available as an all-in-one solution.\n\nTechnical Remark:\n\n - Due to [a bug in Elm-Ui](https://github.com/mdgriffith/elm-ui/issues/47) the menu button still behave wierd.\n I've not found a workaround for it.\n - The Icons are taken from [danmarcab/material-icons](https://dark.elm.dmy.fr/packages/danmarcab/material-icons/latest/).\n - The drawer button as not taken from the specification (This will been to be added later)\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.LayoutStyle msg"},{"name":"outlinedButton","comment":" A outlined button representing an important action within a group.\n\n![Contained Button](https://material.io/develop/images/content/2b50635d38c5fdec260f09be9aeafb10.svg)\n\n_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"},{"name":"row","comment":" A simple styling for a row.\n","type":"Widget.Style.RowStyle msg"},{"name":"snackbar","comment":" A typical snackbar\n\n![Snackbar](https://material.io/develop/images/content/f2ec5451582a06af5eb20e3dfb3d27d5.svg)\n\n_Image take from [material.io](https://material.io/develop/android/components/snackbar/)_\n\nTechnical Remark:\n\n - The text color of the button was not given in the specification. This implementation\n adujsts the luminance of the color to fit the [w3 accessability standard](https://www.w3.org/TR/WCAG20/#Contrast)\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.SnackbarStyle msg"},{"name":"tab","comment":" A Tab bar meant for only the upper most level. Do not use a tab within a tab.\n","type":"Widget.Style.Material.Palette -> Widget.Style.TabStyle msg"},{"name":"tabButton","comment":" A single Tab button.\n\nTechnical Remark:\n\n* The official specification states that the background color should be the surface color,\n but the pictures and actuall implementations all have no background color.\n So here the background color is also not set.\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"},{"name":"textButton","comment":" A text button representing a simple action within a group.\n\n![Text Button](https://material.io/develop/images/content/d3079632c6f54d86f9b7093d541c2ee9.svg)\n\n_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"},{"name":"textInput","comment":" A text input style that is included only to support input chips.\n\nTechnical Remark:\n\n - This is just a temporary implementation. It will soon be replaced with the official implementation.\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.TextInputStyle msg"},{"name":"toggleButton","comment":" A ToggleButton. Only use as a group in combination with `buttonRow`.\n\n![Toggle Button](https://material.io/develop/images/content/749a1ba8591d02356fa1d6eea2641d96.svg)\n\n_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_\n\nToggle buttons should only be used with the `iconButton` widget, else use chips instead.\n\nTechnical Remark:\n\n - Border color was not defined in the [specification](https://material.io/components/buttons#toggle-button)\n - There are two different versions, one where the selected color is gray and another where the color is primary.\n I noticed the gray version was used more often, so i went with that one.\n\n","type":"Widget.Style.Material.Palette -> Widget.Style.ButtonStyle msg"}],"binops":[]},{"name":"Widget.Style.Template","comment":" ![Example using the Template style](https://orasund.github.io/elm-ui-widgets/assets/template-style.png)\n\nThis package contains mockups designed for writing your own style.\n\nStart by copying the following code and then replace the fields one by one.\n\n```\ntype alias Style msg =\n { dialog : DialogStyle msg\n , expansionPanel : ExpansionPanelStyle msg\n , button : ButtonStyle msg\n , primaryButton : ButtonStyle msg\n , tab : TabStyle msg\n , textInput : TextInputStyle msg\n , chipButton : ButtonStyle msg\n , row : RowStyle msg\n , buttonRow : RowStyle msg\n , column : ColumnStyle msg\n , cardColumn : ColumnStyle msg\n , sortTable : SortTableStyle msg\n , selectButton : ButtonStyle msg\n , layout : LayoutStyle msg\n }\n\nstyle : Style msg\nstyle =\n { sortTable = Template.sortTable <| \"sortTable\"\n , row = Template.row <| \"row\"\n , buttonRow = Template.row <| \"buttonRow\"\n , cardColumn = Template.column <| \"cardRow\"\n , column = Template.column <| \"column\"\n , button = Template.button <| \"button\"\n , primaryButton = Template.button <| \"primaryButton\"\n , tab = Template.tab <| \"tab\"\n , textInput = Template.textInput <| \"textInput\"\n , chipButton = Template.button <| \"chipButton\"\n , expansionPanel = Template.expansionPanel \"expansionPanel\"\n , selectButton = Template.button \"selectButton\"\n , dialog = Template.dialog \"dialog\"\n , layout = Template.layout \"layout\"\n }\n```\n\n\n# Base Elements\n\n@docs box, decoration, icon\n\n\n# Mockups\n\n@docs button, column, dialog, expansionPanel, layout, row, snackbar, sortTable, tab, textInput\n\n","unions":[],"aliases":[],"values":[{"name":"box","comment":" A box representing an element\n","type":"String.String -> List.List (Element.Attribute msg)"},{"name":"button","comment":"\n\n```\nbutton : String -> ButtonStyle msg\nbutton string =\n { container = box <| string ++ \":container\"\n , labelRow = box <| string ++ \":labelRow\"\n , text = box <| string ++ \":text\"\n , ifDisabled = decoration <| string ++ \":ifDisabled\"\n , ifActive = decoration <| string ++ \":ifActive\"\n , otherwise = decoration <| string ++ \":otherwise\"\n }\n```\n\n","type":"String.String -> Widget.Style.ButtonStyle msg"},{"name":"column","comment":"\n\n```\ncolumn : String -> ColumnStyle msg\ncolumn string =\n { containerColumn = box <| string ++ \":containerColumn\"\n , element = box <| string ++ \":element\"\n , ifFirst = box <| string ++ \":ifFirst\"\n , ifLast = box <| string ++ \":ifLast\"\n , otherwise = box <| string ++ \":otherwise\"\n }\n```\n\n","type":"String.String -> Widget.Style.ColumnStyle msg"},{"name":"decoration","comment":" An additional attribute representing a state change.\n","type":"String.String -> List.List (Element.Attribute msg)"},{"name":"dialog","comment":"\n\n```\ndialog : String -> DialogStyle msg\ndialog string =\n { containerColumn = box <| string ++ \":containerColumn\"\n , title = box <| string ++ \":title\"\n , text = box <| string ++ \":text\"\n , buttonRow = box <| string ++ \":buttonRow\"\n , acceptButton = button <| string ++ \":acceptButton\"\n , dismissButton = button <| string ++ \":dismissButton\"\n }\n```\n\n","type":"String.String -> Widget.Style.DialogStyle msg"},{"name":"expansionPanel","comment":"\n\n```\nexpansionPanel : String -> ExpansionPanelStyle msg\nexpansionPanel string =\n { containerColumn = box <| string ++ \":containerColumn\"\n , panelRow = box <| string ++ \":panelRow\"\n , labelRow = box <| string ++ \":labelRow\"\n , content = box <| string ++ \":content\"\n , expandIcon = icon <| string ++ \":expandIcon\"\n , collapseIcon = icon <| string ++ \":collapseIcon\"\n }\n\n```\n\n","type":"String.String -> Widget.Style.ExpansionPanelStyle msg"},{"name":"icon","comment":" A circle representing an icon\n","type":"String.String -> Element.Element msg"},{"name":"layout","comment":"\n\n```\nlayout : String -> LayoutStyle msg\nlayout string =\n { container = box <| string ++ \":container\"\n , snackbar = snackbar <| string ++ \":snackbar\"\n , layout = Element.layout\n , header = box <| string ++ \":header\"\n , menuButton = button <| string ++ \":menuButton\"\n , sheetButton = button <| string ++ \":sheetButton\"\n , menuTabButton = button <| string ++ \":menuTabButton\"\n , sheet = box <| string ++ \":sheet\"\n , menuIcon = icon <| string ++ \":menuIcon\"\n , moreVerticalIcon = icon <| string ++ \":moreVerticalIcon\"\n , spacing = 8\n , title = box <| string ++ \":title\"\n , searchIcon = icon <| string ++ \":searchIcon\"\n , search = box <| string ++ \":search\"\n , searchFill = box <| string ++ \":searchFill\"\n }\n```\n\n","type":"String.String -> Widget.Style.LayoutStyle msg"},{"name":"row","comment":"\n\n```\nrow : String -> RowStyle msg\nrow string =\n { containerRow = box <| string ++ \":containerRow\"\n , element = box <| string ++ \":element\"\n , ifFirst = box <| string ++ \":ifFirst\"\n , ifLast = box <| string ++ \":ifLast\"\n , otherwise = box <| string ++ \":otherwise\"\n }\n```\n\n","type":"String.String -> Widget.Style.RowStyle msg"},{"name":"snackbar","comment":"\n\n```\nsnackbar : String -> SnackbarStyle msg\nsnackbar string =\n { containerRow = box <| string ++ \":containerRow\"\n , button = button <| string ++ \":button\"\n , text = box <| string ++ \":text\"\n }\n```\n\n","type":"String.String -> Widget.Style.SnackbarStyle msg"},{"name":"sortTable","comment":"\n\n```\nsortTable : String -> SortTableStyle msg\nsortTable string =\n { containerTable = box <| string ++ \":containerTable\"\n , headerButton = button <| string ++ \":headerButton\"\n , ascIcon = icon <| string ++ \":ascIcon\"\n , descIcon = icon <| string ++ \":descIcon\"\n , defaultIcon = icon <| string ++ \":defaultIcon\"\n }\n```\n\n","type":"String.String -> Widget.Style.SortTableStyle msg"},{"name":"tab","comment":"\n\n```\ntab : String -> TabStyle msg\ntab string =\n { button = button <| string ++ \":button\"\n , optionRow = box <| string ++ \":optionRow\"\n , containerColumn = box <| string ++ \":containerColumn\"\n , content = box <| string ++ \":content\"\n }\n```\n\n","type":"String.String -> Widget.Style.TabStyle msg"},{"name":"textInput","comment":"\n\n```\ntextInput : String -> TextInputStyle msg\ntextInput string =\n { chipButton = button <| string ++ \":chipButton\"\n , chipsRow = box <| string ++ \":chipsRow\"\n , containerRow = box <| string ++ \":containerRow\"\n , input = box <| string ++ \":input\"\n }\n\n```\n\n","type":"String.String -> Widget.Style.TextInputStyle msg"}],"binops":[]}] \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index fefb9a7..e757add 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,7 +2,7 @@ - Example + Main @@ -5241,26 +5241,23 @@ var $elm$core$Task$perform = F2( A2($elm$core$Task$map, toMessage, task))); }); var $elm$browser$Browser$element = _Browser_element; -var $author$project$Example$GotViewport = function (a) { +var $author$project$Main$GotViewport = function (a) { return {$: 'GotViewport', a: a}; }; -var $author$project$Example$Loading = {$: 'Loading'}; +var $author$project$Main$Loading = {$: 'Loading'}; var $elm$browser$Browser$Dom$getViewport = _Browser_withWindow(_Browser_getViewport); -var $author$project$Example$init = function (_v0) { +var $author$project$Main$init = function (_v0) { return _Utils_Tuple2( - $author$project$Example$Loading, - A2($elm$core$Task$perform, $author$project$Example$GotViewport, $elm$browser$Browser$Dom$getViewport)); + $author$project$Main$Loading, + A2($elm$core$Task$perform, $author$project$Main$GotViewport, $elm$browser$Browser$Dom$getViewport)); }; -var $author$project$Example$LoadedSpecific = function (a) { +var $author$project$Main$LoadedSpecific = function (a) { return {$: 'LoadedSpecific', a: a}; }; -var $author$project$Example$Resized = function (a) { +var $author$project$Main$Resized = function (a) { return {$: 'Resized', a: a}; }; -var $author$project$Example$ScrollingNavSpecific = function (a) { - return {$: 'ScrollingNavSpecific', a: a}; -}; -var $author$project$Example$TimePassed = function (a) { +var $author$project$Main$TimePassed = function (a) { return {$: 'TimePassed', a: a}; }; var $elm$core$Basics$always = F2( @@ -5901,130 +5898,266 @@ var $elm$browser$Browser$Events$onResize = function (func) { A2($elm$json$Json$Decode$field, 'innerWidth', $elm$json$Json$Decode$int), A2($elm$json$Json$Decode$field, 'innerHeight', $elm$json$Json$Decode$int)))); }; -var $author$project$Widget$ScrollingNav$TimePassed = {$: 'TimePassed'}; -var $author$project$Widget$ScrollingNav$subscriptions = A2( - $elm$time$Time$every, - 100, - $elm$core$Basics$always($author$project$Widget$ScrollingNav$TimePassed)); -var $author$project$Example$subscriptions = function (model) { +var $author$project$Main$subscriptions = function (_v0) { return A2( $elm$core$Platform$Sub$map, - $author$project$Example$LoadedSpecific, + $author$project$Main$LoadedSpecific, $elm$core$Platform$Sub$batch( _List_fromArray( [ - A2($elm$core$Platform$Sub$map, $author$project$Example$ScrollingNavSpecific, $author$project$Widget$ScrollingNav$subscriptions), A2( $elm$time$Time$every, 50, $elm$core$Basics$always( - $author$project$Example$TimePassed(50))), + $author$project$Main$TimePassed(50))), $elm$browser$Browser$Events$onResize( F2( function (h, w) { - return $author$project$Example$Resized( + return $author$project$Main$Resized( {height: h, width: w}); })) ]))); }; -var $author$project$Example$Loaded = function (a) { +var $author$project$Main$Loaded = function (a) { return {$: 'Loaded', a: a}; }; -var $author$project$Data$Section$ComponentViews = {$: 'ComponentViews'}; -var $author$project$Data$Section$ReusableViews = {$: 'ReusableViews'}; -var $author$project$Data$Section$StatelessViews = {$: 'StatelessViews'}; -var $author$project$Data$Section$asList = _List_fromArray( - [$author$project$Data$Section$StatelessViews, $author$project$Data$Section$ReusableViews, $author$project$Data$Section$ComponentViews]); -var $mdgriffith$elm_ui$Element$BigDesktop = {$: 'BigDesktop'}; -var $mdgriffith$elm_ui$Element$Desktop = {$: 'Desktop'}; -var $mdgriffith$elm_ui$Element$Landscape = {$: 'Landscape'}; -var $mdgriffith$elm_ui$Element$Phone = {$: 'Phone'}; -var $mdgriffith$elm_ui$Element$Portrait = {$: 'Portrait'}; -var $mdgriffith$elm_ui$Element$Tablet = {$: 'Tablet'}; -var $elm$core$Basics$min = F2( - function (x, y) { - return (_Utils_cmp(x, y) < 0) ? x : y; - }); -var $mdgriffith$elm_ui$Element$classifyDevice = function (window) { - return { - _class: function () { - var shortSide = A2($elm$core$Basics$min, window.width, window.height); - var longSide = A2($elm$core$Basics$max, window.width, window.height); - return (shortSide < 600) ? $mdgriffith$elm_ui$Element$Phone : ((longSide <= 1200) ? $mdgriffith$elm_ui$Element$Tablet : (((longSide > 1200) && (longSide <= 1920)) ? $mdgriffith$elm_ui$Element$Desktop : $mdgriffith$elm_ui$Element$BigDesktop)); - }(), - orientation: (_Utils_cmp(window.width, window.height) < 0) ? $mdgriffith$elm_ui$Element$Portrait : $mdgriffith$elm_ui$Element$Landscape - }; +var $author$project$Main$Idle = {$: 'Idle'}; +var $author$project$Data$Theme$Material = {$: 'Material'}; +var $author$project$Main$StatelessSpecific = function (a) { + return {$: 'StatelessSpecific', a: a}; +}; +var $author$project$Main$UpdateScrollingNav = function (a) { + return {$: 'UpdateScrollingNav', a: a}; +}; +var $author$project$Data$Example$ButtonExample = {$: 'ButtonExample'}; +var $author$project$Data$Example$DialogExample = {$: 'DialogExample'}; +var $author$project$Data$Example$ExpansionPanelExample = {$: 'ExpansionPanelExample'}; +var $author$project$Data$Example$ListExample = {$: 'ListExample'}; +var $author$project$Data$Example$ModalExample = {$: 'ModalExample'}; +var $author$project$Data$Example$MultiSelectExample = {$: 'MultiSelectExample'}; +var $author$project$Data$Example$SelectExample = {$: 'SelectExample'}; +var $author$project$Data$Example$SortTableExample = {$: 'SortTableExample'}; +var $author$project$Data$Example$TabExample = {$: 'TabExample'}; +var $author$project$Data$Example$TextInputExample = {$: 'TextInputExample'}; +var $elm$core$List$sortBy = _List_sortBy; +var $author$project$Data$Example$toString = function (example) { + switch (example.$) { + case 'ButtonExample': + return 'Button'; + case 'SelectExample': + return 'Select'; + case 'MultiSelectExample': + return 'Multi Select'; + case 'ExpansionPanelExample': + return 'ExpansionPanel'; + case 'TabExample': + return 'Tab'; + case 'SortTableExample': + return 'SortTable'; + case 'ModalExample': + return 'Modal'; + case 'DialogExample': + return 'Dialog'; + case 'TextInputExample': + return 'TextInput'; + default: + return 'List'; + } +}; +var $author$project$Data$Example$asList = A2( + $elm$core$List$sortBy, + $author$project$Data$Example$toString, + _List_fromArray( + [$author$project$Data$Example$ButtonExample, $author$project$Data$Example$SelectExample, $author$project$Data$Example$MultiSelectExample, $author$project$Data$Example$ExpansionPanelExample, $author$project$Data$Example$TabExample, $author$project$Data$Example$SortTableExample, $author$project$Data$Example$ModalExample, $author$project$Data$Example$DialogExample, $author$project$Data$Example$TextInputExample, $author$project$Data$Example$ListExample])); +var $elm$core$Platform$Cmd$batch = _Platform_batch; +var $turboMaCk$any_set$Set$Any$AnySet = function (a) { + return {$: 'AnySet', a: a}; +}; +var $turboMaCk$any_dict$Dict$Any$AnyDict = function (a) { + return {$: 'AnyDict', a: a}; +}; +var $turboMaCk$any_dict$Dict$Any$empty = function (toKey) { + return $turboMaCk$any_dict$Dict$Any$AnyDict( + {dict: $elm$core$Dict$empty, toKey: toKey}); +}; +var $turboMaCk$any_set$Set$Any$empty = A2($elm$core$Basics$composeL, $turboMaCk$any_set$Set$Any$AnySet, $turboMaCk$any_dict$Dict$Any$empty); +var $author$project$Data$Example$fromString = function (string) { + switch (string) { + case 'Button': + return $elm$core$Maybe$Just($author$project$Data$Example$ButtonExample); + case 'Select': + return $elm$core$Maybe$Just($author$project$Data$Example$SelectExample); + case 'Multi Select': + return $elm$core$Maybe$Just($author$project$Data$Example$MultiSelectExample); + case 'ExpansionPanel': + return $elm$core$Maybe$Just($author$project$Data$Example$ExpansionPanelExample); + case 'Tab': + return $elm$core$Maybe$Just($author$project$Data$Example$TabExample); + case 'SortTable': + return $elm$core$Maybe$Just($author$project$Data$Example$SortTableExample); + case 'Modal': + return $elm$core$Maybe$Just($author$project$Data$Example$ModalExample); + case 'Dialog': + return $elm$core$Maybe$Just($author$project$Data$Example$DialogExample); + case 'TextInput': + return $elm$core$Maybe$Just($author$project$Data$Example$TextInputExample); + case 'List': + return $elm$core$Maybe$Just($author$project$Data$Example$ListExample); + default: + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Stateless$ExampleSpecific = function (a) { + return {$: 'ExampleSpecific', a: a}; +}; +var $author$project$Data$Example$Button = function (a) { + return {$: 'Button', a: a}; +}; +var $author$project$Data$Example$Dialog = function (a) { + return {$: 'Dialog', a: a}; +}; +var $author$project$Data$Example$ExpansionPanel = function (a) { + return {$: 'ExpansionPanel', a: a}; +}; +var $author$project$Data$Example$List = function (a) { + return {$: 'List', a: a}; +}; +var $author$project$Data$Example$Modal = function (a) { + return {$: 'Modal', a: a}; +}; +var $author$project$Data$Example$MultiSelect = function (a) { + return {$: 'MultiSelect', a: a}; +}; +var $author$project$Data$Example$Select = function (a) { + return {$: 'Select', a: a}; +}; +var $author$project$Data$Example$SortTable = function (a) { + return {$: 'SortTable', a: a}; +}; +var $author$project$Data$Example$Tab = function (a) { + return {$: 'Tab', a: a}; +}; +var $author$project$Data$Example$TextInput = function (a) { + return {$: 'TextInput', a: a}; +}; +var $author$project$Example$Button$IsButtonEnabled = function (a) { + return {$: 'IsButtonEnabled', a: a}; +}; +var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); +var $author$project$Example$Button$init = _Utils_Tuple2( + $author$project$Example$Button$IsButtonEnabled(true), + $elm$core$Platform$Cmd$none); +var $author$project$Example$Dialog$IsOpen = function (a) { + return {$: 'IsOpen', a: a}; +}; +var $author$project$Example$Dialog$init = _Utils_Tuple2( + $author$project$Example$Dialog$IsOpen(true), + $elm$core$Platform$Cmd$none); +var $author$project$Example$ExpansionPanel$IsExpanded = function (a) { + return {$: 'IsExpanded', a: a}; +}; +var $author$project$Example$ExpansionPanel$init = _Utils_Tuple2( + $author$project$Example$ExpansionPanel$IsExpanded(false), + $elm$core$Platform$Cmd$none); +var $author$project$Example$List$init = _Utils_Tuple2(_Utils_Tuple0, $elm$core$Platform$Cmd$none); +var $author$project$Example$Modal$IsEnabled = function (a) { + return {$: 'IsEnabled', a: a}; +}; +var $author$project$Example$Modal$init = _Utils_Tuple2( + $author$project$Example$Modal$IsEnabled(true), + $elm$core$Platform$Cmd$none); +var $author$project$Example$MultiSelect$Selected = function (a) { + return {$: 'Selected', a: a}; }; var $elm$core$Set$Set_elm_builtin = function (a) { return {$: 'Set_elm_builtin', a: a}; }; var $elm$core$Set$empty = $elm$core$Set$Set_elm_builtin($elm$core$Dict$empty); -var $elm$core$Set$insert = F2( - function (key, _v0) { - var dict = _v0.a; - return $elm$core$Set$Set_elm_builtin( - A3($elm$core$Dict$insert, key, _Utils_Tuple0, dict)); - }); -var $elm$core$Set$fromList = function (list) { - return A3($elm$core$List$foldl, $elm$core$Set$insert, $elm$core$Set$empty, list); +var $author$project$Example$MultiSelect$init = _Utils_Tuple2( + $author$project$Example$MultiSelect$Selected($elm$core$Set$empty), + $elm$core$Platform$Cmd$none); +var $author$project$Example$Select$Selected = function (a) { + return {$: 'Selected', a: a}; }; -var $author$project$Widget$FilterSelect$init = function (options) { - return {options: options, raw: '', selected: $elm$core$Maybe$Nothing}; +var $author$project$Example$Select$init = _Utils_Tuple2( + $author$project$Example$Select$Selected($elm$core$Maybe$Nothing), + $elm$core$Platform$Cmd$none); +var $author$project$Example$SortTable$init = _Utils_Tuple2( + {asc: true, title: 'Name'}, + $elm$core$Platform$Cmd$none); +var $author$project$Example$Tab$Selected = function (a) { + return {$: 'Selected', a: a}; }; -var $author$project$Widget$ValidatedInput$Model = function (a) { - return {$: 'Model', a: a}; -}; -var $author$project$Widget$ValidatedInput$init = function (_v0) { - var validator = _v0.validator; - var toString = _v0.toString; - var value = _v0.value; - return $author$project$Widget$ValidatedInput$Model( - {err: $elm$core$Maybe$Nothing, raw: $elm$core$Maybe$Nothing, toString: toString, validator: validator, value: value}); -}; -var $author$project$Component$init = { - filterSelect: $author$project$Widget$FilterSelect$init( - $elm$core$Set$fromList( +var $author$project$Example$Tab$init = _Utils_Tuple2( + $author$project$Example$Tab$Selected($elm$core$Maybe$Nothing), + $elm$core$Platform$Cmd$none); +var $author$project$Example$TextInput$init = _Utils_Tuple2( + {chipTextInput: $elm$core$Set$empty, textInput: ''}, + $elm$core$Platform$Cmd$none); +var $elm$core$Platform$Cmd$map = _Platform_map; +var $author$project$Data$Example$init = function () { + var _v0 = $author$project$Example$TextInput$init; + var textInputModel = _v0.a; + var textInputMsg = _v0.b; + var _v1 = $author$project$Example$Tab$init; + var tabModel = _v1.a; + var tabMsg = _v1.b; + var _v2 = $author$project$Example$SortTable$init; + var sortTableModel = _v2.a; + var sortTableMsg = _v2.b; + var _v3 = $author$project$Example$Select$init; + var selectModel = _v3.a; + var selectMsg = _v3.b; + var _v4 = $author$project$Example$MultiSelect$init; + var multiSelectModel = _v4.a; + var multiSelectMsg = _v4.b; + var _v5 = $author$project$Example$Modal$init; + var modalModel = _v5.a; + var modalMsg = _v5.b; + var _v6 = $author$project$Example$List$init; + var listModel = _v6.a; + var listMsg = _v6.b; + var _v7 = $author$project$Example$ExpansionPanel$init; + var expansionPanelModel = _v7.a; + var expansionPanelMsg = _v7.b; + var _v8 = $author$project$Example$Dialog$init; + var dialogModel = _v8.a; + var dialogMsg = _v8.b; + var _v9 = $author$project$Example$Button$init; + var buttonModel = _v9.a; + var buttonMsg = _v9.b; + return _Utils_Tuple2( + {button: buttonModel, dialog: dialogModel, expansionPanel: expansionPanelModel, list: listModel, modal: modalModel, multiSelect: multiSelectModel, select: selectModel, sortTable: sortTableModel, tab: tabModel, textInput: textInputModel}, + $elm$core$Platform$Cmd$batch( _List_fromArray( - ['Apple', 'Kiwi', 'Strawberry', 'Pineapple', 'Mango', 'Grapes', 'Watermelon', 'Orange', 'Lemon', 'Blueberry', 'Grapefruit', 'Coconut', 'Cherry', 'Banana']))), - validatedInput: $author$project$Widget$ValidatedInput$init( - { - toString: function (_v0) { - var first = _v0.a; - var second = _v0.b; - return first + (' ' + second); - }, - validator: function (string) { - var _v1 = A2($elm$core$String$split, ' ', string); - if ((_v1.b && _v1.b.b) && (!_v1.b.b.b)) { - var first = _v1.a; - var _v2 = _v1.b; - var second = _v2.a; - return $elm$core$Result$Ok( - _Utils_Tuple2(first, second)); - } else { - return $elm$core$Result$Err(_Utils_Tuple0); - } - }, - value: _Utils_Tuple2('John', 'Doe') - }) -}; + [ + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$Button, buttonMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$Select, selectMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$MultiSelect, multiSelectMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$ExpansionPanel, expansionPanelMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$Tab, tabMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$SortTable, sortTableMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$Modal, modalMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$Dialog, dialogMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$TextInput, textInputMsg), + A2($elm$core$Platform$Cmd$map, $author$project$Data$Example$List, listMsg) + ]))); +}(); +var $author$project$Stateless$init = function () { + var _v0 = $author$project$Data$Example$init; + var example = _v0.a; + var cmd = _v0.b; + return _Utils_Tuple2( + {carousel: 0, example: example}, + A2($elm$core$Platform$Cmd$map, $author$project$Stateless$ExampleSpecific, cmd)); +}(); var $turboMaCk$queue$Queue$Queue = F2( function (a, b) { return {$: 'Queue', a: a, b: b}; }); var $turboMaCk$queue$Queue$empty = A2($turboMaCk$queue$Queue$Queue, _List_Nil, _List_Nil); var $author$project$Widget$Snackbar$init = {current: $elm$core$Maybe$Nothing, queue: $turboMaCk$queue$Queue$empty}; -var $author$project$Layout$init = {sheet: $elm$core$Maybe$Nothing, snackbar: $author$project$Widget$Snackbar$init}; -var $author$project$Widget$SortTable$sortBy = $elm$core$Basics$identity; -var $author$project$Reusable$init = $author$project$Widget$SortTable$sortBy( - {asc: true, title: 'Name'}); -var $author$project$Stateless$init = {carousel: 0, isCollapsed: false, multiSelected: $elm$core$Set$empty, selected: $elm$core$Maybe$Nothing, tab: 1}; -var $elm_community$intdict$IntDict$Empty = {$: 'Empty'}; -var $elm_community$intdict$IntDict$empty = $elm_community$intdict$IntDict$Empty; -var $author$project$Widget$ScrollingNav$GotHeaderPos = F2( - function (a, b) { - return {$: 'GotHeaderPos', a: a, b: b}; - }); +var $author$project$Widget$Layout$init = {active: $elm$core$Maybe$Nothing, snackbar: $author$project$Widget$Snackbar$init}; var $elm$core$Task$onError = _Scheduler_onError; var $elm$core$Task$attempt = F2( function (resultToMessage, task) { @@ -6044,84 +6177,262 @@ var $elm$core$Task$attempt = F2( $elm$core$Result$Ok), task)))); }); -var $elm$core$Platform$Cmd$batch = _Platform_batch; +var $elm_community$intdict$IntDict$Empty = {$: 'Empty'}; +var $elm_community$intdict$IntDict$empty = $elm_community$intdict$IntDict$Empty; +var $elm$browser$Browser$Dom$getElement = _Browser_getElement; +var $elm_community$intdict$IntDict$Inner = function (a) { + return {$: 'Inner', a: a}; +}; +var $elm_community$intdict$IntDict$size = function (dict) { + switch (dict.$) { + case 'Empty': + return 0; + case 'Leaf': + return 1; + default: + var i = dict.a; + return i.size; + } +}; +var $elm_community$intdict$IntDict$inner = F3( + function (p, l, r) { + var _v0 = _Utils_Tuple2(l, r); + if (_v0.a.$ === 'Empty') { + var _v1 = _v0.a; + return r; + } else { + if (_v0.b.$ === 'Empty') { + var _v2 = _v0.b; + return l; + } else { + return $elm_community$intdict$IntDict$Inner( + { + left: l, + prefix: p, + right: r, + size: $elm_community$intdict$IntDict$size(l) + $elm_community$intdict$IntDict$size(r) + }); + } + } + }); +var $elm$core$Bitwise$and = _Bitwise_and; var $elm$core$Basics$composeR = F3( function (f, g, x) { return g( f(x)); }); -var $elm$browser$Browser$Dom$getElement = _Browser_getElement; +var $elm$core$Basics$neq = _Utils_notEqual; +var $elm$core$Bitwise$complement = _Bitwise_complement; +var $elm$core$Bitwise$or = _Bitwise_or; +var $elm$core$Bitwise$shiftRightZfBy = _Bitwise_shiftRightZfBy; +var $elm_community$intdict$IntDict$highestBitSet = function (n) { + var shiftOr = F2( + function (i, shift) { + return i | (i >>> shift); + }); + var n1 = A2(shiftOr, n, 1); + var n2 = A2(shiftOr, n1, 2); + var n3 = A2(shiftOr, n2, 4); + var n4 = A2(shiftOr, n3, 8); + var n5 = A2(shiftOr, n4, 16); + return n5 & (~(n5 >>> 1)); +}; +var $elm$core$Basics$negate = function (n) { + return -n; +}; +var $elm_community$intdict$IntDict$signBit = $elm_community$intdict$IntDict$highestBitSet(-1); +var $elm$core$Bitwise$xor = _Bitwise_xor; +var $elm_community$intdict$IntDict$isBranchingBitSet = function (p) { + return A2( + $elm$core$Basics$composeR, + $elm$core$Bitwise$xor($elm_community$intdict$IntDict$signBit), + A2( + $elm$core$Basics$composeR, + $elm$core$Bitwise$and(p.branchingBit), + $elm$core$Basics$neq(0))); +}; +var $elm_community$intdict$IntDict$higherBitMask = function (branchingBit) { + return branchingBit ^ (~(branchingBit - 1)); +}; +var $elm_community$intdict$IntDict$lcp = F2( + function (x, y) { + var branchingBit = $elm_community$intdict$IntDict$highestBitSet(x ^ y); + var mask = $elm_community$intdict$IntDict$higherBitMask(branchingBit); + var prefixBits = x & mask; + return {branchingBit: branchingBit, prefixBits: prefixBits}; + }); +var $elm_community$intdict$IntDict$Leaf = function (a) { + return {$: 'Leaf', a: a}; +}; +var $elm_community$intdict$IntDict$leaf = F2( + function (k, v) { + return $elm_community$intdict$IntDict$Leaf( + {key: k, value: v}); + }); +var $elm_community$intdict$IntDict$prefixMatches = F2( + function (p, n) { + return _Utils_eq( + n & $elm_community$intdict$IntDict$higherBitMask(p.branchingBit), + p.prefixBits); + }); +var $elm_community$intdict$IntDict$update = F3( + function (key, alter, dict) { + var join = F2( + function (_v2, _v3) { + var k1 = _v2.a; + var l = _v2.b; + var k2 = _v3.a; + var r = _v3.b; + var prefix = A2($elm_community$intdict$IntDict$lcp, k1, k2); + return A2($elm_community$intdict$IntDict$isBranchingBitSet, prefix, k2) ? A3($elm_community$intdict$IntDict$inner, prefix, l, r) : A3($elm_community$intdict$IntDict$inner, prefix, r, l); + }); + var alteredNode = function (mv) { + var _v1 = alter(mv); + if (_v1.$ === 'Just') { + var v = _v1.a; + return A2($elm_community$intdict$IntDict$leaf, key, v); + } else { + return $elm_community$intdict$IntDict$empty; + } + }; + switch (dict.$) { + case 'Empty': + return alteredNode($elm$core$Maybe$Nothing); + case 'Leaf': + var l = dict.a; + return _Utils_eq(l.key, key) ? alteredNode( + $elm$core$Maybe$Just(l.value)) : A2( + join, + _Utils_Tuple2( + key, + alteredNode($elm$core$Maybe$Nothing)), + _Utils_Tuple2(l.key, dict)); + default: + var i = dict.a; + return A2($elm_community$intdict$IntDict$prefixMatches, i.prefix, key) ? (A2($elm_community$intdict$IntDict$isBranchingBitSet, i.prefix, key) ? A3( + $elm_community$intdict$IntDict$inner, + i.prefix, + i.left, + A3($elm_community$intdict$IntDict$update, key, alter, i.right)) : A3( + $elm_community$intdict$IntDict$inner, + i.prefix, + A3($elm_community$intdict$IntDict$update, key, alter, i.left), + i.right)) : A2( + join, + _Utils_Tuple2( + key, + alteredNode($elm$core$Maybe$Nothing)), + _Utils_Tuple2(i.prefix.prefixBits, dict)); + } + }); +var $elm_community$intdict$IntDict$insert = F3( + function (key, value, dict) { + return A3( + $elm_community$intdict$IntDict$update, + key, + $elm$core$Basics$always( + $elm$core$Maybe$Just(value)), + dict); + }); var $elm$core$Basics$round = _Basics_round; var $author$project$Widget$ScrollingNav$syncPositions = function (_v0) { - var labels = _v0.labels; + var toString = _v0.toString; var arrangement = _v0.arrangement; - return $elm$core$Platform$Cmd$batch( - A2( - $elm$core$List$map, - function (label) { - return A2( - $elm$core$Task$attempt, - $author$project$Widget$ScrollingNav$GotHeaderPos(label), - A2( + return A2( + $elm$core$Task$map, + F2( + function (list, m) { + return A3( + $elm$core$List$foldl, + F2( + function (_v1, model) { + var pos = _v1.a; + var label = _v1.b; + return _Utils_update( + model, + { + positions: A3( + $elm_community$intdict$IntDict$insert, + pos, + model.toString(label), + model.positions) + }); + }), + m, + list); + }), + $elm$core$Task$sequence( + A2( + $elm$core$List$map, + function (label) { + return A2( $elm$core$Task$map, - A2( - $elm$core$Basics$composeR, - function ($) { - return $.element; - }, - A2( - $elm$core$Basics$composeR, - function ($) { - return $.y; - }, - $elm$core$Basics$round)), + function (x) { + return _Utils_Tuple2( + $elm$core$Basics$round(x.element.y), + label); + }, $elm$browser$Browser$Dom$getElement( - labels(label)))); - }, - arrangement)); + toString(label))); + }, + arrangement))); }; var $author$project$Widget$ScrollingNav$init = function (_v0) { - var labels = _v0.labels; + var toString = _v0.toString; + var fromString = _v0.fromString; var arrangement = _v0.arrangement; + var toMsg = _v0.toMsg; return function (a) { return _Utils_Tuple2( a, - $author$project$Widget$ScrollingNav$syncPositions(a)); + A2( + $elm$core$Task$attempt, + toMsg, + $author$project$Widget$ScrollingNav$syncPositions(a))); }( - {arrangement: arrangement, labels: labels, positions: $elm_community$intdict$IntDict$empty, scrollPos: 0}); + {arrangement: arrangement, fromString: fromString, positions: $elm_community$intdict$IntDict$empty, scrollPos: 0, toString: toString}); }; -var $elm$core$Platform$Cmd$map = _Platform_map; -var $author$project$Data$Section$toString = function (section) { - switch (section.$) { - case 'ComponentViews': - return 'Component'; - case 'ReusableViews': - return 'Reusable'; - default: - return 'Stateless'; - } -}; -var $author$project$Example$initialModel = function (_v0) { +var $author$project$Main$initialModel = function (_v0) { var viewport = _v0.viewport; - var _v1 = $author$project$Widget$ScrollingNav$init( - {arrangement: $author$project$Data$Section$asList, labels: $author$project$Data$Section$toString}); - var scrollingNav = _v1.a; - var cmd = _v1.b; + var _v1 = $author$project$Stateless$init; + var stateless = _v1.a; + var statelessCmd = _v1.b; + var _v2 = $author$project$Widget$ScrollingNav$init( + { + arrangement: $author$project$Data$Example$asList, + fromString: $author$project$Data$Example$fromString, + toMsg: function (result) { + if (result.$ === 'Ok') { + var fun = result.a; + return $author$project$Main$UpdateScrollingNav(fun); + } else { + return $author$project$Main$Idle; + } + }, + toString: $author$project$Data$Example$toString + }); + var scrollingNav = _v2.a; + var cmd = _v2.b; return _Utils_Tuple2( { - component: $author$project$Component$init, - deviceClass: $mdgriffith$elm_ui$Element$classifyDevice( - { - height: $elm$core$Basics$round(viewport.height), - width: $elm$core$Basics$round(viewport.width) - })._class, displayDialog: false, - layout: $author$project$Layout$init, - reusable: $author$project$Reusable$init, + expanded: $turboMaCk$any_set$Set$Any$empty($author$project$Data$Example$toString), + layout: $author$project$Widget$Layout$init, scrollingNav: scrollingNav, - stateless: $author$project$Stateless$init + search: {current: '', raw: '', remaining: 0}, + stateless: stateless, + theme: $author$project$Data$Theme$Material, + window: { + height: $elm$core$Basics$round(viewport.height), + width: $elm$core$Basics$round(viewport.width) + } }, - A2($elm$core$Platform$Cmd$map, $author$project$Example$ScrollingNavSpecific, cmd)); + $elm$core$Platform$Cmd$batch( + _List_fromArray( + [ + cmd, + A2($elm$core$Platform$Cmd$map, $author$project$Main$StatelessSpecific, statelessCmd) + ]))); }; var $elm$core$Tuple$mapBoth = F3( function (funcA, funcB, _v0) { @@ -6131,31 +6442,43 @@ var $elm$core$Tuple$mapBoth = F3( funcA(x), funcB(y)); }); -var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); -var $author$project$Example$ComponentSpecific = function (a) { - return {$: 'ComponentSpecific', a: a}; -}; -var $author$project$Example$StatelessSpecific = function (a) { - return {$: 'StatelessSpecific', a: a}; -}; -var $author$project$Widget$ScrollingNav$ChangedViewport = function (a) { - return {$: 'ChangedViewport', a: a}; +var $author$project$Main$AddSnackbar = function (a) { + return {$: 'AddSnackbar', a: a}; }; +var $author$project$Widget$Layout$activate = F2( + function (part, layout) { + return _Utils_update( + layout, + {active: part}); + }); +var $author$project$Widget$ScrollingNav$getPos = A2( + $elm$core$Task$map, + F2( + function (_int, model) { + return _Utils_update( + model, + { + scrollPos: $elm$core$Basics$round(_int.viewport.y) + }); + }), + $elm$browser$Browser$Dom$getViewport); var $elm$browser$Browser$Dom$setViewport = _Browser_setViewport; var $author$project$Widget$ScrollingNav$jumpTo = F2( - function (section, _v0) { - var labels = _v0.labels; + function (_v0, _v1) { + var section = _v0.section; + var onChange = _v0.onChange; + var toString = _v1.toString; return A2( $elm$core$Task$attempt, - $author$project$Widget$ScrollingNav$ChangedViewport, + onChange, A2( $elm$core$Task$andThen, - function (_v1) { - var element = _v1.element; + function (_v2) { + var element = _v2.element; return A2($elm$browser$Browser$Dom$setViewport, 0, element.y); }, $elm$browser$Browser$Dom$getElement( - labels(section)))); + toString(section)))); }); var $elm$browser$Browser$Navigation$load = _Browser_load; var $turboMaCk$queue$Queue$queue = F2( @@ -6200,7 +6523,7 @@ var $author$project$Widget$Snackbar$insertFor = F3( } }); var $author$project$Widget$Snackbar$insert = $author$project$Widget$Snackbar$insertFor(10000); -var $author$project$Layout$queueMessage = F2( +var $author$project$Widget$Layout$queueMessage = F2( function (message, layout) { return _Utils_update( layout, @@ -6208,12 +6531,6 @@ var $author$project$Layout$queueMessage = F2( snackbar: A2($author$project$Widget$Snackbar$insert, message, layout.snackbar) }); }); -var $author$project$Layout$setSidebar = F2( - function (direction, layout) { - return _Utils_update( - layout, - {sheet: direction}); - }); var $turboMaCk$queue$Queue$dequeue = function (_v0) { var fl = _v0.a; var rl = _v0.b; @@ -6252,9 +6569,6 @@ var $elm$core$Tuple$mapSecond = F2( x, func(y)); }); -var $elm$core$Basics$negate = function (n) { - return -n; -}; var $author$project$Widget$Snackbar$timePassed = F2( function (ms, model) { var _v0 = model.current; @@ -6279,118 +6593,51 @@ var $author$project$Widget$Snackbar$timePassed = F2( }); } }); -var $author$project$Layout$timePassed = F2( +var $author$project$Widget$Layout$timePassed = F2( function (sec, layout) { - var _v0 = layout.sheet; - if (_v0.$ === 'Nothing') { - return _Utils_update( - layout, + var _v0 = layout.active; + _v0$2: + while (true) { + if (_v0.$ === 'Just') { + switch (_v0.a.$) { + case 'LeftSheet': + var _v1 = _v0.a; + return layout; + case 'RightSheet': + var _v2 = _v0.a; + return layout; + default: + break _v0$2; + } + } else { + break _v0$2; + } + } + return _Utils_update( + layout, + { + snackbar: A2($author$project$Widget$Snackbar$timePassed, sec, layout.snackbar) + }); + }); +var $turboMaCk$any_dict$Dict$Any$insert = F3( + function (k, v, _v0) { + var inner = _v0.a; + return $turboMaCk$any_dict$Dict$Any$AnyDict( + _Utils_update( + inner, { - snackbar: A2($author$project$Widget$Snackbar$timePassed, sec, layout.snackbar) - }); - } else { - return layout; - } + dict: A3( + $elm$core$Dict$insert, + inner.toKey(k), + _Utils_Tuple2(k, v), + inner.dict) + })); }); -var $author$project$Widget$FilterSelect$update = F2( - function (msg, model) { - if (msg.$ === 'ChangedRaw') { - var string = msg.a; - return _Utils_update( - model, - {raw: string}); - } else { - var maybe = msg.a; - return function () { - if (maybe.$ === 'Just') { - var string = maybe.a; - return function (m) { - return _Utils_update( - m, - {raw: string}); - }; - } else { - return $elm$core$Basics$identity; - } - }()( - _Utils_update( - model, - {selected: maybe})); - } - }); -var $author$project$Widget$ValidatedInput$update = F2( - function (msg, _v0) { - var model = _v0.a; - switch (msg.$) { - case 'StartEditing': - return $author$project$Widget$ValidatedInput$Model( - _Utils_update( - model, - { - raw: $elm$core$Maybe$Just( - model.toString(model.value)) - })); - case 'ChangedRaw': - var string = msg.a; - return $author$project$Widget$ValidatedInput$Model( - _Utils_update( - model, - { - err: $elm$core$Maybe$Nothing, - raw: $elm$core$Maybe$Just(string) - })); - default: - var _v2 = model.raw; - if (_v2.$ === 'Just') { - var string = _v2.a; - var _v3 = model.validator(string); - if (_v3.$ === 'Ok') { - var value = _v3.a; - return $author$project$Widget$ValidatedInput$Model( - _Utils_update( - model, - {err: $elm$core$Maybe$Nothing, raw: $elm$core$Maybe$Nothing, value: value})); - } else { - var err = _v3.a; - return $author$project$Widget$ValidatedInput$Model( - _Utils_update( - model, - { - err: $elm$core$Maybe$Just(err), - raw: $elm$core$Maybe$Nothing - })); - } - } else { - return $author$project$Widget$ValidatedInput$Model(model); - } - } - }); -var $author$project$Component$update = F2( - function (msg, model) { - if (msg.$ === 'FilterSelectSpecific') { - var m = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - filterSelect: A2($author$project$Widget$FilterSelect$update, m, model.filterSelect) - }), - $elm$core$Platform$Cmd$none); - } else { - var m = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - validatedInput: A2($author$project$Widget$ValidatedInput$update, m, model.validatedInput) - }), - $elm$core$Platform$Cmd$none); - } - }); -var $author$project$Reusable$update = F2( - function (msg, model) { - var m = msg.a; - return m; +var $turboMaCk$any_set$Set$Any$insert = F2( + function (a, _v0) { + var dict = _v0.a; + return $turboMaCk$any_set$Set$Any$AnySet( + A3($turboMaCk$any_dict$Dict$Any$insert, a, _Utils_Tuple0, dict)); }); var $elm$core$Dict$member = F2( function (key, dict) { @@ -6401,10 +6648,19 @@ var $elm$core$Dict$member = F2( return false; } }); -var $elm$core$Set$member = F2( - function (key, _v0) { +var $turboMaCk$any_dict$Dict$Any$member = F2( + function (k, _v0) { + var dict = _v0.a.dict; + var toKey = _v0.a.toKey; + return A2( + $elm$core$Dict$member, + toKey(k), + dict); + }); +var $turboMaCk$any_set$Set$Any$member = F2( + function (a, _v0) { var dict = _v0.a; - return A2($elm$core$Dict$member, key, dict); + return A2($turboMaCk$any_dict$Dict$Any$member, a, dict); }); var $elm$core$Dict$getMin = function (dict) { getMin: @@ -6768,289 +7024,429 @@ var $elm$core$Dict$remove = F2( return x; } }); +var $turboMaCk$any_dict$Dict$Any$remove = F2( + function (k, _v0) { + var inner = _v0.a; + return $turboMaCk$any_dict$Dict$Any$AnyDict( + _Utils_update( + inner, + { + dict: A2( + $elm$core$Dict$remove, + inner.toKey(k), + inner.dict) + })); + }); +var $turboMaCk$any_set$Set$Any$remove = F2( + function (a, _v0) { + var dict = _v0.a; + return $turboMaCk$any_set$Set$Any$AnySet( + A2($turboMaCk$any_dict$Dict$Any$remove, a, dict)); + }); +var $turboMaCk$any_set$Set$Any$toggle = F2( + function (a, set) { + return A2($turboMaCk$any_set$Set$Any$member, a, set) ? A2($turboMaCk$any_set$Set$Any$remove, a, set) : A2($turboMaCk$any_set$Set$Any$insert, a, set); + }); +var $elm$core$Platform$Sub$none = $elm$core$Platform$Sub$batch(_List_Nil); +var $author$project$Example$Button$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$Dialog$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$ExpansionPanel$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$List$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$Modal$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$MultiSelect$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$Select$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$SortTable$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$Tab$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$TextInput$subscriptions = function (_v0) { + return $elm$core$Platform$Sub$none; +}; +var $author$project$Example$Button$update = F2( + function (msg, _v0) { + var bool = msg.a; + return _Utils_Tuple2( + $author$project$Example$Button$IsButtonEnabled(bool), + $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$Dialog$update = F2( + function (msg, _v0) { + var bool = msg.a; + return _Utils_Tuple2( + $author$project$Example$Dialog$IsOpen(bool), + $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$ExpansionPanel$update = F2( + function (msg, _v0) { + var bool = msg.a; + return _Utils_Tuple2( + $author$project$Example$ExpansionPanel$IsExpanded(bool), + $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$List$update = F2( + function (_v0, _v1) { + return _Utils_Tuple2(_Utils_Tuple0, $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$Modal$update = F2( + function (msg, _v0) { + var bool = msg.a; + return _Utils_Tuple2( + $author$project$Example$Modal$IsEnabled(bool), + $elm$core$Platform$Cmd$none); + }); +var $elm$core$Set$insert = F2( + function (key, _v0) { + var dict = _v0.a; + return $elm$core$Set$Set_elm_builtin( + A3($elm$core$Dict$insert, key, _Utils_Tuple0, dict)); + }); +var $elm$core$Set$member = F2( + function (key, _v0) { + var dict = _v0.a; + return A2($elm$core$Dict$member, key, dict); + }); var $elm$core$Set$remove = F2( function (key, _v0) { var dict = _v0.a; return $elm$core$Set$Set_elm_builtin( A2($elm$core$Dict$remove, key, dict)); }); -var $author$project$Stateless$update = F2( +var $author$project$Example$MultiSelect$update = F2( + function (msg, _v0) { + var selected = _v0.a; + var _int = msg.a; + return _Utils_Tuple2( + $author$project$Example$MultiSelect$Selected( + (A2($elm$core$Set$member, _int, selected) ? $elm$core$Set$remove(_int) : $elm$core$Set$insert(_int))(selected)), + $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$Select$update = F2( + function (msg, _v0) { + var _int = msg.a; + return _Utils_Tuple2( + $author$project$Example$Select$Selected( + $elm$core$Maybe$Just(_int)), + $elm$core$Platform$Cmd$none); + }); +var $elm$core$Basics$not = _Basics_not; +var $author$project$Example$SortTable$update = F2( function (msg, model) { - switch (msg.$) { - case 'ChangedSelected': - var _int = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - selected: $elm$core$Maybe$Just(_int) - }), - $elm$core$Platform$Cmd$none); - case 'ChangedMultiSelected': - var _int = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - multiSelected: (A2($elm$core$Set$member, _int, model.multiSelected) ? $elm$core$Set$remove(_int) : $elm$core$Set$insert(_int))(model.multiSelected) - }), - $elm$core$Platform$Cmd$none); - case 'ToggleCollapsable': - var bool = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - {isCollapsed: bool}), - $elm$core$Platform$Cmd$none); - case 'SetCarousel': - var _int = msg.a; - return _Utils_Tuple2( - ((_int < 0) || (_int > 3)) ? model : _Utils_update( - model, - {carousel: _int}), - $elm$core$Platform$Cmd$none); - default: - var _int = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - {tab: _int}), - $elm$core$Platform$Cmd$none); + var string = msg.a; + return _Utils_Tuple2( + { + asc: _Utils_eq(model.title, string) ? (!model.asc) : true, + title: string + }, + $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$Tab$update = F2( + function (msg, _v0) { + var _int = msg.a; + return _Utils_Tuple2( + $author$project$Example$Tab$Selected( + $elm$core$Maybe$Just(_int)), + $elm$core$Platform$Cmd$none); + }); +var $author$project$Example$TextInput$update = F2( + function (msg, model) { + if (msg.$ === 'ToggleTextInputChip') { + var string = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + chipTextInput: (A2($elm$core$Set$member, string, model.chipTextInput) ? $elm$core$Set$remove(string) : $elm$core$Set$insert(string))(model.chipTextInput) + }), + $elm$core$Platform$Cmd$none); + } else { + var string = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + {textInput: string}), + $elm$core$Platform$Cmd$none); } }); -var $author$project$Widget$ScrollingNav$SyncPosition = function (a) { - return {$: 'SyncPosition', a: a}; -}; -var $elm_community$intdict$IntDict$Inner = function (a) { - return {$: 'Inner', a: a}; -}; -var $elm_community$intdict$IntDict$size = function (dict) { - switch (dict.$) { - case 'Empty': - return 0; - case 'Leaf': - return 1; - default: - var i = dict.a; - return i.size; +var $author$project$Data$Example$upgradeRecord = { + button: { + from: function ($) { + return $.button; + }, + msgMapper: $author$project$Data$Example$Button, + subscriptionsFun: $author$project$Example$Button$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {button: a}); + }), + updateFun: $author$project$Example$Button$update + }, + dialog: { + from: function ($) { + return $.dialog; + }, + msgMapper: $author$project$Data$Example$Dialog, + subscriptionsFun: $author$project$Example$Dialog$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {dialog: a}); + }), + updateFun: $author$project$Example$Dialog$update + }, + expansionPanel: { + from: function ($) { + return $.expansionPanel; + }, + msgMapper: $author$project$Data$Example$ExpansionPanel, + subscriptionsFun: $author$project$Example$ExpansionPanel$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {expansionPanel: a}); + }), + updateFun: $author$project$Example$ExpansionPanel$update + }, + list: { + from: function ($) { + return $.list; + }, + msgMapper: $author$project$Data$Example$List, + subscriptionsFun: $author$project$Example$List$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {list: a}); + }), + updateFun: $author$project$Example$List$update + }, + modal: { + from: function ($) { + return $.modal; + }, + msgMapper: $author$project$Data$Example$Modal, + subscriptionsFun: $author$project$Example$Modal$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {modal: a}); + }), + updateFun: $author$project$Example$Modal$update + }, + multiSelect: { + from: function ($) { + return $.multiSelect; + }, + msgMapper: $author$project$Data$Example$MultiSelect, + subscriptionsFun: $author$project$Example$MultiSelect$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {multiSelect: a}); + }), + updateFun: $author$project$Example$MultiSelect$update + }, + select: { + from: function ($) { + return $.select; + }, + msgMapper: $author$project$Data$Example$Select, + subscriptionsFun: $author$project$Example$Select$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {select: a}); + }), + updateFun: $author$project$Example$Select$update + }, + sortTable: { + from: function ($) { + return $.sortTable; + }, + msgMapper: $author$project$Data$Example$SortTable, + subscriptionsFun: $author$project$Example$SortTable$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {sortTable: a}); + }), + updateFun: $author$project$Example$SortTable$update + }, + tab: { + from: function ($) { + return $.tab; + }, + msgMapper: $author$project$Data$Example$Tab, + subscriptionsFun: $author$project$Example$Tab$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {tab: a}); + }), + updateFun: $author$project$Example$Tab$update + }, + textInput: { + from: function ($) { + return $.textInput; + }, + msgMapper: $author$project$Data$Example$TextInput, + subscriptionsFun: $author$project$Example$TextInput$subscriptions, + to: F2( + function (model, a) { + return _Utils_update( + model, + {textInput: a}); + }), + updateFun: $author$project$Example$TextInput$update } }; -var $elm_community$intdict$IntDict$inner = F3( - function (p, l, r) { - var _v0 = _Utils_Tuple2(l, r); - if (_v0.a.$ === 'Empty') { - var _v1 = _v0.a; - return r; - } else { - if (_v0.b.$ === 'Empty') { - var _v2 = _v0.b; - return l; - } else { - return $elm_community$intdict$IntDict$Inner( - { - left: l, - prefix: p, - right: r, - size: $elm_community$intdict$IntDict$size(l) + $elm_community$intdict$IntDict$size(r) - }); - } - } - }); -var $elm$core$Bitwise$and = _Bitwise_and; -var $elm$core$Basics$neq = _Utils_notEqual; -var $elm$core$Bitwise$complement = _Bitwise_complement; -var $elm$core$Bitwise$or = _Bitwise_or; -var $elm$core$Bitwise$shiftRightZfBy = _Bitwise_shiftRightZfBy; -var $elm_community$intdict$IntDict$highestBitSet = function (n) { - var shiftOr = F2( - function (i, shift) { - return i | (i >>> shift); - }); - var n1 = A2(shiftOr, n, 1); - var n2 = A2(shiftOr, n1, 2); - var n3 = A2(shiftOr, n2, 4); - var n4 = A2(shiftOr, n3, 8); - var n5 = A2(shiftOr, n4, 16); - return n5 & (~(n5 >>> 1)); -}; -var $elm_community$intdict$IntDict$signBit = $elm_community$intdict$IntDict$highestBitSet(-1); -var $elm$core$Bitwise$xor = _Bitwise_xor; -var $elm_community$intdict$IntDict$isBranchingBitSet = function (p) { - return A2( - $elm$core$Basics$composeR, - $elm$core$Bitwise$xor($elm_community$intdict$IntDict$signBit), - A2( - $elm$core$Basics$composeR, - $elm$core$Bitwise$and(p.branchingBit), - $elm$core$Basics$neq(0))); -}; -var $elm_community$intdict$IntDict$higherBitMask = function (branchingBit) { - return branchingBit ^ (~(branchingBit - 1)); -}; -var $elm_community$intdict$IntDict$lcp = F2( - function (x, y) { - var branchingBit = $elm_community$intdict$IntDict$highestBitSet(x ^ y); - var mask = $elm_community$intdict$IntDict$higherBitMask(branchingBit); - var prefixBits = x & mask; - return {branchingBit: branchingBit, prefixBits: prefixBits}; - }); -var $elm_community$intdict$IntDict$Leaf = function (a) { - return {$: 'Leaf', a: a}; -}; -var $elm_community$intdict$IntDict$leaf = F2( - function (k, v) { - return $elm_community$intdict$IntDict$Leaf( - {key: k, value: v}); - }); -var $elm_community$intdict$IntDict$prefixMatches = F2( - function (p, n) { - return _Utils_eq( - n & $elm_community$intdict$IntDict$higherBitMask(p.branchingBit), - p.prefixBits); - }); -var $elm_community$intdict$IntDict$update = F3( - function (key, alter, dict) { - var join = F2( - function (_v2, _v3) { - var k1 = _v2.a; - var l = _v2.b; - var k2 = _v3.a; - var r = _v3.b; - var prefix = A2($elm_community$intdict$IntDict$lcp, k1, k2); - return A2($elm_community$intdict$IntDict$isBranchingBitSet, prefix, k2) ? A3($elm_community$intdict$IntDict$inner, prefix, l, r) : A3($elm_community$intdict$IntDict$inner, prefix, r, l); - }); - var alteredNode = function (mv) { - var _v1 = alter(mv); - if (_v1.$ === 'Just') { - var v = _v1.a; - return A2($elm_community$intdict$IntDict$leaf, key, v); - } else { - return $elm_community$intdict$IntDict$empty; - } - }; - switch (dict.$) { - case 'Empty': - return alteredNode($elm$core$Maybe$Nothing); - case 'Leaf': - var l = dict.a; - return _Utils_eq(l.key, key) ? alteredNode( - $elm$core$Maybe$Just(l.value)) : A2( - join, - _Utils_Tuple2( - key, - alteredNode($elm$core$Maybe$Nothing)), - _Utils_Tuple2(l.key, dict)); - default: - var i = dict.a; - return A2($elm_community$intdict$IntDict$prefixMatches, i.prefix, key) ? (A2($elm_community$intdict$IntDict$isBranchingBitSet, i.prefix, key) ? A3( - $elm_community$intdict$IntDict$inner, - i.prefix, - i.left, - A3($elm_community$intdict$IntDict$update, key, alter, i.right)) : A3( - $elm_community$intdict$IntDict$inner, - i.prefix, - A3($elm_community$intdict$IntDict$update, key, alter, i.left), - i.right)) : A2( - join, - _Utils_Tuple2( - key, - alteredNode($elm$core$Maybe$Nothing)), - _Utils_Tuple2(i.prefix.prefixBits, dict)); - } - }); -var $elm_community$intdict$IntDict$insert = F3( - function (key, value, dict) { +var $author$project$Data$Example$updateField = F3( + function (getter, msg, model) { + var _v0 = getter($author$project$Data$Example$upgradeRecord); + var from = _v0.from; + var to = _v0.to; + var msgMapper = _v0.msgMapper; + var updateFun = _v0.updateFun; return A3( - $elm_community$intdict$IntDict$update, - key, - $elm$core$Basics$always( - $elm$core$Maybe$Just(value)), - dict); + $elm$core$Tuple$mapBoth, + to(model), + $elm$core$Platform$Cmd$map(msgMapper), + A2( + updateFun, + msg, + from(model))); }); -var $author$project$Widget$ScrollingNav$update = F2( +var $author$project$Data$Example$update = F2( function (msg, model) { - switch (msg.$) { - case 'GotHeaderPos': - var label = msg.a; - var result = msg.b; - return _Utils_Tuple2( - function () { - if (result.$ === 'Ok') { - var pos = result.a; - return _Utils_update( - model, - { - positions: A3( - $elm_community$intdict$IntDict$insert, - pos, - model.labels(label), - model.positions) - }); - } else { - return model; - } - }(), - $elm$core$Platform$Cmd$none); - case 'ChangedViewport': - return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); - case 'SyncPosition': - var pos = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - {scrollPos: pos}), - $elm$core$Platform$Cmd$none); - case 'TimePassed': - return _Utils_Tuple2( + return function () { + switch (msg.$) { + case 'Button': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.button; + }, + m); + case 'Select': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.select; + }, + m); + case 'MultiSelect': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.multiSelect; + }, + m); + case 'ExpansionPanel': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.expansionPanel; + }, + m); + case 'Tab': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.tab; + }, + m); + case 'SortTable': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.sortTable; + }, + m); + case 'Modal': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.modal; + }, + m); + case 'Dialog': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.dialog; + }, + m); + case 'TextInput': + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.textInput; + }, + m); + default: + var m = msg.a; + return A2( + $author$project$Data$Example$updateField, + function ($) { + return $.list; + }, + m); + } + }()(model); + }); +var $author$project$Stateless$update = F2( + function (msg, model) { + if (msg.$ === 'ExampleSpecific') { + var exampleMsg = msg.a; + var _v1 = A2($author$project$Data$Example$update, exampleMsg, model.example); + var exampleModel = _v1.a; + var exampleCmd = _v1.b; + return _Utils_Tuple2( + _Utils_update( model, - A2( - $elm$core$Task$perform, - $author$project$Widget$ScrollingNav$SyncPosition, - A2( - $elm$core$Task$map, - A2( - $elm$core$Basics$composeR, - function ($) { - return $.viewport; - }, - A2( - $elm$core$Basics$composeR, - function ($) { - return $.y; - }, - $elm$core$Basics$round)), - $elm$browser$Browser$Dom$getViewport))); - default: - var elem = msg.a; - return _Utils_Tuple2( - model, - A2($author$project$Widget$ScrollingNav$jumpTo, elem, model)); + {example: exampleModel}), + A2($elm$core$Platform$Cmd$map, $author$project$Stateless$ExampleSpecific, exampleCmd)); + } else { + return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); } }); -var $author$project$Example$updateLoaded = F2( +var $author$project$Main$updateLoaded = F2( function (msg, model) { switch (msg.$) { - case 'ComponentSpecific': - var m = msg.a; - return A3( - $elm$core$Tuple$mapBoth, - function (component) { - return _Utils_update( - model, - {component: component}); - }, - $elm$core$Platform$Cmd$map($author$project$Example$ComponentSpecific), - A2($author$project$Component$update, m, model.component)); - case 'ReusableSpecific': - var m = msg.a; - return _Utils_Tuple2( - function (reusable) { - return _Utils_update( - model, - {reusable: reusable}); - }( - A2($author$project$Reusable$update, m, model.reusable)), - $elm$core$Platform$Cmd$none); case 'StatelessSpecific': var m = msg.a; return A3( @@ -7060,35 +7456,53 @@ var $author$project$Example$updateLoaded = F2( model, {stateless: stateless}); }, - $elm$core$Platform$Cmd$map($author$project$Example$StatelessSpecific), + $elm$core$Platform$Cmd$map($author$project$Main$StatelessSpecific), A2($author$project$Stateless$update, m, model.stateless)); - case 'ScrollingNavSpecific': - var m = msg.a; - return A3( - $elm$core$Tuple$mapBoth, - function (scrollingNav) { - return _Utils_update( - model, - {scrollingNav: scrollingNav}); - }, - $elm$core$Platform$Cmd$map($author$project$Example$ScrollingNavSpecific), - A2($author$project$Widget$ScrollingNav$update, m, model.scrollingNav)); - case 'TimePassed': - var _int = msg.a; + case 'UpdateScrollingNav': + var fun = msg.a; return _Utils_Tuple2( _Utils_update( model, { - layout: A2($author$project$Layout$timePassed, _int, model.layout) + scrollingNav: fun(model.scrollingNav) }), $elm$core$Platform$Cmd$none); - case 'AddSnackbar': - var string = msg.a; + case 'TimePassed': + var _int = msg.a; + var search = model.search; return _Utils_Tuple2( _Utils_update( model, { - layout: A2($author$project$Layout$queueMessage, string, model.layout) + layout: A2($author$project$Widget$Layout$timePassed, _int, model.layout), + search: (search.remaining > 0) ? ((_Utils_cmp(search.remaining, _int) < 1) ? _Utils_update( + search, + {current: search.raw, remaining: 0}) : _Utils_update( + search, + {remaining: search.remaining - _int})) : model.search + }), + A2($elm$core$Task$perform, $author$project$Main$UpdateScrollingNav, $author$project$Widget$ScrollingNav$getPos)); + case 'AddSnackbar': + var _v1 = msg.a; + var string = _v1.a; + var bool = _v1.b; + return _Utils_Tuple2( + _Utils_update( + model, + { + layout: A2( + $author$project$Widget$Layout$queueMessage, + { + button: bool ? $elm$core$Maybe$Just( + { + onPress: $elm$core$Maybe$Just( + $author$project$Main$AddSnackbar( + _Utils_Tuple2('This is another message', false))), + text: 'Add' + }) : $elm$core$Maybe$Nothing, + text: string + }, + model.layout) }), $elm$core$Platform$Cmd$none); case 'ToggleDialog': @@ -7099,13 +7513,11 @@ var $author$project$Example$updateLoaded = F2( {displayDialog: bool}), $elm$core$Platform$Cmd$none); case 'Resized': - var screen = msg.a; + var window = msg.a; return _Utils_Tuple2( _Utils_update( model, - { - deviceClass: $mdgriffith$elm_ui$Element$classifyDevice(screen)._class - }), + {window: window}), $elm$core$Platform$Cmd$none); case 'ChangedSidebar': var sidebar = msg.a; @@ -7113,7 +7525,7 @@ var $author$project$Example$updateLoaded = F2( _Utils_update( model, { - layout: A2($author$project$Layout$setSidebar, sidebar, model.layout) + layout: A2($author$project$Widget$Layout$activate, sidebar, model.layout) }), $elm$core$Platform$Cmd$none); case 'Load': @@ -7121,17 +7533,50 @@ var $author$project$Example$updateLoaded = F2( return _Utils_Tuple2( model, $elm$browser$Browser$Navigation$load(string)); - default: + case 'JumpTo': var section = msg.a; return _Utils_Tuple2( model, A2( - $elm$core$Platform$Cmd$map, - $author$project$Example$ScrollingNavSpecific, - A2($author$project$Widget$ScrollingNav$jumpTo, section, model.scrollingNav))); + $author$project$Widget$ScrollingNav$jumpTo, + { + onChange: $elm$core$Basics$always($author$project$Main$Idle), + section: section + }, + model.scrollingNav)); + case 'ChangedSearch': + var string = msg.a; + var search = model.search; + return _Utils_Tuple2( + _Utils_update( + model, + { + search: _Utils_update( + search, + {raw: string, remaining: 300}) + }), + $elm$core$Platform$Cmd$none); + case 'SetTheme': + var theme = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + {theme: theme}), + $elm$core$Platform$Cmd$none); + case 'ToggledExample': + var example = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + expanded: A2($turboMaCk$any_set$Set$Any$toggle, example, model.expanded) + }), + $elm$core$Platform$Cmd$none); + default: + return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); } }); -var $author$project$Example$update = F2( +var $author$project$Main$update = F2( function (msg, model) { var _v0 = _Utils_Tuple2(model, msg); _v0$2: @@ -7142,9 +7587,9 @@ var $author$project$Example$update = F2( var viewport = _v0.b.a; return A3( $elm$core$Tuple$mapBoth, - $author$project$Example$Loaded, - $elm$core$Platform$Cmd$map($author$project$Example$LoadedSpecific), - $author$project$Example$initialModel(viewport)); + $author$project$Main$Loaded, + $elm$core$Platform$Cmd$map($author$project$Main$LoadedSpecific), + $author$project$Main$initialModel(viewport)); } else { break _v0$2; } @@ -7154,9 +7599,9 @@ var $author$project$Example$update = F2( var m = _v0.b.a; return A3( $elm$core$Tuple$mapBoth, - $author$project$Example$Loaded, - $elm$core$Platform$Cmd$map($author$project$Example$LoadedSpecific), - A2($author$project$Example$updateLoaded, m, state)); + $author$project$Main$Loaded, + $elm$core$Platform$Cmd$map($author$project$Main$LoadedSpecific), + A2($author$project$Main$updateLoaded, m, state)); } else { break _v0$2; } @@ -7164,29 +7609,27 @@ var $author$project$Example$update = F2( } return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); }); -var $author$project$Example$AddSnackbar = function (a) { - return {$: 'AddSnackbar', a: a}; +var $author$project$Main$ChangedSearch = function (a) { + return {$: 'ChangedSearch', a: a}; }; -var $author$project$Example$ChangedSidebar = function (a) { +var $author$project$Main$ChangedSidebar = function (a) { return {$: 'ChangedSidebar', a: a}; }; -var $author$project$Example$JumpTo = function (a) { +var $author$project$Data$Theme$DarkMaterial = {$: 'DarkMaterial'}; +var $author$project$Data$Theme$ElmUiFramework = {$: 'ElmUiFramework'}; +var $author$project$Main$JumpTo = function (a) { return {$: 'JumpTo', a: a}; }; -var $author$project$Example$Load = function (a) { +var $author$project$Main$Load = function (a) { return {$: 'Load', a: a}; }; -var $author$project$Example$ReusableSpecific = function (a) { - return {$: 'ReusableSpecific', a: a}; +var $author$project$Main$SetTheme = function (a) { + return {$: 'SetTheme', a: a}; }; -var $author$project$Example$ToggleDialog = function (a) { +var $author$project$Data$Theme$Template = {$: 'Template'}; +var $author$project$Main$ToggleDialog = function (a) { return {$: 'ToggleDialog', a: a}; }; -var $mdgriffith$elm_ui$Internal$Model$AlignX = function (a) { - return {$: 'AlignX', a: a}; -}; -var $mdgriffith$elm_ui$Internal$Model$Right = {$: 'Right'}; -var $mdgriffith$elm_ui$Element$alignRight = $mdgriffith$elm_ui$Internal$Model$AlignX($mdgriffith$elm_ui$Internal$Model$Right); var $elm$svg$Svg$Attributes$d = _VirtualDom_attribute('d'); var $elm$svg$Svg$trustedNode = _VirtualDom_nodeNS('http://www.w3.org/2000/svg'); var $elm$svg$Svg$path = $elm$svg$Svg$trustedNode('path'); @@ -7235,28 +7678,24 @@ var $author$project$Icons$book = A2( ]), _List_Nil) ])); -var $mdgriffith$elm_ui$Internal$Model$Attr = function (a) { - return {$: 'Attr', a: a}; +var $mdgriffith$elm_ui$Internal$Model$AlignX = function (a) { + return {$: 'AlignX', a: a}; }; -var $mdgriffith$elm_ui$Internal$Model$Button = {$: 'Button'}; -var $mdgriffith$elm_ui$Internal$Model$Describe = function (a) { - return {$: 'Describe', a: a}; +var $mdgriffith$elm_ui$Internal$Model$Right = {$: 'Right'}; +var $mdgriffith$elm_ui$Element$alignRight = $mdgriffith$elm_ui$Internal$Model$AlignX($mdgriffith$elm_ui$Internal$Model$Right); +var $mdgriffith$elm_ui$Internal$Model$CenterX = {$: 'CenterX'}; +var $mdgriffith$elm_ui$Element$centerX = $mdgriffith$elm_ui$Internal$Model$AlignX($mdgriffith$elm_ui$Internal$Model$CenterX); +var $mdgriffith$elm_ui$Internal$Model$AlignY = function (a) { + return {$: 'AlignY', a: a}; }; +var $mdgriffith$elm_ui$Internal$Model$CenterY = {$: 'CenterY'}; +var $mdgriffith$elm_ui$Element$centerY = $mdgriffith$elm_ui$Internal$Model$AlignY($mdgriffith$elm_ui$Internal$Model$CenterY); var $mdgriffith$elm_ui$Internal$Model$Unkeyed = function (a) { return {$: 'Unkeyed', a: a}; }; -var $mdgriffith$elm_ui$Internal$Model$AsEl = {$: 'AsEl'}; -var $mdgriffith$elm_ui$Internal$Model$asEl = $mdgriffith$elm_ui$Internal$Model$AsEl; +var $mdgriffith$elm_ui$Internal$Model$AsColumn = {$: 'AsColumn'}; +var $mdgriffith$elm_ui$Internal$Model$asColumn = $mdgriffith$elm_ui$Internal$Model$AsColumn; var $mdgriffith$elm_ui$Internal$Style$classes = {above: 'a', active: 'atv', alignBottom: 'ab', alignCenterX: 'cx', alignCenterY: 'cy', alignContainerBottom: 'acb', alignContainerCenterX: 'accx', alignContainerCenterY: 'accy', alignContainerRight: 'acr', alignLeft: 'al', alignRight: 'ar', alignTop: 'at', alignedHorizontally: 'ah', alignedVertically: 'av', any: 's', behind: 'bh', below: 'b', bold: 'w7', borderDashed: 'bd', borderDotted: 'bdt', borderNone: 'bn', borderSolid: 'bs', capturePointerEvents: 'cpe', clip: 'cp', clipX: 'cpx', clipY: 'cpy', column: 'c', container: 'ctr', contentBottom: 'cb', contentCenterX: 'ccx', contentCenterY: 'ccy', contentLeft: 'cl', contentRight: 'cr', contentTop: 'ct', cursorPointer: 'cptr', cursorText: 'ctxt', focus: 'fcs', focusedWithin: 'focus-within', fullSize: 'fs', grid: 'g', hasBehind: 'hbh', heightContent: 'hc', heightExact: 'he', heightFill: 'hf', heightFillPortion: 'hfp', hover: 'hv', imageContainer: 'ic', inFront: 'fr', inputMultiline: 'iml', inputMultilineFiller: 'imlf', inputMultilineParent: 'imlp', inputMultilineWrapper: 'implw', inputText: 'it', italic: 'i', link: 'lnk', nearby: 'nb', noTextSelection: 'notxt', onLeft: 'ol', onRight: 'or', opaque: 'oq', overflowHidden: 'oh', page: 'pg', paragraph: 'p', passPointerEvents: 'ppe', root: 'ui', row: 'r', scrollbars: 'sb', scrollbarsX: 'sbx', scrollbarsY: 'sby', seButton: 'sbt', single: 'e', sizeByCapital: 'cap', spaceEvenly: 'sev', strike: 'sk', text: 't', textCenter: 'tc', textExtraBold: 'w8', textExtraLight: 'w2', textHeavy: 'w9', textJustify: 'tj', textJustifyAll: 'tja', textLeft: 'tl', textLight: 'w3', textMedium: 'w5', textNormalWeight: 'w4', textRight: 'tr', textSemiBold: 'w6', textThin: 'w1', textUnitalicized: 'tun', transition: 'ts', transparent: 'clr', underline: 'u', widthContent: 'wc', widthExact: 'we', widthFill: 'wf', widthFillPortion: 'wfp', wrapped: 'wrp'}; -var $elm$json$Json$Encode$bool = _Json_wrap; -var $elm$html$Html$Attributes$boolProperty = F2( - function (key, bool) { - return A2( - _VirtualDom_property, - key, - $elm$json$Json$Encode$bool(bool)); - }); -var $elm$html$Html$Attributes$disabled = $elm$html$Html$Attributes$boolProperty('disabled'); var $mdgriffith$elm_ui$Internal$Model$Generic = {$: 'Generic'}; var $mdgriffith$elm_ui$Internal$Model$div = $mdgriffith$elm_ui$Internal$Model$Generic; var $mdgriffith$elm_ui$Internal$Model$NoNearbyChildren = {$: 'NoNearbyChildren'}; @@ -7356,6 +7795,8 @@ var $mdgriffith$elm_ui$Internal$Model$addKeyedChildren = F3( inFront))); } }); +var $mdgriffith$elm_ui$Internal$Model$AsEl = {$: 'AsEl'}; +var $mdgriffith$elm_ui$Internal$Model$asEl = $mdgriffith$elm_ui$Internal$Model$AsEl; var $mdgriffith$elm_ui$Internal$Model$AsParagraph = {$: 'AsParagraph'}; var $mdgriffith$elm_ui$Internal$Model$asParagraph = $mdgriffith$elm_ui$Internal$Model$AsParagraph; var $mdgriffith$elm_ui$Internal$Flag$Flag = function (a) { @@ -9803,6 +10244,10 @@ var $mdgriffith$elm_ui$Internal$Model$hasSmallCaps = function (typeface) { return false; } }; +var $elm$core$Basics$min = F2( + function (x, y) { + return (_Utils_cmp(x, y) < 0) ? x : y; + }); var $mdgriffith$elm_ui$Internal$Model$renderProps = F3( function (force, _v0, existing) { var key = _v0.a; @@ -10797,7 +11242,6 @@ var $elm$virtual_dom$VirtualDom$keyedNode = function (tag) { return _VirtualDom_keyedNode( _VirtualDom_noScript(tag)); }; -var $elm$core$Basics$not = _Basics_not; var $elm$html$Html$p = _VirtualDom_node('p'); var $mdgriffith$elm_ui$Internal$Flag$present = F2( function (myFlag, _v0) { @@ -12579,27 +13023,113 @@ var $mdgriffith$elm_ui$Internal$Model$element = F4( $mdgriffith$elm_ui$Internal$Model$NoNearbyChildren, $elm$core$List$reverse(attributes))); }); -var $mdgriffith$elm_ui$Internal$Model$NoAttribute = {$: 'NoAttribute'}; -var $mdgriffith$elm_ui$Element$Input$hasFocusStyle = function (attr) { - if (((attr.$ === 'StyleClass') && (attr.b.$ === 'PseudoSelector')) && (attr.b.a.$ === 'Focus')) { - var _v1 = attr.b; - var _v2 = _v1.a; - return true; - } else { - return false; - } +var $mdgriffith$elm_ui$Internal$Model$Height = function (a) { + return {$: 'Height', a: a}; +}; +var $mdgriffith$elm_ui$Element$height = $mdgriffith$elm_ui$Internal$Model$Height; +var $mdgriffith$elm_ui$Internal$Model$Attr = function (a) { + return {$: 'Attr', a: a}; }; var $mdgriffith$elm_ui$Internal$Model$htmlClass = function (cls) { return $mdgriffith$elm_ui$Internal$Model$Attr( $elm$html$Html$Attributes$class(cls)); }; -var $mdgriffith$elm_ui$Element$Input$focusDefault = function (attrs) { - return A2($elm$core$List$any, $mdgriffith$elm_ui$Element$Input$hasFocusStyle, attrs) ? $mdgriffith$elm_ui$Internal$Model$NoAttribute : $mdgriffith$elm_ui$Internal$Model$htmlClass('focusable'); +var $mdgriffith$elm_ui$Internal$Model$Content = {$: 'Content'}; +var $mdgriffith$elm_ui$Element$shrink = $mdgriffith$elm_ui$Internal$Model$Content; +var $mdgriffith$elm_ui$Internal$Model$Width = function (a) { + return {$: 'Width', a: a}; }; -var $mdgriffith$elm_ui$Internal$Model$Height = function (a) { - return {$: 'Height', a: a}; +var $mdgriffith$elm_ui$Element$width = $mdgriffith$elm_ui$Internal$Model$Width; +var $mdgriffith$elm_ui$Element$column = F2( + function (attrs, children) { + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asColumn, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentTop + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.contentLeft)), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + attrs))), + $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); + }); +var $mdgriffith$elm_ui$Element$el = F2( + function (attrs, child) { + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asEl, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), + attrs)), + $mdgriffith$elm_ui$Internal$Model$Unkeyed( + _List_fromArray( + [child]))); + }); +var $mdgriffith$elm_ui$Internal$Model$Class = F2( + function (a, b) { + return {$: 'Class', a: a, b: b}; + }); +var $mdgriffith$elm_ui$Internal$Flag$overflow = $mdgriffith$elm_ui$Internal$Flag$flag(20); +var $mdgriffith$elm_ui$Element$clip = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$overflow, $mdgriffith$elm_ui$Internal$Style$classes.clip); +var $mdgriffith$elm_ui$Internal$Model$Colored = F3( + function (a, b, c) { + return {$: 'Colored', a: a, b: b, c: c}; + }); +var $mdgriffith$elm_ui$Internal$Model$StyleClass = F2( + function (a, b) { + return {$: 'StyleClass', a: a, b: b}; + }); +var $mdgriffith$elm_ui$Internal$Flag$bgColor = $mdgriffith$elm_ui$Internal$Flag$flag(8); +var $mdgriffith$elm_ui$Internal$Model$formatColorClass = function (_v0) { + var red = _v0.a; + var green = _v0.b; + var blue = _v0.c; + var alpha = _v0.d; + return $mdgriffith$elm_ui$Internal$Model$floatClass(red) + ('-' + ($mdgriffith$elm_ui$Internal$Model$floatClass(green) + ('-' + ($mdgriffith$elm_ui$Internal$Model$floatClass(blue) + ('-' + $mdgriffith$elm_ui$Internal$Model$floatClass(alpha)))))); }; -var $mdgriffith$elm_ui$Element$height = $mdgriffith$elm_ui$Internal$Model$Height; +var $mdgriffith$elm_ui$Element$Background$color = function (clr) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$bgColor, + A3( + $mdgriffith$elm_ui$Internal$Model$Colored, + 'bg-' + $mdgriffith$elm_ui$Internal$Model$formatColorClass(clr), + 'background-color', + clr)); +}; +var $mdgriffith$elm_ui$Internal$Model$Fill = function (a) { + return {$: 'Fill', a: a}; +}; +var $mdgriffith$elm_ui$Element$fill = $mdgriffith$elm_ui$Internal$Model$Fill(1); +var $mdgriffith$elm_ui$Internal$Model$InFront = {$: 'InFront'}; +var $mdgriffith$elm_ui$Internal$Model$Nearby = F2( + function (a, b) { + return {$: 'Nearby', a: a, b: b}; + }); +var $mdgriffith$elm_ui$Internal$Model$NoAttribute = {$: 'NoAttribute'}; +var $mdgriffith$elm_ui$Element$createNearby = F2( + function (loc, element) { + if (element.$ === 'Empty') { + return $mdgriffith$elm_ui$Internal$Model$NoAttribute; + } else { + return A2($mdgriffith$elm_ui$Internal$Model$Nearby, loc, element); + } + }); +var $mdgriffith$elm_ui$Element$inFront = function (element) { + return A2($mdgriffith$elm_ui$Element$createNearby, $mdgriffith$elm_ui$Internal$Model$InFront, element); +}; +var $mdgriffith$elm_ui$Internal$Model$Empty = {$: 'Empty'}; +var $mdgriffith$elm_ui$Element$none = $mdgriffith$elm_ui$Internal$Model$Empty; var $elm$virtual_dom$VirtualDom$Normal = function (a) { return {$: 'Normal', a: a}; }; @@ -12618,6 +13148,135 @@ var $elm$html$Html$Events$onClick = function (msg) { $elm$json$Json$Decode$succeed(msg)); }; var $mdgriffith$elm_ui$Element$Events$onClick = A2($elm$core$Basics$composeL, $mdgriffith$elm_ui$Internal$Model$Attr, $elm$html$Html$Events$onClick); +var $mdgriffith$elm_ui$Internal$Model$Rgba = F4( + function (a, b, c, d) { + return {$: 'Rgba', a: a, b: b, c: c, d: d}; + }); +var $mdgriffith$elm_ui$Element$rgba255 = F4( + function (red, green, blue, a) { + return A4($mdgriffith$elm_ui$Internal$Model$Rgba, red / 255, green / 255, blue / 255, a); + }); +var $elm$core$List$singleton = function (value) { + return _List_fromArray( + [value]); +}; +var $author$project$Internal$Dialog$modal = function (_v0) { + var onDismiss = _v0.onDismiss; + var content = _v0.content; + return _List_fromArray( + [ + $mdgriffith$elm_ui$Element$inFront( + A2( + $mdgriffith$elm_ui$Element$el, + _Utils_ap( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$Background$color( + A4($mdgriffith$elm_ui$Element$rgba255, 0, 0, 0, 0.5)) + ]), + A2( + $elm$core$Maybe$withDefault, + _List_Nil, + A2( + $elm$core$Maybe$map, + A2($elm$core$Basics$composeR, $mdgriffith$elm_ui$Element$Events$onClick, $elm$core$List$singleton), + onDismiss))), + $mdgriffith$elm_ui$Element$none)), + $mdgriffith$elm_ui$Element$inFront(content), + $mdgriffith$elm_ui$Element$clip + ]); +}; +var $mdgriffith$elm_ui$Internal$Model$Describe = function (a) { + return {$: 'Describe', a: a}; +}; +var $mdgriffith$elm_ui$Internal$Model$Paragraph = {$: 'Paragraph'}; +var $mdgriffith$elm_ui$Internal$Model$SpacingStyle = F3( + function (a, b, c) { + return {$: 'SpacingStyle', a: a, b: b, c: c}; + }); +var $mdgriffith$elm_ui$Internal$Flag$spacing = $mdgriffith$elm_ui$Internal$Flag$flag(3); +var $mdgriffith$elm_ui$Internal$Model$spacingName = F2( + function (x, y) { + return 'spacing-' + ($elm$core$String$fromInt(x) + ('-' + $elm$core$String$fromInt(y))); + }); +var $mdgriffith$elm_ui$Element$spacing = function (x) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$spacing, + A3( + $mdgriffith$elm_ui$Internal$Model$SpacingStyle, + A2($mdgriffith$elm_ui$Internal$Model$spacingName, x, x), + x, + x)); +}; +var $mdgriffith$elm_ui$Element$paragraph = F2( + function (attrs, children) { + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asParagraph, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$Describe($mdgriffith$elm_ui$Internal$Model$Paragraph), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$spacing(5), + attrs))), + $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); + }); +var $mdgriffith$elm_ui$Internal$Model$AsRow = {$: 'AsRow'}; +var $mdgriffith$elm_ui$Internal$Model$asRow = $mdgriffith$elm_ui$Internal$Model$AsRow; +var $mdgriffith$elm_ui$Element$row = F2( + function (attrs, children) { + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asRow, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.contentCenterY)), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), + attrs))), + $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); + }); +var $mdgriffith$elm_ui$Internal$Model$Text = function (a) { + return {$: 'Text', a: a}; +}; +var $mdgriffith$elm_ui$Element$text = function (content) { + return $mdgriffith$elm_ui$Internal$Model$Text(content); +}; +var $mdgriffith$elm_ui$Internal$Model$Button = {$: 'Button'}; +var $elm$json$Json$Encode$bool = _Json_wrap; +var $elm$html$Html$Attributes$boolProperty = F2( + function (key, bool) { + return A2( + _VirtualDom_property, + key, + $elm$json$Json$Encode$bool(bool)); + }); +var $elm$html$Html$Attributes$disabled = $elm$html$Html$Attributes$boolProperty('disabled'); +var $mdgriffith$elm_ui$Element$Input$hasFocusStyle = function (attr) { + if (((attr.$ === 'StyleClass') && (attr.b.$ === 'PseudoSelector')) && (attr.b.a.$ === 'Focus')) { + var _v1 = attr.b; + var _v2 = _v1.a; + return true; + } else { + return false; + } +}; +var $mdgriffith$elm_ui$Element$Input$focusDefault = function (attrs) { + return A2($elm$core$List$any, $mdgriffith$elm_ui$Element$Input$hasFocusStyle, attrs) ? $mdgriffith$elm_ui$Internal$Model$NoAttribute : $mdgriffith$elm_ui$Internal$Model$htmlClass('focusable'); +}; var $mdgriffith$elm_ui$Element$Input$enter = 'Enter'; var $elm$json$Json$Decode$andThen = _Json_andThen; var $elm$json$Json$Decode$fail = _Json_fail; @@ -12655,24 +13314,14 @@ var $mdgriffith$elm_ui$Element$Input$onKey = F2( var $mdgriffith$elm_ui$Element$Input$onEnter = function (msg) { return A2($mdgriffith$elm_ui$Element$Input$onKey, $mdgriffith$elm_ui$Element$Input$enter, msg); }; -var $mdgriffith$elm_ui$Internal$Model$Class = F2( - function (a, b) { - return {$: 'Class', a: a, b: b}; - }); var $mdgriffith$elm_ui$Internal$Flag$cursor = $mdgriffith$elm_ui$Internal$Flag$flag(21); var $mdgriffith$elm_ui$Element$pointer = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$cursor, $mdgriffith$elm_ui$Internal$Style$classes.cursorPointer); -var $mdgriffith$elm_ui$Internal$Model$Content = {$: 'Content'}; -var $mdgriffith$elm_ui$Element$shrink = $mdgriffith$elm_ui$Internal$Model$Content; var $elm$html$Html$Attributes$tabindex = function (n) { return A2( _VirtualDom_attribute, 'tabIndex', $elm$core$String$fromInt(n)); }; -var $mdgriffith$elm_ui$Internal$Model$Width = function (a) { - return {$: 'Width', a: a}; -}; -var $mdgriffith$elm_ui$Element$width = $mdgriffith$elm_ui$Internal$Model$Width; var $mdgriffith$elm_ui$Element$Input$button = F2( function (attrs, _v0) { var onPress = _v0.onPress; @@ -12725,301 +13374,226 @@ var $mdgriffith$elm_ui$Element$Input$button = F2( _List_fromArray( [label]))); }); -var $mdgriffith$elm_ui$Internal$Model$CenterX = {$: 'CenterX'}; -var $mdgriffith$elm_ui$Element$centerX = $mdgriffith$elm_ui$Internal$Model$AlignX($mdgriffith$elm_ui$Internal$Model$CenterX); -var $mdgriffith$elm_ui$Internal$Model$AlignY = function (a) { - return {$: 'AlignY', a: a}; -}; -var $mdgriffith$elm_ui$Internal$Model$CenterY = {$: 'CenterY'}; -var $mdgriffith$elm_ui$Element$centerY = $mdgriffith$elm_ui$Internal$Model$AlignY($mdgriffith$elm_ui$Internal$Model$CenterY); -var $elm$svg$Svg$circle = $elm$svg$Svg$trustedNode('circle'); -var $elm$svg$Svg$Attributes$cx = _VirtualDom_attribute('cx'); -var $elm$svg$Svg$Attributes$cy = _VirtualDom_attribute('cy'); -var $elm$svg$Svg$Attributes$r = _VirtualDom_attribute('r'); -var $author$project$Icons$circle = A2( - $author$project$Icons$svgFeatherIcon, - 'circle', - _List_fromArray( - [ - A2( - $elm$svg$Svg$circle, - _List_fromArray( - [ - $elm$svg$Svg$Attributes$cx('12'), - $elm$svg$Svg$Attributes$cy('12'), - $elm$svg$Svg$Attributes$r('10') - ]), - _List_Nil) - ])); -var $mdgriffith$elm_ui$Internal$Model$AsColumn = {$: 'AsColumn'}; -var $mdgriffith$elm_ui$Internal$Model$asColumn = $mdgriffith$elm_ui$Internal$Model$AsColumn; -var $mdgriffith$elm_ui$Element$column = F2( - function (attrs, children) { - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asColumn, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentTop + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.contentLeft)), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), +var $elm$virtual_dom$VirtualDom$map = _VirtualDom_map; +var $mdgriffith$elm_ui$Internal$Model$map = F2( + function (fn, el) { + switch (el.$) { + case 'Styled': + var styled = el.a; + return $mdgriffith$elm_ui$Internal$Model$Styled( + { + html: F2( + function (add, context) { + return A2( + $elm$virtual_dom$VirtualDom$map, + fn, + A2(styled.html, add, context)); + }), + styles: styled.styles + }); + case 'Unstyled': + var html = el.a; + return $mdgriffith$elm_ui$Internal$Model$Unstyled( A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), - attrs))), - $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); - }); -var $mdgriffith$elm_ui$Internal$Model$Top = {$: 'Top'}; -var $mdgriffith$elm_ui$Element$alignTop = $mdgriffith$elm_ui$Internal$Model$AlignY($mdgriffith$elm_ui$Internal$Model$Top); -var $mdgriffith$elm_ui$Internal$Model$Fill = function (a) { - return {$: 'Fill', a: a}; -}; -var $mdgriffith$elm_ui$Element$fill = $mdgriffith$elm_ui$Internal$Model$Fill(1); -var $Orasund$elm_ui_framework$Framework$Grid$compact = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), - $mdgriffith$elm_ui$Element$alignTop - ]); -var $mdgriffith$elm_ui$Internal$Model$Colored = F3( - function (a, b, c) { - return {$: 'Colored', a: a, b: b, c: c}; - }); -var $mdgriffith$elm_ui$Internal$Model$StyleClass = F2( - function (a, b) { - return {$: 'StyleClass', a: a, b: b}; - }); -var $mdgriffith$elm_ui$Internal$Flag$bgColor = $mdgriffith$elm_ui$Internal$Flag$flag(8); -var $mdgriffith$elm_ui$Internal$Model$formatColorClass = function (_v0) { - var red = _v0.a; - var green = _v0.b; - var blue = _v0.c; - var alpha = _v0.d; - return $mdgriffith$elm_ui$Internal$Model$floatClass(red) + ('-' + ($mdgriffith$elm_ui$Internal$Model$floatClass(green) + ('-' + ($mdgriffith$elm_ui$Internal$Model$floatClass(blue) + ('-' + $mdgriffith$elm_ui$Internal$Model$floatClass(alpha)))))); -}; -var $mdgriffith$elm_ui$Element$Background$color = function (clr) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$bgColor, - A3( - $mdgriffith$elm_ui$Internal$Model$Colored, - 'bg-' + $mdgriffith$elm_ui$Internal$Model$formatColorClass(clr), - 'background-color', - clr)); -}; -var $mdgriffith$elm_ui$Internal$Model$Main = {$: 'Main'}; -var $mdgriffith$elm_ui$Element$Region$mainContent = $mdgriffith$elm_ui$Internal$Model$Describe($mdgriffith$elm_ui$Internal$Model$Main); -var $mdgriffith$elm_ui$Internal$Model$Max = F2( - function (a, b) { - return {$: 'Max', a: a, b: b}; - }); -var $mdgriffith$elm_ui$Element$maximum = F2( - function (i, l) { - return A2($mdgriffith$elm_ui$Internal$Model$Max, i, l); - }); -var $mdgriffith$elm_ui$Internal$Model$PaddingStyle = F5( - function (a, b, c, d, e) { - return {$: 'PaddingStyle', a: a, b: b, c: c, d: d, e: e}; - }); -var $mdgriffith$elm_ui$Internal$Flag$padding = $mdgriffith$elm_ui$Internal$Flag$flag(2); -var $mdgriffith$elm_ui$Element$padding = function (x) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$padding, - A5( - $mdgriffith$elm_ui$Internal$Model$PaddingStyle, - 'p-' + $elm$core$String$fromInt(x), - x, - x, - x, - x)); -}; -var $mdgriffith$elm_ui$Internal$Model$Rgba = F4( - function (a, b, c, d) { - return {$: 'Rgba', a: a, b: b, c: c, d: d}; - }); -var $mdgriffith$elm_ui$Element$rgb255 = F3( - function (red, green, blue) { - return A4($mdgriffith$elm_ui$Internal$Model$Rgba, red / 255, green / 255, blue / 255, 1); - }); -var $Orasund$elm_ui_framework$Framework$container = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$centerX, - $mdgriffith$elm_ui$Element$centerY, - $mdgriffith$elm_ui$Element$width( - A2($mdgriffith$elm_ui$Element$maximum, 1200, $mdgriffith$elm_ui$Element$fill)), - $mdgriffith$elm_ui$Element$padding(20), - $mdgriffith$elm_ui$Element$Region$mainContent, - $mdgriffith$elm_ui$Element$Background$color( - A3($mdgriffith$elm_ui$Element$rgb255, 255, 255, 255)) - ]); -var $elm_community$intdict$IntDict$findMin = function (dict) { - findMin: - while (true) { - switch (dict.$) { - case 'Empty': - return $elm$core$Maybe$Nothing; - case 'Leaf': - var l = dict.a; - return $elm$core$Maybe$Just( - _Utils_Tuple2(l.key, l.value)); + $elm$core$Basics$composeL, + $elm$virtual_dom$VirtualDom$map(fn), + html)); + case 'Text': + var str = el.a; + return $mdgriffith$elm_ui$Internal$Model$Text(str); default: - var i = dict.a; - var $temp$dict = i.left; - dict = $temp$dict; - continue findMin; - } - } -}; -var $elm_community$intdict$IntDict$after = F2( - function (key, dict) { - var go = F2( - function (def, currentDict) { - go: - while (true) { - switch (currentDict.$) { - case 'Empty': - return $elm_community$intdict$IntDict$findMin(def); - case 'Leaf': - var l = currentDict.a; - return (_Utils_cmp(l.key, key) < 1) ? $elm_community$intdict$IntDict$findMin(def) : $elm$core$Maybe$Just( - _Utils_Tuple2(l.key, l.value)); - default: - var i = currentDict.a; - if (!A2($elm_community$intdict$IntDict$prefixMatches, i.prefix, key)) { - return (_Utils_cmp(i.prefix.prefixBits, key) < 0) ? $elm_community$intdict$IntDict$findMin(def) : $elm_community$intdict$IntDict$findMin(i.left); - } else { - if (A2($elm_community$intdict$IntDict$isBranchingBitSet, i.prefix, key)) { - var $temp$def = def, - $temp$currentDict = i.right; - def = $temp$def; - currentDict = $temp$currentDict; - continue go; - } else { - var $temp$def = i.right, - $temp$currentDict = i.left; - def = $temp$def; - currentDict = $temp$currentDict; - continue go; - } - } - } - } - }); - return A2(go, $elm_community$intdict$IntDict$Empty, dict); - }); -var $elm$core$Maybe$andThen = F2( - function (callback, maybeValue) { - if (maybeValue.$ === 'Just') { - var value = maybeValue.a; - return callback(value); - } else { - return $elm$core$Maybe$Nothing; + return $mdgriffith$elm_ui$Internal$Model$Empty; } }); -var $elm_community$intdict$IntDict$findMax = function (dict) { - findMax: - while (true) { - switch (dict.$) { - case 'Empty': - return $elm$core$Maybe$Nothing; - case 'Leaf': - var l = dict.a; - return $elm$core$Maybe$Just( - _Utils_Tuple2(l.key, l.value)); - default: - var i = dict.a; - var $temp$dict = i.right; - dict = $temp$dict; - continue findMax; - } - } -}; -var $elm_community$intdict$IntDict$before = F2( - function (key, dict) { - var go = F2( - function (def, currentDict) { - go: - while (true) { - switch (currentDict.$) { - case 'Empty': - return $elm_community$intdict$IntDict$findMax(def); - case 'Leaf': - var l = currentDict.a; - return (_Utils_cmp(l.key, key) > -1) ? $elm_community$intdict$IntDict$findMax(def) : $elm$core$Maybe$Just( - _Utils_Tuple2(l.key, l.value)); - default: - var i = currentDict.a; - if (!A2($elm_community$intdict$IntDict$prefixMatches, i.prefix, key)) { - return (_Utils_cmp(i.prefix.prefixBits, key) > 0) ? $elm_community$intdict$IntDict$findMax(def) : $elm_community$intdict$IntDict$findMax(i.right); - } else { - if (A2($elm_community$intdict$IntDict$isBranchingBitSet, i.prefix, key)) { - var $temp$def = i.left, - $temp$currentDict = i.right; - def = $temp$def; - currentDict = $temp$currentDict; - continue go; - } else { - var $temp$def = def, - $temp$currentDict = i.left; - def = $temp$def; - currentDict = $temp$currentDict; - continue go; - } - } - } - } - }); - return A2(go, $elm_community$intdict$IntDict$Empty, dict); - }); -var $author$project$Widget$ScrollingNav$current = F2( - function (fromString, _v0) { - var positions = _v0.positions; - var scrollPos = _v0.scrollPos; +var $mdgriffith$elm_ui$Element$map = $mdgriffith$elm_ui$Internal$Model$map; +var $author$project$Internal$Button$button = F2( + function (style, _v0) { + var onPress = _v0.onPress; + var text = _v0.text; + var icon = _v0.icon; return A2( - $elm$core$Maybe$andThen, - fromString, - A2( - $elm$core$Maybe$map, - $elm$core$Tuple$second, - A2( - $elm$core$Maybe$withDefault, - A2($elm_community$intdict$IntDict$after, scrollPos + 1, positions), - A2( - $elm$core$Maybe$map, - $elm$core$Maybe$Just, - A2($elm_community$intdict$IntDict$before, scrollPos + 1, positions))))); + $mdgriffith$elm_ui$Element$Input$button, + _Utils_ap( + style.container, + _Utils_eq(onPress, $elm$core$Maybe$Nothing) ? style.ifDisabled : style.otherwise), + { + label: A2( + $mdgriffith$elm_ui$Element$row, + style.labelRow, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), + A2( + $mdgriffith$elm_ui$Element$el, + style.text, + $mdgriffith$elm_ui$Element$text(text)) + ])), + onPress: onPress + }); }); -var $mdgriffith$elm_ui$Element$el = F2( - function (attrs, child) { - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asEl, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), - A2( +var $author$project$Internal$Button$textButton = F2( + function (style, _v0) { + var onPress = _v0.onPress; + var text = _v0.text; + return A2( + $author$project$Internal$Button$button, + style, + {icon: $mdgriffith$elm_ui$Element$none, onPress: onPress, text: text}); + }); +var $author$project$Internal$Dialog$dialog = F2( + function (style, _v0) { + var title = _v0.title; + var text = _v0.text; + var accept = _v0.accept; + var dismiss = _v0.dismiss; + return $author$project$Internal$Dialog$modal( + { + content: A2( + $mdgriffith$elm_ui$Element$column, + _Utils_ap( + _List_fromArray( + [$mdgriffith$elm_ui$Element$centerX, $mdgriffith$elm_ui$Element$centerY]), + style.containerColumn), + _List_fromArray( + [ + A2( + $elm$core$Maybe$withDefault, + $mdgriffith$elm_ui$Element$none, + A2( + $elm$core$Maybe$map, + A2( + $elm$core$Basics$composeR, + $mdgriffith$elm_ui$Element$text, + $mdgriffith$elm_ui$Element$el(style.title)), + title)), + A2( + $mdgriffith$elm_ui$Element$paragraph, + style.text, + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text(text))), + A2( + $mdgriffith$elm_ui$Element$row, + _Utils_ap( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$alignRight, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink) + ]), + style.buttonRow), + function () { + var _v1 = _Utils_Tuple2(accept, dismiss); + if (_v1.a.$ === 'Just') { + if (_v1.b.$ === 'Nothing') { + var acceptButton = _v1.a.a; + var _v2 = _v1.b; + return $elm$core$List$singleton( + A2($author$project$Internal$Button$textButton, style.acceptButton, acceptButton)); + } else { + var acceptButton = _v1.a.a; + var dismissButton = _v1.b.a; + return _List_fromArray( + [ + A2($author$project$Internal$Button$textButton, style.dismissButton, dismissButton), + A2($author$project$Internal$Button$textButton, style.acceptButton, acceptButton) + ]); + } + } else { + return _List_Nil; + } + }()) + ])), + onDismiss: function () { + var _v3 = _Utils_Tuple2(accept, dismiss); + if (_v3.a.$ === 'Nothing') { + if (_v3.b.$ === 'Nothing') { + var _v4 = _v3.a; + var _v5 = _v3.b; + return $elm$core$Maybe$Nothing; + } else { + var _v6 = _v3.a; + var onPress = _v3.b.a.onPress; + return onPress; + } + } else { + return $elm$core$Maybe$Nothing; + } + }() + }); + }); +var $author$project$Widget$dialog = $author$project$Internal$Dialog$dialog; +var $elm$core$Array$fromListHelp = F3( + function (list, nodeList, nodeListSize) { + fromListHelp: + while (true) { + var _v0 = A2($elm$core$Elm$JsArray$initializeFromList, $elm$core$Array$branchFactor, list); + var jsArray = _v0.a; + var remainingItems = _v0.b; + if (_Utils_cmp( + $elm$core$Elm$JsArray$length(jsArray), + $elm$core$Array$branchFactor) < 0) { + return A2( + $elm$core$Array$builderToArray, + true, + {nodeList: nodeList, nodeListSize: nodeListSize, tail: jsArray}); + } else { + var $temp$list = remainingItems, + $temp$nodeList = A2( $elm$core$List$cons, - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), - attrs)), - $mdgriffith$elm_ui$Internal$Model$Unkeyed( - _List_fromArray( - [child]))); + $elm$core$Array$Leaf(jsArray), + nodeList), + $temp$nodeListSize = nodeListSize + 1; + list = $temp$list; + nodeList = $temp$nodeList; + nodeListSize = $temp$nodeListSize; + continue fromListHelp; + } + } }); -var $author$project$Data$Section$fromString = function (string) { - switch (string) { - case 'Component': - return $elm$core$Maybe$Just($author$project$Data$Section$ComponentViews); - case 'Reusable': - return $elm$core$Maybe$Just($author$project$Data$Section$ReusableViews); - case 'Stateless': - return $elm$core$Maybe$Just($author$project$Data$Section$StatelessViews); - default: - return $elm$core$Maybe$Nothing; +var $elm$core$Array$fromList = function (list) { + if (!list.b) { + return $elm$core$Array$empty; + } else { + return A3($elm$core$Array$fromListHelp, list, _List_Nil, 0); } }; +var $elm$core$Array$bitMask = 4294967295 >>> (32 - $elm$core$Array$shiftStep); +var $elm$core$Elm$JsArray$unsafeGet = _JsArray_unsafeGet; +var $elm$core$Array$getHelp = F3( + function (shift, index, tree) { + getHelp: + while (true) { + var pos = $elm$core$Array$bitMask & (index >>> shift); + var _v0 = A2($elm$core$Elm$JsArray$unsafeGet, pos, tree); + if (_v0.$ === 'SubTree') { + var subTree = _v0.a; + var $temp$shift = shift - $elm$core$Array$shiftStep, + $temp$index = index, + $temp$tree = subTree; + shift = $temp$shift; + index = $temp$index; + tree = $temp$tree; + continue getHelp; + } else { + var values = _v0.a; + return A2($elm$core$Elm$JsArray$unsafeGet, $elm$core$Array$bitMask & index, values); + } + } + }); +var $elm$core$Array$tailIndex = function (len) { + return (len >>> 5) << 5; +}; +var $elm$core$Array$get = F2( + function (index, _v0) { + var len = _v0.a; + var startShift = _v0.b; + var tree = _v0.c; + var tail = _v0.d; + return ((index < 0) || (_Utils_cmp(index, len) > -1)) ? $elm$core$Maybe$Nothing : ((_Utils_cmp( + index, + $elm$core$Array$tailIndex(len)) > -1) ? $elm$core$Maybe$Just( + A2($elm$core$Elm$JsArray$unsafeGet, $elm$core$Array$bitMask & index, tail)) : $elm$core$Maybe$Just( + A3($elm$core$Array$getHelp, startShift, index, tree))); + }); var $author$project$Icons$github = A2( $author$project$Icons$svgFeatherIcon, 'github', @@ -13045,6 +13619,11 @@ var $mdgriffith$elm_ui$Internal$Model$Heading = function (a) { return {$: 'Heading', a: a}; }; var $mdgriffith$elm_ui$Element$Region$heading = A2($elm$core$Basics$composeL, $mdgriffith$elm_ui$Internal$Model$Describe, $mdgriffith$elm_ui$Internal$Model$Heading); +var $mdgriffith$elm_ui$Internal$Model$PaddingStyle = F5( + function (a, b, c, d, e) { + return {$: 'PaddingStyle', a: a, b: b, c: c, d: d, e: e}; + }); +var $mdgriffith$elm_ui$Internal$Flag$padding = $mdgriffith$elm_ui$Internal$Flag$flag(2); var $mdgriffith$elm_ui$Internal$Model$paddingName = F4( function (top, right, bottom, left) { return 'pad-' + ($elm$core$String$fromInt(top) + ('-' + ($elm$core$String$fromInt(right) + ('-' + ($elm$core$String$fromInt(bottom) + ('-' + $elm$core$String$fromInt(left))))))); @@ -13098,26 +13677,66 @@ var $Orasund$elm_ui_framework$Framework$Heading$h = function (inputLevel) { ]); }; var $Orasund$elm_ui_framework$Framework$Heading$h1 = $Orasund$elm_ui_framework$Framework$Heading$h(1); -var $Orasund$elm_ui_framework$Framework$Heading$h3 = $Orasund$elm_ui_framework$Framework$Heading$h(3); -var $elm$core$List$head = function (list) { - if (list.b) { - var x = list.a; - var xs = list.b; - return $elm$core$Maybe$Just(x); - } else { - return $elm$core$Maybe$Nothing; - } -}; var $mdgriffith$elm_ui$Internal$Model$unstyled = A2($elm$core$Basics$composeL, $mdgriffith$elm_ui$Internal$Model$Unstyled, $elm$core$Basics$always); var $mdgriffith$elm_ui$Element$html = $mdgriffith$elm_ui$Internal$Model$unstyled; -var $mdgriffith$elm_ui$Internal$Model$Min = F2( - function (a, b) { - return {$: 'Min', a: a, b: b}; - }); -var $mdgriffith$elm_ui$Element$minimum = F2( - function (i, l) { - return A2($mdgriffith$elm_ui$Internal$Model$Min, i, l); +var $elm$html$Html$map = $elm$virtual_dom$VirtualDom$map; +var $elm$svg$Svg$circle = $elm$svg$Svg$trustedNode('circle'); +var $elm$svg$Svg$Attributes$cx = _VirtualDom_attribute('cx'); +var $elm$svg$Svg$Attributes$cy = _VirtualDom_attribute('cy'); +var $elm$svg$Svg$Attributes$r = _VirtualDom_attribute('r'); +var $author$project$Icons$penTool = A2( + $author$project$Icons$svgFeatherIcon, + 'pen-tool', + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M12 19l7-7 3 3-7 7-3-3z') + ]), + _List_Nil), + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z') + ]), + _List_Nil), + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M2 2l7.586 7.586') + ]), + _List_Nil), + A2( + $elm$svg$Svg$circle, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$cx('11'), + $elm$svg$Svg$Attributes$cy('11'), + $elm$svg$Svg$Attributes$r('2') + ]), + _List_Nil) + ])); +var $elm$html$Html$Attributes$attribute = $elm$virtual_dom$VirtualDom$attribute; +var $mdgriffith$elm_ui$Internal$Flag$fontColor = $mdgriffith$elm_ui$Internal$Flag$flag(14); +var $mdgriffith$elm_ui$Element$Font$color = function (fontColor) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$fontColor, + A3( + $mdgriffith$elm_ui$Internal$Model$Colored, + 'fc-' + $mdgriffith$elm_ui$Internal$Model$formatColorClass(fontColor), + 'color', + fontColor)); +}; +var $mdgriffith$elm_ui$Element$rgb255 = F3( + function (red, green, blue) { + return A4($mdgriffith$elm_ui$Internal$Model$Rgba, red / 255, green / 255, blue / 255, 1); }); +var $Orasund$elm_ui_framework$Framework$Color$darkerGrey = A3($mdgriffith$elm_ui$Element$rgb255, 18, 18, 18); var $mdgriffith$elm_ui$Internal$Flag$borderColor = $mdgriffith$elm_ui$Internal$Flag$flag(28); var $mdgriffith$elm_ui$Element$Border$color = function (clr) { return A2( @@ -13135,218 +13754,6 @@ var $Orasund$elm_ui_framework$Framework$Color$light = _List_fromArray( $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$lighterGrey), $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lighterGrey) ]); -var $Orasund$elm_ui_framework$Framework$Color$lightGrey = A3($mdgriffith$elm_ui$Element$rgb255, 219, 219, 219); -var $mdgriffith$elm_ui$Element$rgba = $mdgriffith$elm_ui$Internal$Model$Rgba; -var $mdgriffith$elm_ui$Internal$Model$boxShadowClass = function (shadow) { - return $elm$core$String$concat( - _List_fromArray( - [ - shadow.inset ? 'box-inset' : 'box-', - $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.offset.a) + 'px', - $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.offset.b) + 'px', - $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.blur) + 'px', - $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.size) + 'px', - $mdgriffith$elm_ui$Internal$Model$formatColorClass(shadow.color) - ])); -}; -var $mdgriffith$elm_ui$Internal$Flag$shadows = $mdgriffith$elm_ui$Internal$Flag$flag(19); -var $mdgriffith$elm_ui$Element$Border$shadow = function (almostShade) { - var shade = {blur: almostShade.blur, color: almostShade.color, inset: false, offset: almostShade.offset, size: almostShade.size}; - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$shadows, - A3( - $mdgriffith$elm_ui$Internal$Model$Single, - $mdgriffith$elm_ui$Internal$Model$boxShadowClass(shade), - 'box-shadow', - $mdgriffith$elm_ui$Internal$Model$formatBoxShadow(shade))); -}; -var $mdgriffith$elm_ui$Element$paddingXY = F2( - function (x, y) { - return _Utils_eq(x, y) ? A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$padding, - A5( - $mdgriffith$elm_ui$Internal$Model$PaddingStyle, - 'p-' + $elm$core$String$fromInt(x), - x, - x, - x, - x)) : A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$padding, - A5( - $mdgriffith$elm_ui$Internal$Model$PaddingStyle, - 'p-' + ($elm$core$String$fromInt(x) + ('-' + $elm$core$String$fromInt(y))), - y, - x, - y, - x)); - }); -var $mdgriffith$elm_ui$Internal$Flag$borderRound = $mdgriffith$elm_ui$Internal$Flag$flag(17); -var $mdgriffith$elm_ui$Element$Border$rounded = function (radius) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$borderRound, - A3( - $mdgriffith$elm_ui$Internal$Model$Single, - 'br-' + $elm$core$String$fromInt(radius), - 'border-radius', - $elm$core$String$fromInt(radius) + 'px')); -}; -var $Orasund$elm_ui_framework$Framework$Color$simple = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$lightGrey), - $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lightGrey) - ]); -var $Orasund$elm_ui_framework$Framework$Tag$simple = _Utils_ap( - $Orasund$elm_ui_framework$Framework$Color$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$rounded(4), - A2($mdgriffith$elm_ui$Element$paddingXY, 7, 4) - ])); -var $mdgriffith$elm_ui$Internal$Model$BorderWidth = F5( - function (a, b, c, d, e) { - return {$: 'BorderWidth', a: a, b: b, c: c, d: d, e: e}; - }); -var $mdgriffith$elm_ui$Element$Border$width = function (v) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$borderWidth, - A5( - $mdgriffith$elm_ui$Internal$Model$BorderWidth, - 'b-' + $elm$core$String$fromInt(v), - v, - v, - v, - v)); -}; -var $Orasund$elm_ui_framework$Framework$Card$simple = _Utils_ap( - $Orasund$elm_ui_framework$Framework$Tag$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Color$light, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$shadow( - { - blur: 10, - color: A4($mdgriffith$elm_ui$Element$rgba, 0, 0, 0, 0.05), - offset: _Utils_Tuple2(0, 2), - size: 1 - }), - $mdgriffith$elm_ui$Element$Border$width(1), - $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lightGrey), - $mdgriffith$elm_ui$Element$alignTop, - $mdgriffith$elm_ui$Element$padding(20), - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) - ]))); -var $Orasund$elm_ui_framework$Framework$Card$withSize = function (_int) { - return _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$width( - A2( - $mdgriffith$elm_ui$Element$minimum, - 240, - A2($mdgriffith$elm_ui$Element$maximum, _int, $mdgriffith$elm_ui$Element$fill))) - ])); -}; -var $Orasund$elm_ui_framework$Framework$Card$large = $Orasund$elm_ui_framework$Framework$Card$withSize(480); -var $mdgriffith$elm_ui$Internal$Model$Empty = {$: 'Empty'}; -var $mdgriffith$elm_ui$Internal$Model$Text = function (a) { - return {$: 'Text', a: a}; -}; -var $elm$virtual_dom$VirtualDom$map = _VirtualDom_map; -var $mdgriffith$elm_ui$Internal$Model$map = F2( - function (fn, el) { - switch (el.$) { - case 'Styled': - var styled = el.a; - return $mdgriffith$elm_ui$Internal$Model$Styled( - { - html: F2( - function (add, context) { - return A2( - $elm$virtual_dom$VirtualDom$map, - fn, - A2(styled.html, add, context)); - }), - styles: styled.styles - }); - case 'Unstyled': - var html = el.a; - return $mdgriffith$elm_ui$Internal$Model$Unstyled( - A2( - $elm$core$Basics$composeL, - $elm$virtual_dom$VirtualDom$map(fn), - html)); - case 'Text': - var str = el.a; - return $mdgriffith$elm_ui$Internal$Model$Text(str); - default: - return $mdgriffith$elm_ui$Internal$Model$Empty; - } - }); -var $mdgriffith$elm_ui$Element$map = $mdgriffith$elm_ui$Internal$Model$map; -var $elm$html$Html$map = $elm$virtual_dom$VirtualDom$map; -var $mdgriffith$elm_ui$Element$none = $mdgriffith$elm_ui$Internal$Model$Empty; -var $mdgriffith$elm_ui$Internal$Model$Paragraph = {$: 'Paragraph'}; -var $mdgriffith$elm_ui$Internal$Model$SpacingStyle = F3( - function (a, b, c) { - return {$: 'SpacingStyle', a: a, b: b, c: c}; - }); -var $mdgriffith$elm_ui$Internal$Flag$spacing = $mdgriffith$elm_ui$Internal$Flag$flag(3); -var $mdgriffith$elm_ui$Internal$Model$spacingName = F2( - function (x, y) { - return 'spacing-' + ($elm$core$String$fromInt(x) + ('-' + $elm$core$String$fromInt(y))); - }); -var $mdgriffith$elm_ui$Element$spacing = function (x) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$spacing, - A3( - $mdgriffith$elm_ui$Internal$Model$SpacingStyle, - A2($mdgriffith$elm_ui$Internal$Model$spacingName, x, x), - x, - x)); -}; -var $mdgriffith$elm_ui$Element$paragraph = F2( - function (attrs, children) { - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asParagraph, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$Describe($mdgriffith$elm_ui$Internal$Model$Paragraph), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$spacing(5), - attrs))), - $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); - }); -var $mdgriffith$elm_ui$Internal$Model$Px = function (a) { - return {$: 'Px', a: a}; -}; -var $mdgriffith$elm_ui$Element$px = $mdgriffith$elm_ui$Internal$Model$Px; -var $elm$html$Html$Attributes$attribute = $elm$virtual_dom$VirtualDom$attribute; -var $mdgriffith$elm_ui$Internal$Flag$fontColor = $mdgriffith$elm_ui$Internal$Flag$flag(14); -var $mdgriffith$elm_ui$Element$Font$color = function (fontColor) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$fontColor, - A3( - $mdgriffith$elm_ui$Internal$Model$Colored, - 'fc-' + $mdgriffith$elm_ui$Internal$Model$formatColorClass(fontColor), - 'color', - fontColor)); -}; -var $Orasund$elm_ui_framework$Framework$Color$darkerGrey = A3($mdgriffith$elm_ui$Element$rgb255, 18, 18, 18); var $Orasund$elm_ui_framework$Framework$layoutAttributes = _Utils_ap( _List_fromArray( [ @@ -13358,10 +13765,6 @@ var $mdgriffith$elm_ui$Internal$Model$FocusStyleOption = function (a) { return {$: 'FocusStyleOption', a: a}; }; var $mdgriffith$elm_ui$Element$focusStyle = $mdgriffith$elm_ui$Internal$Model$FocusStyleOption; -var $elm$core$List$singleton = function (value) { - return _List_fromArray( - [value]); -}; var $Orasund$elm_ui_framework$Framework$Color$turquoise = A3($mdgriffith$elm_ui$Element$rgb255, 0, 209, 178); var $Orasund$elm_ui_framework$Framework$layoutOptions = $elm$core$List$singleton( $mdgriffith$elm_ui$Element$focusStyle( @@ -13652,19 +14055,284 @@ var $Orasund$elm_ui_framework$Framework$responsiveLayout = F2( A2($Orasund$elm_ui_framework$Framework$layout, attributes, view) ])); }); -var $mdgriffith$elm_ui$Internal$Flag$fontAlignment = $mdgriffith$elm_ui$Internal$Flag$flag(12); -var $mdgriffith$elm_ui$Element$Font$center = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$fontAlignment, $mdgriffith$elm_ui$Internal$Style$classes.textCenter); -var $Orasund$elm_ui_framework$Framework$Color$grey = A3($mdgriffith$elm_ui$Element$rgb255, 122, 122, 122); -var $mdgriffith$elm_ui$Internal$Model$Hover = {$: 'Hover'}; +var $elm_community$intdict$IntDict$findMin = function (dict) { + findMin: + while (true) { + switch (dict.$) { + case 'Empty': + return $elm$core$Maybe$Nothing; + case 'Leaf': + var l = dict.a; + return $elm$core$Maybe$Just( + _Utils_Tuple2(l.key, l.value)); + default: + var i = dict.a; + var $temp$dict = i.left; + dict = $temp$dict; + continue findMin; + } + } +}; +var $elm_community$intdict$IntDict$after = F2( + function (key, dict) { + var go = F2( + function (def, currentDict) { + go: + while (true) { + switch (currentDict.$) { + case 'Empty': + return $elm_community$intdict$IntDict$findMin(def); + case 'Leaf': + var l = currentDict.a; + return (_Utils_cmp(l.key, key) < 1) ? $elm_community$intdict$IntDict$findMin(def) : $elm$core$Maybe$Just( + _Utils_Tuple2(l.key, l.value)); + default: + var i = currentDict.a; + if (!A2($elm_community$intdict$IntDict$prefixMatches, i.prefix, key)) { + return (_Utils_cmp(i.prefix.prefixBits, key) < 0) ? $elm_community$intdict$IntDict$findMin(def) : $elm_community$intdict$IntDict$findMin(i.left); + } else { + if (A2($elm_community$intdict$IntDict$isBranchingBitSet, i.prefix, key)) { + var $temp$def = def, + $temp$currentDict = i.right; + def = $temp$def; + currentDict = $temp$currentDict; + continue go; + } else { + var $temp$def = i.right, + $temp$currentDict = i.left; + def = $temp$def; + currentDict = $temp$currentDict; + continue go; + } + } + } + } + }); + return A2(go, $elm_community$intdict$IntDict$Empty, dict); + }); +var $elm$core$Maybe$andThen = F2( + function (callback, maybeValue) { + if (maybeValue.$ === 'Just') { + var value = maybeValue.a; + return callback(value); + } else { + return $elm$core$Maybe$Nothing; + } + }); +var $elm_community$intdict$IntDict$findMax = function (dict) { + findMax: + while (true) { + switch (dict.$) { + case 'Empty': + return $elm$core$Maybe$Nothing; + case 'Leaf': + var l = dict.a; + return $elm$core$Maybe$Just( + _Utils_Tuple2(l.key, l.value)); + default: + var i = dict.a; + var $temp$dict = i.right; + dict = $temp$dict; + continue findMax; + } + } +}; +var $elm_community$intdict$IntDict$before = F2( + function (key, dict) { + var go = F2( + function (def, currentDict) { + go: + while (true) { + switch (currentDict.$) { + case 'Empty': + return $elm_community$intdict$IntDict$findMax(def); + case 'Leaf': + var l = currentDict.a; + return (_Utils_cmp(l.key, key) > -1) ? $elm_community$intdict$IntDict$findMax(def) : $elm$core$Maybe$Just( + _Utils_Tuple2(l.key, l.value)); + default: + var i = currentDict.a; + if (!A2($elm_community$intdict$IntDict$prefixMatches, i.prefix, key)) { + return (_Utils_cmp(i.prefix.prefixBits, key) > 0) ? $elm_community$intdict$IntDict$findMax(def) : $elm_community$intdict$IntDict$findMax(i.right); + } else { + if (A2($elm_community$intdict$IntDict$isBranchingBitSet, i.prefix, key)) { + var $temp$def = i.left, + $temp$currentDict = i.right; + def = $temp$def; + currentDict = $temp$currentDict; + continue go; + } else { + var $temp$def = def, + $temp$currentDict = i.left; + def = $temp$def; + currentDict = $temp$currentDict; + continue go; + } + } + } + } + }); + return A2(go, $elm_community$intdict$IntDict$Empty, dict); + }); +var $author$project$Widget$ScrollingNav$current = F2( + function (fromString, _v0) { + var positions = _v0.positions; + var scrollPos = _v0.scrollPos; + return A2( + $elm$core$Maybe$andThen, + fromString, + A2( + $elm$core$Maybe$map, + $elm$core$Tuple$second, + A2( + $elm$core$Maybe$withDefault, + A2($elm_community$intdict$IntDict$after, scrollPos + 1, positions), + A2( + $elm$core$Maybe$map, + $elm$core$Maybe$Just, + A2($elm_community$intdict$IntDict$before, scrollPos + 1, positions))))); + }); +var $elm$core$List$head = function (list) { + if (list.b) { + var x = list.a; + var xs = list.b; + return $elm$core$Maybe$Just(x); + } else { + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Widget$ScrollingNav$toSelect = F2( + function (onSelect, model) { + var arrangement = model.arrangement; + var toString = model.toString; + var fromString = model.fromString; + return { + onSelect: onSelect, + options: A2( + $elm$core$List$map, + function (s) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: toString(s) + }; + }, + arrangement), + selected: $elm$core$List$head( + A2( + $elm$core$List$filterMap, + function (_v0) { + var i = _v0.a; + var s = _v0.b; + return _Utils_eq( + $elm$core$Maybe$Just(s), + A2($author$project$Widget$ScrollingNav$current, fromString, model)) ? $elm$core$Maybe$Just(i) : $elm$core$Maybe$Nothing; + }, + A2( + $elm$core$List$indexedMap, + F2( + function (i, s) { + return _Utils_Tuple2(i, s); + }), + arrangement))) + }; + }); +var $avh4$elm_color$Color$RgbaSpace = F4( + function (a, b, c, d) { + return {$: 'RgbaSpace', a: a, b: b, c: c, d: d}; + }); +var $avh4$elm_color$Color$scaleFrom255 = function (c) { + return c / 255; +}; +var $avh4$elm_color$Color$rgb255 = F3( + function (r, g, b) { + return A4( + $avh4$elm_color$Color$RgbaSpace, + $avh4$elm_color$Color$scaleFrom255(r), + $avh4$elm_color$Color$scaleFrom255(g), + $avh4$elm_color$Color$scaleFrom255(b), + 1.0); + }); +var $author$project$Widget$Style$Material$darkPalette = { + background: A3($avh4$elm_color$Color$rgb255, 18, 18, 18), + error: A3($avh4$elm_color$Color$rgb255, 207, 102, 121), + on: { + background: A3($avh4$elm_color$Color$rgb255, 255, 255, 255), + error: A3($avh4$elm_color$Color$rgb255, 0, 0, 0), + primary: A3($avh4$elm_color$Color$rgb255, 0, 0, 0), + secondary: A3($avh4$elm_color$Color$rgb255, 0, 0, 0), + surface: A3($avh4$elm_color$Color$rgb255, 255, 255, 255) + }, + primary: A3($avh4$elm_color$Color$rgb255, 187, 134, 252), + secondary: A3($avh4$elm_color$Color$rgb255, 3, 218, 198), + surface: A3($avh4$elm_color$Color$rgb255, 18, 18, 18) +}; +var $author$project$Widget$Style$Material$defaultPalette = { + background: A3($avh4$elm_color$Color$rgb255, 255, 255, 255), + error: A3($avh4$elm_color$Color$rgb255, 176, 0, 32), + on: { + background: A3($avh4$elm_color$Color$rgb255, 0, 0, 0), + error: A3($avh4$elm_color$Color$rgb255, 255, 255, 255), + primary: A3($avh4$elm_color$Color$rgb255, 255, 255, 255), + secondary: A3($avh4$elm_color$Color$rgb255, 0, 0, 0), + surface: A3($avh4$elm_color$Color$rgb255, 0, 0, 0) + }, + primary: A3($avh4$elm_color$Color$rgb255, 98, 0, 238), + secondary: A3($avh4$elm_color$Color$rgb255, 3, 218, 198), + surface: A3($avh4$elm_color$Color$rgb255, 255, 255, 255) +}; +var $mdgriffith$elm_ui$Internal$Flag$borderRound = $mdgriffith$elm_ui$Internal$Flag$flag(17); +var $mdgriffith$elm_ui$Element$Border$rounded = function (radius) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$borderRound, + A3( + $mdgriffith$elm_ui$Internal$Model$Single, + 'br-' + $elm$core$String$fromInt(radius), + 'border-radius', + $elm$core$String$fromInt(radius) + 'px')); +}; +var $Orasund$elm_ui_framework$Framework$Group$center = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$rounded(0) + ]); +var $mdgriffith$elm_ui$Internal$Model$Top = {$: 'Top'}; +var $mdgriffith$elm_ui$Element$alignTop = $mdgriffith$elm_ui$Internal$Model$AlignY($mdgriffith$elm_ui$Internal$Model$Top); +var $Orasund$elm_ui_framework$Framework$Grid$compact = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$alignTop + ]); +var $mdgriffith$elm_ui$Element$Border$roundEach = function (_v0) { + var topLeft = _v0.topLeft; + var topRight = _v0.topRight; + var bottomLeft = _v0.bottomLeft; + var bottomRight = _v0.bottomRight; + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$borderRound, + A3( + $mdgriffith$elm_ui$Internal$Model$Single, + 'br-' + ($elm$core$String$fromInt(topLeft) + ('-' + ($elm$core$String$fromInt(topRight) + ($elm$core$String$fromInt(bottomLeft) + ('-' + $elm$core$String$fromInt(bottomRight)))))), + 'border-radius', + $elm$core$String$fromInt(topLeft) + ('px ' + ($elm$core$String$fromInt(topRight) + ('px ' + ($elm$core$String$fromInt(bottomRight) + ('px ' + ($elm$core$String$fromInt(bottomLeft) + 'px')))))))); +}; +var $Orasund$elm_ui_framework$Framework$Group$left = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 4, bottomRight: 0, topLeft: 4, topRight: 0}) + ]); +var $Orasund$elm_ui_framework$Framework$Group$right = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 0, bottomRight: 4, topLeft: 0, topRight: 4}) + ]); +var $author$project$Data$Style$ElmUiFramework$buttonRow = {containerRow: $Orasund$elm_ui_framework$Framework$Grid$compact, element: _List_Nil, ifFirst: $Orasund$elm_ui_framework$Framework$Group$left, ifLast: $Orasund$elm_ui_framework$Framework$Group$right, otherwise: $Orasund$elm_ui_framework$Framework$Group$center}; +var $mdgriffith$elm_ui$Internal$Model$Focus = {$: 'Focus'}; var $mdgriffith$elm_ui$Internal$Model$PseudoSelector = F2( function (a, b) { return {$: 'PseudoSelector', a: a, b: b}; }); -var $mdgriffith$elm_ui$Internal$Flag$hover = $mdgriffith$elm_ui$Internal$Flag$flag(33); -var $mdgriffith$elm_ui$Internal$Model$Nearby = F2( - function (a, b) { - return {$: 'Nearby', a: a, b: b}; - }); +var $mdgriffith$elm_ui$Internal$Flag$focus = $mdgriffith$elm_ui$Internal$Flag$flag(31); var $mdgriffith$elm_ui$Internal$Model$TransformComponent = F2( function (a, b) { return {$: 'TransformComponent', a: a, b: b}; @@ -13752,6 +14420,19 @@ var $mdgriffith$elm_ui$Internal$Model$unwrapDecorations = function (attrs) { $mdgriffith$elm_ui$Internal$Model$Transform(transform), styles); }; +var $mdgriffith$elm_ui$Element$focused = function (decs) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$focus, + A2( + $mdgriffith$elm_ui$Internal$Model$PseudoSelector, + $mdgriffith$elm_ui$Internal$Model$Focus, + $mdgriffith$elm_ui$Internal$Model$unwrapDecorations(decs))); +}; +var $Orasund$elm_ui_framework$Framework$Color$grey = A3($mdgriffith$elm_ui$Element$rgb255, 122, 122, 122); +var $mdgriffith$elm_ui$Element$htmlAttribute = $mdgriffith$elm_ui$Internal$Model$Attr; +var $mdgriffith$elm_ui$Internal$Model$Hover = {$: 'Hover'}; +var $mdgriffith$elm_ui$Internal$Flag$hover = $mdgriffith$elm_ui$Internal$Flag$flag(33); var $mdgriffith$elm_ui$Element$mouseOver = function (decs) { return A2( $mdgriffith$elm_ui$Internal$Model$StyleClass, @@ -13761,6 +14442,132 @@ var $mdgriffith$elm_ui$Element$mouseOver = function (decs) { $mdgriffith$elm_ui$Internal$Model$Hover, $mdgriffith$elm_ui$Internal$Model$unwrapDecorations(decs))); }; +var $Orasund$elm_ui_framework$Framework$Color$lightGrey = A3($mdgriffith$elm_ui$Element$rgb255, 219, 219, 219); +var $Orasund$elm_ui_framework$Framework$Color$simple = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$lightGrey), + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lightGrey) + ]); +var $elm$virtual_dom$VirtualDom$style = _VirtualDom_style; +var $elm$html$Html$Attributes$style = $elm$virtual_dom$VirtualDom$style; +var $Orasund$elm_ui_framework$Framework$Color$disabled = _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color($Orasund$elm_ui_framework$Framework$Color$grey), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil), + $mdgriffith$elm_ui$Element$htmlAttribute( + A2($elm$html$Html$Attributes$style, 'cursor', 'not-allowed')) + ])); +var $Orasund$elm_ui_framework$Framework$Color$primary = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$turquoise), + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$turquoise) + ]); +var $mdgriffith$elm_ui$Internal$Flag$fontAlignment = $mdgriffith$elm_ui$Internal$Flag$flag(12); +var $mdgriffith$elm_ui$Element$Font$center = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$fontAlignment, $mdgriffith$elm_ui$Internal$Style$classes.textCenter); +var $mdgriffith$elm_ui$Element$paddingXY = F2( + function (x, y) { + return _Utils_eq(x, y) ? A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$padding, + A5( + $mdgriffith$elm_ui$Internal$Model$PaddingStyle, + 'p-' + $elm$core$String$fromInt(x), + x, + x, + x, + x)) : A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$padding, + A5( + $mdgriffith$elm_ui$Internal$Model$PaddingStyle, + 'p-' + ($elm$core$String$fromInt(x) + ('-' + $elm$core$String$fromInt(y))), + y, + x, + y, + x)); + }); +var $mdgriffith$elm_ui$Element$padding = function (x) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$padding, + A5( + $mdgriffith$elm_ui$Internal$Model$PaddingStyle, + 'p-' + $elm$core$String$fromInt(x), + x, + x, + x, + x)); +}; +var $mdgriffith$elm_ui$Element$rgba = $mdgriffith$elm_ui$Internal$Model$Rgba; +var $mdgriffith$elm_ui$Internal$Model$boxShadowClass = function (shadow) { + return $elm$core$String$concat( + _List_fromArray( + [ + shadow.inset ? 'box-inset' : 'box-', + $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.offset.a) + 'px', + $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.offset.b) + 'px', + $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.blur) + 'px', + $mdgriffith$elm_ui$Internal$Model$floatClass(shadow.size) + 'px', + $mdgriffith$elm_ui$Internal$Model$formatColorClass(shadow.color) + ])); +}; +var $mdgriffith$elm_ui$Internal$Flag$shadows = $mdgriffith$elm_ui$Internal$Flag$flag(19); +var $mdgriffith$elm_ui$Element$Border$shadow = function (almostShade) { + var shade = {blur: almostShade.blur, color: almostShade.color, inset: false, offset: almostShade.offset, size: almostShade.size}; + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$shadows, + A3( + $mdgriffith$elm_ui$Internal$Model$Single, + $mdgriffith$elm_ui$Internal$Model$boxShadowClass(shade), + 'box-shadow', + $mdgriffith$elm_ui$Internal$Model$formatBoxShadow(shade))); +}; +var $Orasund$elm_ui_framework$Framework$Tag$simple = _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$rounded(4), + A2($mdgriffith$elm_ui$Element$paddingXY, 7, 4) + ])); +var $mdgriffith$elm_ui$Internal$Model$BorderWidth = F5( + function (a, b, c, d, e) { + return {$: 'BorderWidth', a: a, b: b, c: c, d: d, e: e}; + }); +var $mdgriffith$elm_ui$Element$Border$width = function (v) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$borderWidth, + A5( + $mdgriffith$elm_ui$Internal$Model$BorderWidth, + 'b-' + $elm$core$String$fromInt(v), + v, + v, + v, + v)); +}; +var $Orasund$elm_ui_framework$Framework$Card$simple = _Utils_ap( + $Orasund$elm_ui_framework$Framework$Tag$simple, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$light, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + { + blur: 10, + color: A4($mdgriffith$elm_ui$Element$rgba, 0, 0, 0, 0.05), + offset: _Utils_Tuple2(0, 2), + size: 1 + }), + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lightGrey), + $mdgriffith$elm_ui$Element$alignTop, + $mdgriffith$elm_ui$Element$padding(20), + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) + ]))); var $Orasund$elm_ui_framework$Framework$Button$simple = _Utils_ap( $Orasund$elm_ui_framework$Framework$Card$simple, _Utils_ap( @@ -13775,39 +14582,203 @@ var $Orasund$elm_ui_framework$Framework$Button$simple = _Utils_ap( ])), A2($mdgriffith$elm_ui$Element$paddingXY, 16, 12) ]))); +var $author$project$Data$Style$ElmUiFramework$buttonStyle = { + container: $Orasund$elm_ui_framework$Framework$Button$simple, + ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8) + ]), + otherwise: _List_Nil, + text: _List_Nil +}; +var $Orasund$elm_ui_framework$Framework$Group$bottom = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 4, bottomRight: 4, topLeft: 0, topRight: 0}) + ]); +var $mdgriffith$elm_ui$Internal$Model$Max = F2( + function (a, b) { + return {$: 'Max', a: a, b: b}; + }); +var $mdgriffith$elm_ui$Element$maximum = F2( + function (i, l) { + return A2($mdgriffith$elm_ui$Internal$Model$Max, i, l); + }); +var $mdgriffith$elm_ui$Internal$Model$Min = F2( + function (a, b) { + return {$: 'Min', a: a, b: b}; + }); +var $mdgriffith$elm_ui$Element$minimum = F2( + function (i, l) { + return A2($mdgriffith$elm_ui$Internal$Model$Min, i, l); + }); +var $Orasund$elm_ui_framework$Framework$Card$withSize = function (_int) { + return _Utils_ap( + $Orasund$elm_ui_framework$Framework$Card$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width( + A2( + $mdgriffith$elm_ui$Element$minimum, + 240, + A2($mdgriffith$elm_ui$Element$maximum, _int, $mdgriffith$elm_ui$Element$fill))) + ])); +}; +var $Orasund$elm_ui_framework$Framework$Card$large = $Orasund$elm_ui_framework$Framework$Card$withSize(480); +var $Orasund$elm_ui_framework$Framework$Group$top = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 0, bottomRight: 0, topLeft: 4, topRight: 4}) + ]); +var $author$project$Data$Style$ElmUiFramework$cardColumn = { + containerColumn: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$compact, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) + ])), + element: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Card$large, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) + ])), + ifFirst: $Orasund$elm_ui_framework$Framework$Group$top, + ifLast: $Orasund$elm_ui_framework$Framework$Group$bottom, + otherwise: $Orasund$elm_ui_framework$Framework$Group$center +}; var $Orasund$elm_ui_framework$Framework$Grid$simple = _List_fromArray( [ $mdgriffith$elm_ui$Element$spacing(10), $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), $mdgriffith$elm_ui$Element$alignTop ]); -var $elm$svg$Svg$rect = $elm$svg$Svg$trustedNode('rect'); -var $elm$svg$Svg$Attributes$rx = _VirtualDom_attribute('rx'); -var $elm$svg$Svg$Attributes$ry = _VirtualDom_attribute('ry'); -var $elm$svg$Svg$Attributes$x = _VirtualDom_attribute('x'); -var $elm$svg$Svg$Attributes$y = _VirtualDom_attribute('y'); -var $author$project$Icons$square = A2( +var $author$project$Data$Style$ElmUiFramework$chipButtonStyle = {container: $Orasund$elm_ui_framework$Framework$Tag$simple, ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, ifDisabled: _List_Nil, labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, otherwise: _List_Nil, text: _List_Nil}; +var $author$project$Data$Style$ElmUiFramework$column = {containerColumn: $Orasund$elm_ui_framework$Framework$Grid$compact, element: _List_Nil, ifFirst: $Orasund$elm_ui_framework$Framework$Group$top, ifLast: $Orasund$elm_ui_framework$Framework$Group$bottom, otherwise: $Orasund$elm_ui_framework$Framework$Group$center}; +var $Orasund$elm_ui_framework$Framework$Heading$h3 = $Orasund$elm_ui_framework$Framework$Heading$h(3); +var $Orasund$elm_ui_framework$Framework$Color$green = A3($mdgriffith$elm_ui$Element$rgb255, 35, 209, 96); +var $Orasund$elm_ui_framework$Framework$Color$success = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$green), + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$green) + ]); +var $author$project$Data$Style$ElmUiFramework$simpleButton = { + container: _Utils_ap($Orasund$elm_ui_framework$Framework$Button$simple, $Orasund$elm_ui_framework$Framework$Color$success), + ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, + otherwise: _List_Nil, + text: _List_Nil +}; +var $author$project$Data$Style$ElmUiFramework$textButton = {container: $Orasund$elm_ui_framework$Framework$Button$simple, ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, otherwise: _List_Nil, text: _List_Nil}; +var $author$project$Data$Style$ElmUiFramework$dialog = { + acceptButton: $author$project$Data$Style$ElmUiFramework$simpleButton, + buttonRow: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 0, left: 0, right: 0, top: 28}) + ])), + containerColumn: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Card$simple, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$centerY, + $mdgriffith$elm_ui$Element$width( + A2( + $mdgriffith$elm_ui$Element$minimum, + 280, + A2($mdgriffith$elm_ui$Element$maximum, 560, $mdgriffith$elm_ui$Element$fill))) + ]))), + dismissButton: $author$project$Data$Style$ElmUiFramework$textButton, + text: _List_Nil, + title: $Orasund$elm_ui_framework$Framework$Heading$h3 +}; +var $elm$svg$Svg$Attributes$points = _VirtualDom_attribute('points'); +var $elm$svg$Svg$polyline = $elm$svg$Svg$trustedNode('polyline'); +var $author$project$Icons$chevronDown = A2( $author$project$Icons$svgFeatherIcon, - 'square', + 'chevron-down', _List_fromArray( [ A2( - $elm$svg$Svg$rect, + $elm$svg$Svg$polyline, _List_fromArray( [ - $elm$svg$Svg$Attributes$x('3'), - $elm$svg$Svg$Attributes$y('3'), - $elm$svg$Svg$Attributes$width('18'), - $elm$svg$Svg$Attributes$height('18'), - $elm$svg$Svg$Attributes$rx('2'), - $elm$svg$Svg$Attributes$ry('2') + $elm$svg$Svg$Attributes$points('6 9 12 15 18 9') ]), _List_Nil) ])); -var $mdgriffith$elm_ui$Element$Font$alignLeft = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$fontAlignment, $mdgriffith$elm_ui$Internal$Style$classes.textLeft); -var $Orasund$elm_ui_framework$Framework$Group$center = _List_fromArray( +var $author$project$Icons$chevronUp = A2( + $author$project$Icons$svgFeatherIcon, + 'chevron-up', + _List_fromArray( + [ + A2( + $elm$svg$Svg$polyline, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$points('18 15 12 9 6 15') + ]), + _List_Nil) + ])); +var $mdgriffith$elm_ui$Element$spaceEvenly = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$spacing, $mdgriffith$elm_ui$Internal$Style$classes.spaceEvenly); +var $Orasund$elm_ui_framework$Framework$Grid$spacedEvenly = _List_fromArray( [ - $mdgriffith$elm_ui$Element$Border$rounded(0) + $mdgriffith$elm_ui$Element$spaceEvenly, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$centerX, + $mdgriffith$elm_ui$Element$centerY + ]); +var $author$project$Data$Style$ElmUiFramework$expansionPanelStyle = { + collapseIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$chevronUp)), + containerColumn: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Card$simple, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) + ]))), + content: _List_Nil, + expandIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$chevronDown)), + labelRow: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) + ])), + panelRow: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$spacedEvenly, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) + ])) +}; +var $mdgriffith$elm_ui$Internal$Model$Main = {$: 'Main'}; +var $mdgriffith$elm_ui$Element$Region$mainContent = $mdgriffith$elm_ui$Internal$Model$Describe($mdgriffith$elm_ui$Internal$Model$Main); +var $Orasund$elm_ui_framework$Framework$container = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$centerX, + $mdgriffith$elm_ui$Element$centerY, + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$maximum, 1200, $mdgriffith$elm_ui$Element$fill)), + $mdgriffith$elm_ui$Element$padding(20), + $mdgriffith$elm_ui$Element$Region$mainContent, + $mdgriffith$elm_ui$Element$Background$color( + A3($mdgriffith$elm_ui$Element$rgb255, 255, 255, 255)) ]); var $Orasund$elm_ui_framework$Framework$Color$dark = _List_fromArray( [ @@ -13815,12 +14786,7 @@ var $Orasund$elm_ui_framework$Framework$Color$dark = _List_fromArray( $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$darkerGrey), $mdgriffith$elm_ui$Element$Font$color($Orasund$elm_ui_framework$Framework$Color$lighterGrey) ]); -var $Orasund$elm_ui_framework$Framework$Button$fill = _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) - ])); +var $Orasund$elm_ui_framework$Framework$Heading$h2 = $Orasund$elm_ui_framework$Framework$Heading$h(2); var $elm$svg$Svg$line = $elm$svg$Svg$trustedNode('line'); var $elm$svg$Svg$Attributes$x1 = _VirtualDom_attribute('x1'); var $elm$svg$Svg$Attributes$x2 = _VirtualDom_attribute('x2'); @@ -13862,6 +14828,70 @@ var $author$project$Icons$menu = A2( ]), _List_Nil) ])); +var $author$project$Data$Style$ElmUiFramework$menuButton = { + container: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Button$simple, + _Utils_ap($Orasund$elm_ui_framework$Framework$Group$center, $Orasund$elm_ui_framework$Framework$Color$dark)), + ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, + otherwise: _List_Nil, + text: _List_Nil +}; +var $Orasund$elm_ui_framework$Framework$Color$black = A3($mdgriffith$elm_ui$Element$rgb255, 0, 0, 0); +var $mdgriffith$elm_ui$Internal$Model$Px = function (a) { + return {$: 'Px', a: a}; +}; +var $mdgriffith$elm_ui$Element$px = $mdgriffith$elm_ui$Internal$Model$Px; +var $mdgriffith$elm_ui$Element$Border$widthXY = F2( + function (x, y) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$borderWidth, + A5( + $mdgriffith$elm_ui$Internal$Model$BorderWidth, + 'b-' + ($elm$core$String$fromInt(x) + ('-' + $elm$core$String$fromInt(y))), + y, + x, + y, + x)); + }); +var $mdgriffith$elm_ui$Element$Border$widthEach = function (_v0) { + var bottom = _v0.bottom; + var top = _v0.top; + var left = _v0.left; + var right = _v0.right; + return (_Utils_eq(top, bottom) && _Utils_eq(left, right)) ? (_Utils_eq(top, right) ? $mdgriffith$elm_ui$Element$Border$width(top) : A2($mdgriffith$elm_ui$Element$Border$widthXY, left, top)) : A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$borderWidth, + A5( + $mdgriffith$elm_ui$Internal$Model$BorderWidth, + 'b-' + ($elm$core$String$fromInt(top) + ('-' + ($elm$core$String$fromInt(right) + ('-' + ($elm$core$String$fromInt(bottom) + ('-' + $elm$core$String$fromInt(left))))))), + top, + right, + bottom, + left)); +}; +var $author$project$Data$Style$ElmUiFramework$menuTabButton = { + container: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(42)), + $mdgriffith$elm_ui$Element$Border$widthEach( + {bottom: 4, left: 0, right: 0, top: 0}), + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 4, left: 8, right: 8, top: 12}), + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$black) + ]), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$turquoise) + ]), + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, + otherwise: _List_Nil, + text: _List_Nil +}; var $author$project$Icons$moreVertical = A2( $author$project$Icons$svgFeatherIcon, 'more-vertical', @@ -13895,41 +14925,82 @@ var $author$project$Icons$moreVertical = A2( ]), _List_Nil) ])); -var $Orasund$elm_ui_framework$Framework$Color$primary = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$turquoise), - $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$turquoise) - ]); -var $mdgriffith$elm_ui$Element$Border$widthXY = F2( - function (x, y) { - return A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$borderWidth, - A5( - $mdgriffith$elm_ui$Internal$Model$BorderWidth, - 'b-' + ($elm$core$String$fromInt(x) + ('-' + $elm$core$String$fromInt(y))), - y, - x, - y, - x)); - }); -var $mdgriffith$elm_ui$Element$Border$widthEach = function (_v0) { - var bottom = _v0.bottom; - var top = _v0.top; - var left = _v0.left; - var right = _v0.right; - return (_Utils_eq(top, bottom) && _Utils_eq(left, right)) ? (_Utils_eq(top, right) ? $mdgriffith$elm_ui$Element$Border$width(top) : A2($mdgriffith$elm_ui$Element$Border$widthXY, left, top)) : A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$borderWidth, - A5( - $mdgriffith$elm_ui$Internal$Model$BorderWidth, - 'b-' + ($elm$core$String$fromInt(top) + ('-' + ($elm$core$String$fromInt(right) + ('-' + ($elm$core$String$fromInt(bottom) + ('-' + $elm$core$String$fromInt(left))))))), - top, - right, - bottom, - left)); +var $author$project$Icons$search = A2( + $author$project$Icons$svgFeatherIcon, + 'search', + _List_fromArray( + [ + A2( + $elm$svg$Svg$circle, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$cx('11'), + $elm$svg$Svg$Attributes$cy('11'), + $elm$svg$Svg$Attributes$r('8') + ]), + _List_Nil), + A2( + $elm$svg$Svg$line, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$x1('21'), + $elm$svg$Svg$Attributes$y1('21'), + $elm$svg$Svg$Attributes$x2('16.65'), + $elm$svg$Svg$Attributes$y2('16.65') + ]), + _List_Nil) + ])); +var $mdgriffith$elm_ui$Element$Font$alignLeft = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$fontAlignment, $mdgriffith$elm_ui$Internal$Style$classes.textLeft); +var $Orasund$elm_ui_framework$Framework$Button$fill = _Utils_ap( + $Orasund$elm_ui_framework$Framework$Button$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ])); +var $author$project$Data$Style$ElmUiFramework$sheetButton = { + container: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Button$fill, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Group$center, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$light, + _List_fromArray( + [$mdgriffith$elm_ui$Element$Font$alignLeft])))), + ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, + otherwise: _List_Nil, + text: _List_Nil }; -var $author$project$Example$style = { +var $author$project$Data$Style$ElmUiFramework$snackbarButton = { + container: _Utils_ap($Orasund$elm_ui_framework$Framework$Button$simple, $Orasund$elm_ui_framework$Framework$Color$dark), + ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: $Orasund$elm_ui_framework$Framework$Grid$simple, + otherwise: _List_Nil, + text: _List_Nil +}; +var $author$project$Data$Style$ElmUiFramework$snackbar = { + button: $author$project$Data$Style$ElmUiFramework$snackbarButton, + containerRow: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Card$simple, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$dark, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 6), + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(54)) + ])))), + text: _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 0) + ]) +}; +var $author$project$Data$Style$ElmUiFramework$layout = { + container: _List_Nil, header: _Utils_ap( $Orasund$elm_ui_framework$Framework$container, _Utils_ap( @@ -13941,18 +15012,33 @@ var $author$project$Example$style = { $mdgriffith$elm_ui$Element$px(42)) ]))), layout: $Orasund$elm_ui_framework$Framework$responsiveLayout, - menuButton: _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _Utils_ap($Orasund$elm_ui_framework$Framework$Group$center, $Orasund$elm_ui_framework$Framework$Color$dark)), - menuButtonSelected: $Orasund$elm_ui_framework$Framework$Color$primary, + menuButton: $author$project$Data$Style$ElmUiFramework$menuButton, menuIcon: A2( $mdgriffith$elm_ui$Element$el, _List_Nil, $mdgriffith$elm_ui$Element$html($author$project$Icons$menu)), + menuTabButton: $author$project$Data$Style$ElmUiFramework$menuTabButton, moreVerticalIcon: A2( $mdgriffith$elm_ui$Element$el, _List_Nil, $mdgriffith$elm_ui$Element$html($author$project$Icons$moreVertical)), + search: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$simple, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Card$large, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + A3($mdgriffith$elm_ui$Element$rgb255, 0, 0, 0)), + $mdgriffith$elm_ui$Element$padding(6), + $mdgriffith$elm_ui$Element$centerY, + $mdgriffith$elm_ui$Element$alignRight + ]))), + searchFill: _Utils_ap($Orasund$elm_ui_framework$Framework$Color$light, $Orasund$elm_ui_framework$Framework$Group$center), + searchIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$search)), sheet: _Utils_ap( $Orasund$elm_ui_framework$Framework$Color$light, _List_fromArray( @@ -13960,119 +15046,1895 @@ var $author$project$Example$style = { $mdgriffith$elm_ui$Element$width( A2($mdgriffith$elm_ui$Element$maximum, 256, $mdgriffith$elm_ui$Element$fill)) ])), - sheetButton: _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$fill, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Group$center, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Color$light, - _List_fromArray( - [$mdgriffith$elm_ui$Element$Font$alignLeft])))), - sheetButtonSelected: $Orasund$elm_ui_framework$Framework$Color$primary, - snackbar: _Utils_ap($Orasund$elm_ui_framework$Framework$Card$simple, $Orasund$elm_ui_framework$Framework$Color$dark), + sheetButton: $author$project$Data$Style$ElmUiFramework$sheetButton, + snackbar: $author$project$Data$Style$ElmUiFramework$snackbar, spacing: 8, - tabButton: _List_fromArray( + title: $Orasund$elm_ui_framework$Framework$Heading$h2 +}; +var $author$project$Data$Style$ElmUiFramework$row = {containerRow: $Orasund$elm_ui_framework$Framework$Grid$simple, element: _List_Nil, ifFirst: $Orasund$elm_ui_framework$Framework$Group$left, ifLast: $Orasund$elm_ui_framework$Framework$Group$right, otherwise: $Orasund$elm_ui_framework$Framework$Group$center}; +var $author$project$Data$Style$ElmUiFramework$tabButtonStyle = { + container: _Utils_ap($Orasund$elm_ui_framework$Framework$Button$simple, $Orasund$elm_ui_framework$Framework$Group$top), + ifActive: $Orasund$elm_ui_framework$Framework$Color$primary, + ifDisabled: $Orasund$elm_ui_framework$Framework$Color$disabled, + labelRow: _List_fromArray( [ - $mdgriffith$elm_ui$Element$height( - $mdgriffith$elm_ui$Element$px(42)), - $mdgriffith$elm_ui$Element$Border$widthEach( - {bottom: 8, left: 0, right: 0, top: 0}) + $mdgriffith$elm_ui$Element$spacing(8) ]), - tabButtonSelected: _List_fromArray( + otherwise: _List_Nil, + text: _List_Nil +}; +var $author$project$Data$Style$ElmUiFramework$sortTable = { + ascIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$chevronUp)), + containerTable: $Orasund$elm_ui_framework$Framework$Grid$simple, + defaultIcon: $mdgriffith$elm_ui$Element$none, + descIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$chevronDown)), + headerButton: $author$project$Data$Style$ElmUiFramework$tabButtonStyle +}; +var $Orasund$elm_ui_framework$Framework$Card$small = $Orasund$elm_ui_framework$Framework$Card$withSize(240); +var $author$project$Data$Style$ElmUiFramework$tab = { + button: $author$project$Data$Style$ElmUiFramework$tabButtonStyle, + containerColumn: $Orasund$elm_ui_framework$Framework$Grid$compact, + content: _Utils_ap($Orasund$elm_ui_framework$Framework$Card$small, $Orasund$elm_ui_framework$Framework$Group$bottom), + optionRow: $Orasund$elm_ui_framework$Framework$Grid$simple +}; +var $author$project$Data$Style$ElmUiFramework$textInputStyle = { + chipButton: $author$project$Data$Style$ElmUiFramework$chipButtonStyle, + chipsRow: _List_fromArray( [ - $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$turquoise) + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + $mdgriffith$elm_ui$Element$spacing(4), + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 8, left: 0, right: 0, top: 8}) + ]), + containerRow: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Button$simple, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$light, + _Utils_ap( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$color( + A3($mdgriffith$elm_ui$Element$rgb255, 186, 189, 182)), + $mdgriffith$elm_ui$Element$Font$alignLeft, + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 0), + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(42)) + ]), + $Orasund$elm_ui_framework$Framework$Grid$simple))), + input: _Utils_ap( + $Orasund$elm_ui_framework$Framework$Color$light, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$padding(8) + ])) +}; +var $author$project$Data$Style$ElmUiFramework$style = {button: $author$project$Data$Style$ElmUiFramework$buttonStyle, buttonRow: $author$project$Data$Style$ElmUiFramework$buttonRow, cardColumn: $author$project$Data$Style$ElmUiFramework$cardColumn, chipButton: $author$project$Data$Style$ElmUiFramework$chipButtonStyle, column: $author$project$Data$Style$ElmUiFramework$column, dialog: $author$project$Data$Style$ElmUiFramework$dialog, expansionPanel: $author$project$Data$Style$ElmUiFramework$expansionPanelStyle, layout: $author$project$Data$Style$ElmUiFramework$layout, primaryButton: $author$project$Data$Style$ElmUiFramework$simpleButton, row: $author$project$Data$Style$ElmUiFramework$row, selectButton: $author$project$Data$Style$ElmUiFramework$buttonStyle, sortTable: $author$project$Data$Style$ElmUiFramework$sortTable, tab: $author$project$Data$Style$ElmUiFramework$tab, textInput: $author$project$Data$Style$ElmUiFramework$textInputStyle}; +var $mdgriffith$elm_ui$Internal$Model$Bottom = {$: 'Bottom'}; +var $mdgriffith$elm_ui$Element$alignBottom = $mdgriffith$elm_ui$Internal$Model$AlignY($mdgriffith$elm_ui$Internal$Model$Bottom); +var $mdgriffith$elm_ui$Internal$Flag$letterSpacing = $mdgriffith$elm_ui$Internal$Flag$flag(16); +var $mdgriffith$elm_ui$Element$Font$letterSpacing = function (offset) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$letterSpacing, + A3( + $mdgriffith$elm_ui$Internal$Model$Single, + 'ls-' + $mdgriffith$elm_ui$Internal$Model$floatClass(offset), + 'letter-spacing', + $elm$core$String$fromFloat(offset) + 'px')); +}; +var $mdgriffith$elm_ui$Element$Font$semiBold = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$fontWeight, $mdgriffith$elm_ui$Internal$Style$classes.textSemiBold); +var $author$project$Widget$Style$Material$buttonFont = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$htmlAttribute( + A2($elm$html$Html$Attributes$style, 'text-transform', 'uppercase')), + $mdgriffith$elm_ui$Element$Font$size(14), + $mdgriffith$elm_ui$Element$Font$semiBold, + $mdgriffith$elm_ui$Element$Font$letterSpacing(1.25) + ]); +var $author$project$Widget$Style$Material$baseButton = function (_v0) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$buttonFont, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(36)), + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 8), + $mdgriffith$elm_ui$Element$Border$rounded(4) + ])), + ifActive: _List_Nil, + ifDisabled: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$htmlAttribute( + A2($elm$html$Html$Attributes$style, 'cursor', 'not-allowed')) + ]), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$minimum, 32, $mdgriffith$elm_ui$Element$shrink)), + $mdgriffith$elm_ui$Element$centerY + ]), + otherwise: _List_Nil, + text: _List_fromArray( + [$mdgriffith$elm_ui$Element$centerX]) + }; +}; +var $author$project$Widget$Style$Material$buttonDisabledOpacity = 0.38; +var $author$project$Widget$Style$Material$buttonFocusOpacity = 0.24; +var $author$project$Widget$Style$Material$buttonHoverOpacity = 0.08; +var $author$project$Widget$Style$Material$buttonPressedOpacity = 0.32; +var $mdgriffith$elm_ui$Element$fromRgb = function (clr) { + return A4($mdgriffith$elm_ui$Internal$Model$Rgba, clr.red, clr.green, clr.blue, clr.alpha); +}; +var $avh4$elm_color$Color$toRgba = function (_v0) { + var r = _v0.a; + var g = _v0.b; + var b = _v0.c; + var a = _v0.d; + return {alpha: a, blue: b, green: g, red: r}; +}; +var $author$project$Widget$Style$Material$fromColor = A2($elm$core$Basics$composeR, $avh4$elm_color$Color$toRgba, $mdgriffith$elm_ui$Element$fromRgb); +var $author$project$Widget$Style$Material$gray = A3($avh4$elm_color$Color$rgb255, 119, 119, 119); +var $mdgriffith$elm_ui$Internal$Model$Active = {$: 'Active'}; +var $mdgriffith$elm_ui$Internal$Flag$active = $mdgriffith$elm_ui$Internal$Flag$flag(32); +var $mdgriffith$elm_ui$Element$mouseDown = function (decs) { + return A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$active, + A2( + $mdgriffith$elm_ui$Internal$Model$PseudoSelector, + $mdgriffith$elm_ui$Internal$Model$Active, + $mdgriffith$elm_ui$Internal$Model$unwrapDecorations(decs))); +}; +var $avh4$elm_color$Color$fromRgba = function (components) { + return A4($avh4$elm_color$Color$RgbaSpace, components.red, components.green, components.blue, components.alpha); +}; +var $author$project$Widget$Style$Material$scaleOpacity = function (opacity) { + return A2( + $elm$core$Basics$composeR, + $avh4$elm_color$Color$toRgba, + A2( + $elm$core$Basics$composeR, + function (color) { + return _Utils_update( + color, + {alpha: color.alpha * opacity}); + }, + $avh4$elm_color$Color$fromRgba)); +}; +var $author$project$Widget$Style$Material$shadow = function (_float) { + return { + blur: _float, + color: A4($mdgriffith$elm_ui$Element$rgba255, 0, 0, 0, 0.2), + offset: _Utils_Tuple2(0, _float), + size: 0 + }; +}; +var $elm$core$Basics$pow = _Basics_pow; +var $noahzgordon$elm_color_extra$Color$Accessibility$luminance = function (cl) { + var f = function (intensity) { + return (intensity <= 0.03928) ? (intensity / 12.92) : A2($elm$core$Basics$pow, (intensity + 0.055) / 1.055, 2.4); + }; + var _v0 = function (a) { + return _Utils_Tuple3( + f(a.red), + f(a.green), + f(a.blue)); + }( + $avh4$elm_color$Color$toRgba(cl)); + var r = _v0.a; + var g = _v0.b; + var b = _v0.c; + return ((0.2126 * r) + (0.7152 * g)) + (0.0722 * b); +}; +var $author$project$Widget$Style$Material$accessibleTextColor = function (color) { + var l = 1 + ($avh4$elm_color$Color$toRgba(color).alpha * ($noahzgordon$elm_color_extra$Color$Accessibility$luminance(color) - 1)); + return ((1.05 / (l + 0.05)) < 7) ? A3($avh4$elm_color$Color$rgb255, 0, 0, 0) : A3($avh4$elm_color$Color$rgb255, 255, 255, 255); +}; +var $author$project$Widget$Style$Material$textAndBackground = function (color) { + return _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor(color)), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor( + $author$project$Widget$Style$Material$accessibleTextColor(color))) + ]); +}; +var $elm$core$Basics$cos = _Basics_cos; +var $noahzgordon$elm_color_extra$Color$Convert$labToXyz = function (_v0) { + var l = _v0.l; + var a = _v0.a; + var b = _v0.b; + var y = (l + 16) / 116; + var c = function (ch) { + var ch_ = (ch * ch) * ch; + return (ch_ > 8.856e-3) ? ch_ : ((ch - (16 / 116)) / 7.787); + }; + return { + x: c(y + (a / 500)) * 95.047, + y: c(y) * 100, + z: c(y - (b / 200)) * 108.883 + }; +}; +var $avh4$elm_color$Color$rgb = F3( + function (r, g, b) { + return A4($avh4$elm_color$Color$RgbaSpace, r, g, b, 1.0); + }); +var $noahzgordon$elm_color_extra$Color$Convert$xyzToColor = function (_v0) { + var x = _v0.x; + var y = _v0.y; + var z = _v0.z; + var z_ = z / 100; + var y_ = y / 100; + var x_ = x / 100; + var r = ((x_ * 3.2404542) + (y_ * (-1.5371385))) + (z_ * (-0.4986)); + var g = ((x_ * (-0.969266)) + (y_ * 1.8760108)) + (z_ * 4.1556e-2); + var c = function (ch) { + var ch_ = (ch > 3.1308e-3) ? ((1.055 * A2($elm$core$Basics$pow, ch, 1 / 2.4)) - 5.5e-2) : (12.92 * ch); + return A3($elm$core$Basics$clamp, 0, 1, ch_); + }; + var b = ((x_ * 5.56434e-2) + (y_ * (-0.2040259))) + (z_ * 1.0572252); + return A3( + $avh4$elm_color$Color$rgb, + c(r), + c(g), + c(b)); +}; +var $noahzgordon$elm_color_extra$Color$Convert$labToColor = A2($elm$core$Basics$composeR, $noahzgordon$elm_color_extra$Color$Convert$labToXyz, $noahzgordon$elm_color_extra$Color$Convert$xyzToColor); +var $elm$core$Basics$sin = _Basics_sin; +var $author$project$Widget$Style$Material$fromCIELCH = A2( + $elm$core$Basics$composeR, + function (_v0) { + var l = _v0.l; + var c = _v0.c; + var h = _v0.h; + return { + a: c * $elm$core$Basics$cos(h), + b: c * $elm$core$Basics$sin(h), + l: l + }; + }, + $noahzgordon$elm_color_extra$Color$Convert$labToColor); +var $elm$core$Basics$atan2 = _Basics_atan2; +var $noahzgordon$elm_color_extra$Color$Convert$colorToXyz = function (cl) { + var c = function (ch) { + var ch_ = (ch > 4.045e-2) ? A2($elm$core$Basics$pow, (ch + 5.5e-2) / 1.055, 2.4) : (ch / 12.92); + return ch_ * 100; + }; + var _v0 = $avh4$elm_color$Color$toRgba(cl); + var red = _v0.red; + var green = _v0.green; + var blue = _v0.blue; + var b = c(blue); + var g = c(green); + var r = c(red); + return {x: ((r * 0.4124) + (g * 0.3576)) + (b * 0.1805), y: ((r * 0.2126) + (g * 0.7152)) + (b * 7.22e-2), z: ((r * 1.93e-2) + (g * 0.1192)) + (b * 0.9505)}; +}; +var $noahzgordon$elm_color_extra$Color$Convert$xyzToLab = function (_v0) { + var x = _v0.x; + var y = _v0.y; + var z = _v0.z; + var c = function (ch) { + return (ch > 8.856e-3) ? A2($elm$core$Basics$pow, ch, 1 / 3) : ((7.787 * ch) + (16 / 116)); + }; + var x_ = c(x / 95.047); + var y_ = c(y / 100); + var z_ = c(z / 108.883); + return {a: 500 * (x_ - y_), b: 200 * (y_ - z_), l: (116 * y_) - 16}; +}; +var $noahzgordon$elm_color_extra$Color$Convert$colorToLab = A2($elm$core$Basics$composeR, $noahzgordon$elm_color_extra$Color$Convert$colorToXyz, $noahzgordon$elm_color_extra$Color$Convert$xyzToLab); +var $elm$core$Basics$sqrt = _Basics_sqrt; +var $author$project$Widget$Style$Material$toCIELCH = A2( + $elm$core$Basics$composeR, + $noahzgordon$elm_color_extra$Color$Convert$colorToLab, + function (_v0) { + var l = _v0.l; + var a = _v0.a; + var b = _v0.b; + return { + c: $elm$core$Basics$sqrt((a * a) + (b * b)), + h: A2($elm$core$Basics$atan2, b, a), + l: l + }; + }); +var $author$project$Widget$Style$Material$withShade = F3( + function (c2, amount, c1) { + var fun = F2( + function (a, b) { + return {c: ((a.c * (1 - amount)) + (b.c * amount)) / 1, h: ((a.h * (1 - amount)) + (b.h * amount)) / 1, l: ((a.l * (1 - amount)) + (b.l * amount)) / 1}; + }); + var alpha = $avh4$elm_color$Color$toRgba(c1).alpha; + return $avh4$elm_color$Color$fromRgba( + function (color) { + return _Utils_update( + color, + {alpha: alpha}); + }( + $avh4$elm_color$Color$toRgba( + $author$project$Widget$Style$Material$fromCIELCH( + A2( + fun, + $author$project$Widget$Style$Material$toCIELCH(c1), + $author$project$Widget$Style$Material$toCIELCH(c2)))))); + }); +var $author$project$Widget$Style$Material$containedButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).container, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(2)), + $mdgriffith$elm_ui$Element$mouseDown( + _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.primary, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.primary)), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(12)) + ]))), + $mdgriffith$elm_ui$Element$focused( + _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.primary, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.primary)), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(6)) + ]))), + $mdgriffith$elm_ui$Element$mouseOver( + _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.primary, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary)), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(6)) + ]))) + ])), + ifActive: $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.primary, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary)), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonDisabledOpacity, $author$project$Widget$Style$Material$gray))), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(0)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).labelRow, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 0) + ])), + otherwise: $author$project$Widget$Style$Material$textAndBackground(palette.primary), + text: $author$project$Widget$Style$Material$baseButton(palette).text + }; +}; +var $author$project$Widget$Style$Material$h6 = _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$size(20), + $mdgriffith$elm_ui$Element$Font$semiBold, + $mdgriffith$elm_ui$Element$Font$letterSpacing(0.15) + ]); +var $author$project$Widget$Style$Material$textButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).container, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor(palette.primary)), + $mdgriffith$elm_ui$Element$mouseDown( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))) + ])) + ])), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))) + ]), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: $author$project$Widget$Style$Material$baseButton(palette).labelRow, + otherwise: _List_Nil, + text: $author$project$Widget$Style$Material$baseButton(palette).text + }; +}; +var $author$project$Widget$Style$Material$alertDialog = function (palette) { + return { + acceptButton: $author$project$Widget$Style$Material$containedButton(palette), + buttonRow: _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 8), + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$alignRight, + $mdgriffith$elm_ui$Element$alignBottom + ]), + containerColumn: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$rounded(4), + $mdgriffith$elm_ui$Element$width( + A2( + $mdgriffith$elm_ui$Element$minimum, + 280, + A2($mdgriffith$elm_ui$Element$maximum, 560, $mdgriffith$elm_ui$Element$fill))), + $mdgriffith$elm_ui$Element$height( + A2($mdgriffith$elm_ui$Element$minimum, 182, $mdgriffith$elm_ui$Element$shrink)), + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor(palette.surface)) + ]), + dismissButton: $author$project$Widget$Style$Material$textButton(palette), + text: _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 24, 0) + ]), + title: _Utils_ap( + $author$project$Widget$Style$Material$h6, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 24, 20) + ])) + }; +}; +var $author$project$Widget$Style$Material$buttonRow = { + containerRow: _List_Nil, + element: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$rounded(2) + ]), + ifFirst: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 2, bottomRight: 0, topLeft: 2, topRight: 0}) + ]), + ifLast: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 0, bottomRight: 2, topLeft: 0, topRight: 2}) + ]), + otherwise: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$rounded(0) ]) }; -var $mdgriffith$elm_ui$Element$text = function (content) { - return $mdgriffith$elm_ui$Internal$Model$Text(content); +var $author$project$Widget$Style$Material$cardColumn = function (palette) { + return { + containerColumn: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(4)) + ])), + $mdgriffith$elm_ui$Element$alignTop, + $mdgriffith$elm_ui$Element$Border$rounded(4) + ]), + element: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$padding(16), + $mdgriffith$elm_ui$Element$Border$rounded(4), + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor(palette.surface)), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor( + $author$project$Widget$Style$Material$accessibleTextColor(palette.surface))), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface))), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$minimum, 344, $mdgriffith$elm_ui$Element$fill)) + ]), + ifFirst: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 0, bottomRight: 0, topLeft: 4, topRight: 4}) + ]), + ifLast: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$roundEach( + {bottomLeft: 4, bottomRight: 4, topLeft: 0, topRight: 0}), + $mdgriffith$elm_ui$Element$Border$widthEach( + {bottom: 1, left: 1, right: 1, top: 0}) + ]), + otherwise: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$rounded(0), + $mdgriffith$elm_ui$Element$Border$widthEach( + {bottom: 1, left: 1, right: 1, top: 0}) + ]) + }; }; -var $author$project$Icons$triangle = A2( - $author$project$Icons$svgFeatherIcon, - 'triangle', +var $author$project$Widget$Style$Material$buttonSelectedOpacity = 0.16; +var $author$project$Widget$Style$Material$chip = function (palette) { + return { + container: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(32)), + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 0, left: 4, right: 12, top: 0}), + $mdgriffith$elm_ui$Element$Border$rounded(16), + $mdgriffith$elm_ui$Element$mouseDown( + $author$project$Widget$Style$Material$textAndBackground( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonPressedOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.12, palette.on.surface)))), + $mdgriffith$elm_ui$Element$focused( + $author$project$Widget$Style$Material$textAndBackground( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonFocusOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.12, palette.on.surface)))), + $mdgriffith$elm_ui$Element$mouseOver( + $author$project$Widget$Style$Material$textAndBackground( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonHoverOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.12, palette.on.surface)))) + ]), + ifActive: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonSelectedOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.12, palette.on.surface))), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(4)) + ])), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonDisabledOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.12, palette.on.surface))), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ]))), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(0), + $mdgriffith$elm_ui$Element$centerY + ]), + otherwise: $author$project$Widget$Style$Material$textAndBackground( + A2($author$project$Widget$Style$Material$scaleOpacity, 0.12, palette.on.surface)), + text: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 0, left: 8, right: 0, top: 0}) + ]) + }; +}; +var $author$project$Widget$Style$Material$column = { + containerColumn: _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 0, 8), + $mdgriffith$elm_ui$Element$spacing(8) + ]), + element: _List_Nil, + ifFirst: _List_Nil, + ifLast: _List_Nil, + otherwise: _List_Nil +}; +var $author$project$Widget$Style$Material$icon = F2( + function (string, size) { + return A2( + $elm$core$Basics$composeR, + $elm$svg$Svg$svg( + _List_fromArray( + [ + $elm$svg$Svg$Attributes$height( + $elm$core$String$fromInt(size)), + $elm$svg$Svg$Attributes$stroke('currentColor'), + $elm$svg$Svg$Attributes$fill('currentColor'), + $elm$svg$Svg$Attributes$viewBox(string), + $elm$svg$Svg$Attributes$width( + $elm$core$String$fromInt(size)) + ])), + A2( + $elm$core$Basics$composeR, + $mdgriffith$elm_ui$Element$html, + $mdgriffith$elm_ui$Element$el(_List_Nil))); + }); +var $author$project$Widget$Style$Material$expand_less = A3( + $author$project$Widget$Style$Material$icon, + '0 0 48 48', + 24, _List_fromArray( [ A2( $elm$svg$Svg$path, _List_fromArray( [ - $elm$svg$Svg$Attributes$d('M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z') + $elm$svg$Svg$Attributes$d('M24 16L12 28l2.83 2.83L24 21.66l9.17 9.17L36 28z') ]), _List_Nil) ])); -var $author$project$Component$FilterSelectSpecific = function (a) { - return {$: 'FilterSelectSpecific', a: a}; +var $author$project$Widget$Style$Material$expand_more = A3( + $author$project$Widget$Style$Material$icon, + '0 0 48 48', + 24, + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M33.17 17.17L24 26.34l-9.17-9.17L12 20l12 12 12-12z') + ]), + _List_Nil) + ])); +var $author$project$Widget$Style$Material$expansionPanel = function (palette) { + return { + collapseIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)) + ]), + $author$project$Widget$Style$Material$expand_less), + containerColumn: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor(palette.surface)), + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ]), + content: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$padding(14) + ]), + expandIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)) + ]), + $author$project$Widget$Style$Material$expand_more), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(32) + ]), + panelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(48)), + $mdgriffith$elm_ui$Element$spaceEvenly, + $mdgriffith$elm_ui$Element$padding(14), + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ]) + }; }; -var $author$project$Widget$FilterSelect$Selected = function (a) { - return {$: 'Selected', a: a}; +var $author$project$Widget$Style$Material$drawerButton = function (palette) { + return { + container: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$size(14), + $mdgriffith$elm_ui$Element$Font$semiBold, + $mdgriffith$elm_ui$Element$Font$letterSpacing(0.25), + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(36)), + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 8), + $mdgriffith$elm_ui$Element$Border$rounded(4), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor( + $author$project$Widget$Style$Material$accessibleTextColor(palette.surface))), + $mdgriffith$elm_ui$Element$mouseDown( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))) + ])) + ]), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor(palette.primary)) + ]), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: $author$project$Widget$Style$Material$baseButton(palette).labelRow, + otherwise: _List_Nil, + text: $author$project$Widget$Style$Material$baseButton(palette).text + }; }; -var $Orasund$elm_ui_framework$Framework$Color$red = A3($mdgriffith$elm_ui$Element$rgb255, 255, 56, 96); -var $Orasund$elm_ui_framework$Framework$Color$danger = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$red), - $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$red), - $mdgriffith$elm_ui$Element$Font$color($Orasund$elm_ui_framework$Framework$Color$lighterGrey) - ]); -var $mdgriffith$elm_ui$Element$Border$roundEach = function (_v0) { - var topLeft = _v0.topLeft; - var topRight = _v0.topRight; - var bottomLeft = _v0.bottomLeft; - var bottomRight = _v0.bottomRight; +var $mdgriffith$elm_ui$Element$Font$family = function (families) { return A2( $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$borderRound, - A3( - $mdgriffith$elm_ui$Internal$Model$Single, - 'br-' + ($elm$core$String$fromInt(topLeft) + ('-' + ($elm$core$String$fromInt(topRight) + ($elm$core$String$fromInt(bottomLeft) + ('-' + $elm$core$String$fromInt(bottomRight)))))), - 'border-radius', - $elm$core$String$fromInt(topLeft) + ('px ' + ($elm$core$String$fromInt(topRight) + ('px ' + ($elm$core$String$fromInt(bottomRight) + ('px ' + ($elm$core$String$fromInt(bottomLeft) + 'px')))))))); + $mdgriffith$elm_ui$Internal$Flag$fontFamily, + A2( + $mdgriffith$elm_ui$Internal$Model$FontFamily, + A3($elm$core$List$foldl, $mdgriffith$elm_ui$Internal$Model$renderFontClassName, 'ff-', families), + families)); }; -var $Orasund$elm_ui_framework$Framework$Group$left = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$roundEach( - {bottomLeft: 4, bottomRight: 0, topLeft: 4, topRight: 0}) - ]); +var $author$project$Widget$Style$Material$iconButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).container, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(48)), + $mdgriffith$elm_ui$Element$Border$rounded(24), + $mdgriffith$elm_ui$Element$mouseDown( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.surface))) + ])), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.surface))) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.surface))) + ])) + ])), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.surface))) + ]), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + $mdgriffith$elm_ui$Element$centerY, + $mdgriffith$elm_ui$Element$centerX + ]), + otherwise: _List_Nil, + text: $author$project$Widget$Style$Material$baseButton(palette).text + }; +}; +var $mdgriffith$elm_ui$Element$layout = $mdgriffith$elm_ui$Element$layoutWith( + {options: _List_Nil}); +var $author$project$Widget$Style$Material$menu = A3( + $author$project$Widget$Style$Material$icon, + '0 0 48 48', + 24, + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M6 36h36v-4H6v4zm0-10h36v-4H6v4zm0-14v4h36v-4H6z') + ]), + _List_Nil) + ])); +var $author$project$Widget$Style$Material$menuTabButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$buttonFont, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(56)), + $mdgriffith$elm_ui$Element$width( + A2( + $mdgriffith$elm_ui$Element$minimum, + 90, + A2($mdgriffith$elm_ui$Element$maximum, 360, $mdgriffith$elm_ui$Element$fill))), + A2($mdgriffith$elm_ui$Element$paddingXY, 12, 16), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor( + $author$project$Widget$Style$Material$accessibleTextColor(palette.primary))), + $mdgriffith$elm_ui$Element$alignBottom, + $mdgriffith$elm_ui$Element$mouseDown( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))) + ])) + ])), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$widthEach( + {bottom: 2, left: 0, right: 0, top: 0}) + ]), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$centerY, + $mdgriffith$elm_ui$Element$centerX + ]), + otherwise: _List_Nil, + text: _List_Nil + }; +}; +var $author$project$Widget$Style$Material$more_vert = A3( + $author$project$Widget$Style$Material$icon, + '0 0 48 48', + 24, + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$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') + ]), + _List_Nil) + ])); +var $mdgriffith$elm_ui$Element$Font$sansSerif = $mdgriffith$elm_ui$Internal$Model$SansSerif; +var $author$project$Widget$Style$Material$search = A3( + $author$project$Widget$Style$Material$icon, + '0 0 48 48', + 24, + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$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') + ]), + _List_Nil) + ])); +var $author$project$Widget$Style$Material$accessibleWithTextColor = F2( + function (c, color) { + var newConstrast = 7; + var l2 = 1 + ($avh4$elm_color$Color$toRgba(color).alpha * ($noahzgordon$elm_color_extra$Color$Accessibility$luminance(color) - 1)); + var lighterLuminance = (newConstrast * (l2 + 0.05)) - 0.05; + var l1 = 1 + ($avh4$elm_color$Color$toRgba(c).alpha * ($noahzgordon$elm_color_extra$Color$Accessibility$luminance(c) - 1)); + var darkerLuminance = (l2 + 0.05) - (0.05 / newConstrast); + return ((_Utils_cmp(l1, l2) > 0) ? ((((l1 + 0.05) / (l2 + 0.05)) < 7) ? A2( + $elm$core$Basics$composeR, + $noahzgordon$elm_color_extra$Color$Convert$colorToLab, + A2( + $elm$core$Basics$composeR, + function (col) { + return _Utils_update( + col, + {l: 100 * lighterLuminance}); + }, + $noahzgordon$elm_color_extra$Color$Convert$labToColor)) : $elm$core$Basics$identity) : ((((l2 + 0.05) / (l1 + 0.05)) < 7) ? A2( + $elm$core$Basics$composeR, + $noahzgordon$elm_color_extra$Color$Convert$colorToLab, + A2( + $elm$core$Basics$composeR, + function (col) { + return _Utils_update( + col, + {l: 100 * darkerLuminance}); + }, + $noahzgordon$elm_color_extra$Color$Convert$labToColor)) : $elm$core$Basics$identity))(c); + }); +var $author$project$Widget$Style$Material$dark = A3($avh4$elm_color$Color$rgb255, 50, 50, 50); +var $author$project$Widget$Style$Material$snackbar = function (palette) { + return { + button: function (b) { + return _Utils_update( + b, + { + container: _Utils_ap( + b.container, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$accessibleWithTextColor, palette.primary, $author$project$Widget$Style$Material$dark))) + ])) + }); + }( + $author$project$Widget$Style$Material$textButton(palette)), + containerRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$dark)), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor( + $author$project$Widget$Style$Material$accessibleTextColor($author$project$Widget$Style$Material$dark))), + $mdgriffith$elm_ui$Element$Border$rounded(4), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$maximum, 344, $mdgriffith$elm_ui$Element$fill)), + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 6), + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(2)) + ]), + text: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$centerX, + A2($mdgriffith$elm_ui$Element$paddingXY, 10, 8) + ]) + }; +}; +var $mdgriffith$elm_ui$Element$Font$typeface = $mdgriffith$elm_ui$Internal$Model$Typeface; +var $author$project$Widget$Style$Material$layout = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.background), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$family( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$typeface('Roboto'), + $mdgriffith$elm_ui$Element$Font$sansSerif + ])), + $mdgriffith$elm_ui$Element$Font$size(16), + $mdgriffith$elm_ui$Element$Font$letterSpacing(0.5) + ])), + header: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.primary), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(56)), + $mdgriffith$elm_ui$Element$padding(16), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$minimum, 360, $mdgriffith$elm_ui$Element$fill)) + ])), + layout: $mdgriffith$elm_ui$Element$layout, + menuButton: $author$project$Widget$Style$Material$iconButton(palette), + menuIcon: $author$project$Widget$Style$Material$menu, + menuTabButton: $author$project$Widget$Style$Material$menuTabButton(palette), + moreVerticalIcon: $author$project$Widget$Style$Material$more_vert, + search: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.surface), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 8), + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(32)), + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$Border$rounded(4), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface))), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(4)) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(2)) + ])), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$maximum, 360, $mdgriffith$elm_ui$Element$fill)), + $mdgriffith$elm_ui$Element$alignRight + ])), + searchFill: $author$project$Widget$Style$Material$textAndBackground(palette.surface), + searchIcon: $author$project$Widget$Style$Material$search, + sheet: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.surface), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$maximum, 360, $mdgriffith$elm_ui$Element$fill)), + $mdgriffith$elm_ui$Element$padding(8), + $mdgriffith$elm_ui$Element$spacing(8) + ])), + sheetButton: $author$project$Widget$Style$Material$drawerButton(palette), + snackbar: $author$project$Widget$Style$Material$snackbar(palette), + spacing: 8, + title: _Utils_ap( + $author$project$Widget$Style$Material$h6, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 0) + ])) + }; +}; +var $author$project$Widget$Style$Material$outlinedButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).container, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor(palette.primary)), + $mdgriffith$elm_ui$Element$mouseDown( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.primary))), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3($author$project$Widget$Style$Material$withShade, palette.primary, $author$project$Widget$Style$Material$buttonPressedOpacity, $author$project$Widget$Style$Material$gray))) + ])), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.primary))), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3($author$project$Widget$Style$Material$withShade, palette.primary, $author$project$Widget$Style$Material$buttonFocusOpacity, $author$project$Widget$Style$Material$gray))) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3($author$project$Widget$Style$Material$withShade, palette.primary, $author$project$Widget$Style$Material$buttonHoverOpacity, $author$project$Widget$Style$Material$gray))) + ])) + ])), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3($author$project$Widget$Style$Material$withShade, palette.primary, $author$project$Widget$Style$Material$buttonHoverOpacity, $author$project$Widget$Style$Material$gray))) + ]), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).labelRow, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 0) + ])), + otherwise: _List_Nil, + text: $author$project$Widget$Style$Material$baseButton(palette).text + }; +}; +var $author$project$Widget$Style$Material$row = { + containerRow: _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$paddingXY, 0, 8), + $mdgriffith$elm_ui$Element$spacing(8) + ]), + element: _List_Nil, + ifFirst: _List_Nil, + ifLast: _List_Nil, + otherwise: _List_Nil +}; +var $author$project$Data$Style$Material$sortTable = function (palette) { + return { + ascIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$chevronUp)), + containerTable: _List_Nil, + defaultIcon: $mdgriffith$elm_ui$Element$none, + descIcon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$chevronDown)), + headerButton: $author$project$Widget$Style$Material$textButton(palette) + }; +}; +var $author$project$Widget$Style$Material$tabButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$buttonFont, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(48)), + $mdgriffith$elm_ui$Element$width( + A2( + $mdgriffith$elm_ui$Element$minimum, + 90, + A2($mdgriffith$elm_ui$Element$maximum, 360, $mdgriffith$elm_ui$Element$fill))), + A2($mdgriffith$elm_ui$Element$paddingXY, 12, 16), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor(palette.primary)), + $mdgriffith$elm_ui$Element$mouseDown( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.primary))) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.primary))) + ])) + ])), + ifActive: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(48)), + $mdgriffith$elm_ui$Element$Border$widthEach( + {bottom: 2, left: 0, right: 0, top: 0}) + ]), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$centerY, + $mdgriffith$elm_ui$Element$centerX + ]), + otherwise: _List_Nil, + text: _List_Nil + }; +}; +var $author$project$Widget$Style$Material$tab = function (palette) { + return { + button: $author$project$Widget$Style$Material$tabButton(palette), + containerColumn: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8) + ]), + content: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ]), + optionRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spaceEvenly, + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(4)) + ]) + }; +}; +var $author$project$Widget$Style$Material$textInput = function (palette) { + return { + chipButton: $author$project$Widget$Style$Material$chip(palette), + chipsRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8) + ]), + containerRow: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.surface), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + A2($mdgriffith$elm_ui$Element$paddingXY, 8, 0), + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$Border$rounded(4), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface))), + $mdgriffith$elm_ui$Element$focused( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(4)), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor(palette.primary)) + ])), + $mdgriffith$elm_ui$Element$mouseOver( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$shadow( + $author$project$Widget$Style$Material$shadow(2)) + ])) + ])), + input: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.surface), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$width(0), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil), + $mdgriffith$elm_ui$Element$focused(_List_Nil) + ])) + }; +}; +var $author$project$Widget$Style$Material$toggleButton = function (palette) { + return { + container: _Utils_ap( + $author$project$Widget$Style$Material$buttonFont, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width( + $mdgriffith$elm_ui$Element$px(48)), + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(48)), + $mdgriffith$elm_ui$Element$padding(4), + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$mouseDown( + _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.surface, $author$project$Widget$Style$Material$buttonPressedOpacity, palette.surface)), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonPressedOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface)))) + ]))), + $mdgriffith$elm_ui$Element$focused(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver( + _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.surface, $author$project$Widget$Style$Material$buttonHoverOpacity, palette.surface)), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonHoverOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface)))) + ]))) + ])), + ifActive: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.surface, $author$project$Widget$Style$Material$buttonSelectedOpacity, palette.surface)), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A3( + $author$project$Widget$Style$Material$withShade, + palette.on.surface, + $author$project$Widget$Style$Material$buttonSelectedOpacity, + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface)))), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil) + ])), + ifDisabled: _Utils_ap( + $author$project$Widget$Style$Material$baseButton(palette).ifDisabled, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Background$color( + $author$project$Widget$Style$Material$fromColor(palette.surface)), + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface))), + $mdgriffith$elm_ui$Element$Font$color( + $author$project$Widget$Style$Material$fromColor($author$project$Widget$Style$Material$gray)), + $mdgriffith$elm_ui$Element$mouseDown(_List_Nil), + $mdgriffith$elm_ui$Element$mouseOver(_List_Nil) + ])), + labelRow: _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(8), + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$Border$rounded(24), + $mdgriffith$elm_ui$Element$padding(8), + $mdgriffith$elm_ui$Element$focused( + $author$project$Widget$Style$Material$textAndBackground( + A3($author$project$Widget$Style$Material$withShade, palette.on.surface, $author$project$Widget$Style$Material$buttonFocusOpacity, palette.surface))) + ]), + otherwise: _Utils_ap( + $author$project$Widget$Style$Material$textAndBackground(palette.surface), + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$color( + $author$project$Widget$Style$Material$fromColor( + A2($author$project$Widget$Style$Material$scaleOpacity, 0.14, palette.on.surface))) + ])), + text: _List_fromArray( + [$mdgriffith$elm_ui$Element$centerX]) + }; +}; +var $author$project$Data$Style$Material$style = function (palette) { + return { + button: $author$project$Widget$Style$Material$outlinedButton(palette), + buttonRow: $author$project$Widget$Style$Material$buttonRow, + cardColumn: $author$project$Widget$Style$Material$cardColumn(palette), + chipButton: $author$project$Widget$Style$Material$chip(palette), + column: $author$project$Widget$Style$Material$column, + dialog: $author$project$Widget$Style$Material$alertDialog(palette), + expansionPanel: $author$project$Widget$Style$Material$expansionPanel(palette), + layout: $author$project$Widget$Style$Material$layout(palette), + primaryButton: $author$project$Widget$Style$Material$containedButton(palette), + row: $author$project$Widget$Style$Material$row, + selectButton: $author$project$Widget$Style$Material$toggleButton(palette), + sortTable: $author$project$Data$Style$Material$sortTable(palette), + tab: $author$project$Widget$Style$Material$tab(palette), + textInput: $author$project$Widget$Style$Material$textInput(palette) + }; +}; +var $mdgriffith$elm_ui$Internal$Model$Above = {$: 'Above'}; +var $mdgriffith$elm_ui$Element$above = function (element) { + return A2($mdgriffith$elm_ui$Element$createNearby, $mdgriffith$elm_ui$Internal$Model$Above, element); +}; +var $author$project$Widget$Style$Template$fontSize = 10; +var $author$project$Widget$Style$Template$box = function (string) { + return _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$Background$color( + A4($mdgriffith$elm_ui$Element$rgba, 1, 1, 1, 0.5)), + $mdgriffith$elm_ui$Element$padding(10), + $mdgriffith$elm_ui$Element$spacing(10), + $mdgriffith$elm_ui$Element$above( + A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$size($author$project$Widget$Style$Template$fontSize) + ]), + $mdgriffith$elm_ui$Element$text(string))) + ]); +}; +var $mdgriffith$elm_ui$Internal$Model$Below = {$: 'Below'}; +var $mdgriffith$elm_ui$Element$below = function (element) { + return A2($mdgriffith$elm_ui$Element$createNearby, $mdgriffith$elm_ui$Internal$Model$Below, element); +}; +var $mdgriffith$elm_ui$Element$rgb = F3( + function (r, g, b) { + return A4($mdgriffith$elm_ui$Internal$Model$Rgba, r, g, b, 1); + }); +var $author$project$Widget$Style$Template$decoration = function (string) { + return _List_fromArray( + [ + $mdgriffith$elm_ui$Element$below( + A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$size($author$project$Widget$Style$Template$fontSize) + ]), + $mdgriffith$elm_ui$Element$text(string))), + $mdgriffith$elm_ui$Element$Background$color( + A3($mdgriffith$elm_ui$Element$rgb, 0.66, 0.66, 0.66)) + ]); +}; +var $author$project$Widget$Style$Template$button = function (string) { + return { + container: $author$project$Widget$Style$Template$box(string + ':container'), + ifActive: $author$project$Widget$Style$Template$decoration(string + ':ifActive'), + ifDisabled: $author$project$Widget$Style$Template$decoration(string + ':ifDisabled'), + labelRow: $author$project$Widget$Style$Template$box(string + ':labelRow'), + otherwise: $author$project$Widget$Style$Template$decoration(string + ':otherwise'), + text: $author$project$Widget$Style$Template$box(string + ':text') + }; +}; +var $author$project$Widget$Style$Template$column = function (string) { + return { + containerColumn: $author$project$Widget$Style$Template$box(string + ':containerColumn'), + element: $author$project$Widget$Style$Template$box(string + ':element'), + ifFirst: $author$project$Widget$Style$Template$decoration(string + ':ifFirst'), + ifLast: $author$project$Widget$Style$Template$decoration(string + ':ifLast'), + otherwise: $author$project$Widget$Style$Template$decoration(string + ':otherwise') + }; +}; +var $author$project$Widget$Style$Template$dialog = function (string) { + return { + acceptButton: $author$project$Widget$Style$Template$button(string + ':acceptButton'), + buttonRow: $author$project$Widget$Style$Template$box(string + ':buttonRow'), + containerColumn: $author$project$Widget$Style$Template$box(string + ':containerColumn'), + dismissButton: $author$project$Widget$Style$Template$button(string + ':dismissButton'), + text: $author$project$Widget$Style$Template$box(string + ':text'), + title: $author$project$Widget$Style$Template$box(string + ':title') + }; +}; +var $author$project$Widget$Style$Template$icon = function (string) { + return A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width( + $mdgriffith$elm_ui$Element$px(12)), + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(12)), + $mdgriffith$elm_ui$Element$Border$rounded(6), + $mdgriffith$elm_ui$Element$Border$width(1), + $mdgriffith$elm_ui$Element$above( + A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Font$size($author$project$Widget$Style$Template$fontSize) + ]), + $mdgriffith$elm_ui$Element$text(string))) + ]), + $mdgriffith$elm_ui$Element$none); +}; +var $author$project$Widget$Style$Template$expansionPanel = function (string) { + return { + collapseIcon: $author$project$Widget$Style$Template$icon(string + ':collapseIcon'), + containerColumn: $author$project$Widget$Style$Template$box(string + ':containerColumn'), + content: $author$project$Widget$Style$Template$box(string + ':content'), + expandIcon: $author$project$Widget$Style$Template$icon(string + ':expandIcon'), + labelRow: $author$project$Widget$Style$Template$box(string + ':labelRow'), + panelRow: $author$project$Widget$Style$Template$box(string + ':panelRow') + }; +}; +var $author$project$Widget$Style$Template$snackbar = function (string) { + return { + button: $author$project$Widget$Style$Template$button(string + ':button'), + containerRow: $author$project$Widget$Style$Template$box(string + ':containerRow'), + text: $author$project$Widget$Style$Template$box(string + ':text') + }; +}; +var $author$project$Widget$Style$Template$layout = function (string) { + return { + container: $author$project$Widget$Style$Template$box(string + ':container'), + header: $author$project$Widget$Style$Template$box(string + ':header'), + layout: $mdgriffith$elm_ui$Element$layout, + menuButton: $author$project$Widget$Style$Template$button(string + ':menuButton'), + menuIcon: $author$project$Widget$Style$Template$icon(string + ':menuIcon'), + menuTabButton: $author$project$Widget$Style$Template$button(string + ':menuTabButton'), + moreVerticalIcon: $author$project$Widget$Style$Template$icon(string + ':moreVerticalIcon'), + search: $author$project$Widget$Style$Template$box(string + ':search'), + searchFill: $author$project$Widget$Style$Template$box(string + ':searchFill'), + searchIcon: $author$project$Widget$Style$Template$icon(string + ':searchIcon'), + sheet: $author$project$Widget$Style$Template$box(string + ':sheet'), + sheetButton: $author$project$Widget$Style$Template$button(string + ':sheetButton'), + snackbar: $author$project$Widget$Style$Template$snackbar(string + ':snackbar'), + spacing: 8, + title: $author$project$Widget$Style$Template$box(string + ':title') + }; +}; +var $author$project$Widget$Style$Template$row = function (string) { + return { + containerRow: $author$project$Widget$Style$Template$box(string + ':containerRow'), + element: $author$project$Widget$Style$Template$box(string + ':element'), + ifFirst: $author$project$Widget$Style$Template$decoration(string + ':ifFirst'), + ifLast: $author$project$Widget$Style$Template$decoration(string + ':ifLast'), + otherwise: $author$project$Widget$Style$Template$decoration(string + ':otherwise') + }; +}; +var $author$project$Widget$Style$Template$sortTable = function (string) { + return { + ascIcon: $author$project$Widget$Style$Template$icon(string + ':ascIcon'), + containerTable: $author$project$Widget$Style$Template$box(string + ':containerTable'), + defaultIcon: $author$project$Widget$Style$Template$icon(string + ':defaultIcon'), + descIcon: $author$project$Widget$Style$Template$icon(string + ':descIcon'), + headerButton: $author$project$Widget$Style$Template$button(string + ':headerButton') + }; +}; +var $author$project$Widget$Style$Template$tab = function (string) { + return { + button: $author$project$Widget$Style$Template$button(string + ':button'), + containerColumn: $author$project$Widget$Style$Template$box(string + ':containerColumn'), + content: $author$project$Widget$Style$Template$box(string + ':content'), + optionRow: $author$project$Widget$Style$Template$box(string + ':optionRow') + }; +}; +var $author$project$Widget$Style$Template$textInput = function (string) { + return { + chipButton: $author$project$Widget$Style$Template$button(string + ':chipButton'), + chipsRow: $author$project$Widget$Style$Template$box(string + ':chipsRow'), + containerRow: $author$project$Widget$Style$Template$box(string + ':containerRow'), + input: $author$project$Widget$Style$Template$box(string + ':input') + }; +}; +var $author$project$Data$Style$Template$style = { + button: $author$project$Widget$Style$Template$button('button'), + buttonRow: $author$project$Widget$Style$Template$row('buttonRow'), + cardColumn: $author$project$Widget$Style$Template$column('cardRow'), + chipButton: $author$project$Widget$Style$Template$button('chipButton'), + column: $author$project$Widget$Style$Template$column('column'), + dialog: $author$project$Widget$Style$Template$dialog('dialog'), + expansionPanel: $author$project$Widget$Style$Template$expansionPanel('expansionPanel'), + layout: $author$project$Widget$Style$Template$layout('layout'), + primaryButton: $author$project$Widget$Style$Template$button('primaryButton'), + row: $author$project$Widget$Style$Template$row('row'), + selectButton: $author$project$Widget$Style$Template$button('selectButton'), + sortTable: $author$project$Widget$Style$Template$sortTable('sortTable'), + tab: $author$project$Widget$Style$Template$tab('tab'), + textInput: $author$project$Widget$Style$Template$textInput('textInput') +}; +var $author$project$Data$Theme$toStyle = function (theme) { + switch (theme.$) { + case 'ElmUiFramework': + return $author$project$Data$Style$ElmUiFramework$style; + case 'Template': + return $author$project$Data$Style$Template$style; + case 'Material': + return $author$project$Data$Style$Material$style($author$project$Widget$Style$Material$defaultPalette); + default: + return $author$project$Data$Style$Material$style($author$project$Widget$Style$Material$darkPalette); + } +}; +var $author$project$Widget$Layout$LeftSheet = {$: 'LeftSheet'}; +var $mdgriffith$elm_ui$Element$Phone = {$: 'Phone'}; +var $author$project$Widget$Layout$RightSheet = {$: 'RightSheet'}; +var $author$project$Widget$Layout$Search = {$: 'Search'}; +var $mdgriffith$elm_ui$Element$Tablet = {$: 'Tablet'}; +var $author$project$Widget$button = $author$project$Internal$Button$button; +var $mdgriffith$elm_ui$Element$BigDesktop = {$: 'BigDesktop'}; +var $mdgriffith$elm_ui$Element$Desktop = {$: 'Desktop'}; +var $mdgriffith$elm_ui$Element$Landscape = {$: 'Landscape'}; +var $mdgriffith$elm_ui$Element$Portrait = {$: 'Portrait'}; +var $mdgriffith$elm_ui$Element$classifyDevice = function (window) { + return { + _class: function () { + var shortSide = A2($elm$core$Basics$min, window.width, window.height); + var longSide = A2($elm$core$Basics$max, window.width, window.height); + return (shortSide < 600) ? $mdgriffith$elm_ui$Element$Phone : ((longSide <= 1200) ? $mdgriffith$elm_ui$Element$Tablet : (((longSide > 1200) && (longSide <= 1920)) ? $mdgriffith$elm_ui$Element$Desktop : $mdgriffith$elm_ui$Element$BigDesktop)); + }(), + orientation: (_Utils_cmp(window.width, window.height) < 0) ? $mdgriffith$elm_ui$Element$Portrait : $mdgriffith$elm_ui$Element$Landscape + }; +}; +var $elm$core$List$drop = F2( + function (n, list) { + drop: + while (true) { + if (n <= 0) { + return list; + } else { + if (!list.b) { + return list; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs; + n = $temp$n; + list = $temp$list; + continue drop; + } + } + } + }); +var $mdgriffith$elm_ui$Internal$Model$Label = function (a) { + return {$: 'Label', a: a}; +}; +var $mdgriffith$elm_ui$Element$Region$description = A2($elm$core$Basics$composeL, $mdgriffith$elm_ui$Internal$Model$Describe, $mdgriffith$elm_ui$Internal$Model$Label); +var $author$project$Internal$Button$iconButton = F2( + function (style, _v0) { + var onPress = _v0.onPress; + var text = _v0.text; + var icon = _v0.icon; + return A2( + $mdgriffith$elm_ui$Element$Input$button, + _Utils_ap( + style.container, + _Utils_ap( + _Utils_eq(onPress, $elm$core$Maybe$Nothing) ? style.ifDisabled : style.otherwise, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Region$description(text) + ]))), + { + label: A2( + $mdgriffith$elm_ui$Element$el, + style.labelRow, + A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon)), + onPress: onPress + }); + }); +var $author$project$Widget$iconButton = $author$project$Internal$Button$iconButton; +var $mdgriffith$elm_ui$Element$Input$HiddenLabel = function (a) { + return {$: 'HiddenLabel', a: a}; +}; +var $mdgriffith$elm_ui$Element$Input$labelHidden = $mdgriffith$elm_ui$Element$Input$HiddenLabel; +var $author$project$Widget$modal = $author$project$Internal$Dialog$modal; var $mdgriffith$elm_ui$Element$Input$Placeholder = F2( function (a, b) { return {$: 'Placeholder', a: a, b: b}; }); var $mdgriffith$elm_ui$Element$Input$placeholder = $mdgriffith$elm_ui$Element$Input$Placeholder; -var $Orasund$elm_ui_framework$Framework$Group$right = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$roundEach( - {bottomLeft: 0, bottomRight: 4, topLeft: 0, topRight: 4}) - ]); -var $mdgriffith$elm_ui$Internal$Model$AsRow = {$: 'AsRow'}; -var $mdgriffith$elm_ui$Internal$Model$asRow = $mdgriffith$elm_ui$Internal$Model$AsRow; -var $mdgriffith$elm_ui$Element$row = F2( - function (attrs, children) { - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asRow, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.contentCenterY)), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), - attrs))), - $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); +var $author$project$Internal$Select$select = function (_v0) { + var selected = _v0.selected; + var options = _v0.options; + var onSelect = _v0.onSelect; + return A2( + $elm$core$List$indexedMap, + F2( + function (i, a) { + return _Utils_Tuple2( + _Utils_eq( + selected, + $elm$core$Maybe$Just(i)), + { + icon: a.icon, + onPress: onSelect(i), + text: a.text + }); + }), + options); +}; +var $author$project$Widget$select = $author$project$Internal$Select$select; +var $author$project$Internal$Select$selectButton = F2( + function (style, _v0) { + var selected = _v0.a; + var b = _v0.b; + return A2( + $mdgriffith$elm_ui$Element$Input$button, + _Utils_ap( + style.container, + _Utils_eq(b.onPress, $elm$core$Maybe$Nothing) ? style.ifDisabled : (selected ? style.ifActive : style.otherwise)), + { + label: A2( + $mdgriffith$elm_ui$Element$row, + style.labelRow, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, b.icon), + A2( + $mdgriffith$elm_ui$Element$el, + style.text, + $mdgriffith$elm_ui$Element$text(b.text)) + ])), + onPress: b.onPress + }); + }); +var $author$project$Widget$selectButton = $author$project$Internal$Select$selectButton; +var $elm$core$List$takeReverse = F3( + function (n, list, kept) { + takeReverse: + while (true) { + if (n <= 0) { + return kept; + } else { + if (!list.b) { + return kept; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs, + $temp$kept = A2($elm$core$List$cons, x, kept); + n = $temp$n; + list = $temp$list; + kept = $temp$kept; + continue takeReverse; + } + } + } + }); +var $elm$core$List$takeTailRec = F2( + function (n, list) { + return $elm$core$List$reverse( + A3($elm$core$List$takeReverse, n, list, _List_Nil)); + }); +var $elm$core$List$takeFast = F3( + function (ctr, n, list) { + if (n <= 0) { + return _List_Nil; + } else { + var _v0 = _Utils_Tuple2(n, list); + _v0$1: + while (true) { + _v0$5: + while (true) { + if (!_v0.b.b) { + return list; + } else { + if (_v0.b.b.b) { + switch (_v0.a) { + case 1: + break _v0$1; + case 2: + var _v2 = _v0.b; + var x = _v2.a; + var _v3 = _v2.b; + var y = _v3.a; + return _List_fromArray( + [x, y]); + case 3: + if (_v0.b.b.b.b) { + var _v4 = _v0.b; + var x = _v4.a; + var _v5 = _v4.b; + var y = _v5.a; + var _v6 = _v5.b; + var z = _v6.a; + return _List_fromArray( + [x, y, z]); + } else { + break _v0$5; + } + default: + if (_v0.b.b.b.b && _v0.b.b.b.b.b) { + var _v7 = _v0.b; + var x = _v7.a; + var _v8 = _v7.b; + var y = _v8.a; + var _v9 = _v8.b; + var z = _v9.a; + var _v10 = _v9.b; + var w = _v10.a; + var tl = _v10.b; + return (ctr > 1000) ? A2( + $elm$core$List$cons, + x, + A2( + $elm$core$List$cons, + y, + A2( + $elm$core$List$cons, + z, + A2( + $elm$core$List$cons, + w, + A2($elm$core$List$takeTailRec, n - 4, tl))))) : A2( + $elm$core$List$cons, + x, + A2( + $elm$core$List$cons, + y, + A2( + $elm$core$List$cons, + z, + A2( + $elm$core$List$cons, + w, + A3($elm$core$List$takeFast, ctr + 1, n - 4, tl))))); + } else { + break _v0$5; + } + } + } else { + if (_v0.a === 1) { + break _v0$1; + } else { + break _v0$5; + } + } + } + } + return list; + } + var _v1 = _v0.b; + var x = _v1.a; + return _List_fromArray( + [x]); + } + }); +var $elm$core$List$take = F2( + function (n, list) { + return A3($elm$core$List$takeFast, 0, n, list); }); -var $Orasund$elm_ui_framework$Framework$Input$simple = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Background$color($Orasund$elm_ui_framework$Framework$Color$lighterGrey), - $mdgriffith$elm_ui$Element$Font$color($Orasund$elm_ui_framework$Framework$Color$darkerGrey) - ]); -var $author$project$Widget$FilterSelect$ChangedRaw = function (a) { - return {$: 'ChangedRaw', a: a}; -}; -var $mdgriffith$elm_ui$Element$Input$HiddenLabel = function (a) { - return {$: 'HiddenLabel', a: a}; -}; -var $mdgriffith$elm_ui$Element$Input$labelHidden = $mdgriffith$elm_ui$Element$Input$HiddenLabel; var $mdgriffith$elm_ui$Element$Input$TextInputNode = function (a) { return {$: 'TextInputNode', a: a}; }; @@ -14148,14 +17010,6 @@ var $mdgriffith$elm_ui$Element$Input$autofill = A2( $mdgriffith$elm_ui$Internal$Model$Attr, $elm$html$Html$Attributes$attribute('autocomplete')); var $mdgriffith$elm_ui$Internal$Model$Behind = {$: 'Behind'}; -var $mdgriffith$elm_ui$Element$createNearby = F2( - function (loc, element) { - if (element.$ === 'Empty') { - return $mdgriffith$elm_ui$Internal$Model$NoAttribute; - } else { - return A2($mdgriffith$elm_ui$Internal$Model$Nearby, loc, element); - } - }); var $mdgriffith$elm_ui$Element$behindContent = function (element) { return A2($mdgriffith$elm_ui$Element$createNearby, $mdgriffith$elm_ui$Internal$Model$Behind, element); }; @@ -14194,12 +17048,6 @@ var $mdgriffith$elm_ui$Element$Input$calcMoveToCompensateForPadding = function ( $elm$core$Basics$floor(vSpace / 2)); } }; -var $mdgriffith$elm_ui$Internal$Flag$overflow = $mdgriffith$elm_ui$Internal$Flag$flag(20); -var $mdgriffith$elm_ui$Element$clip = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$overflow, $mdgriffith$elm_ui$Internal$Style$classes.clip); -var $mdgriffith$elm_ui$Element$rgb = F3( - function (r, g, b) { - return A4($mdgriffith$elm_ui$Internal$Model$Rgba, r, g, b, 1); - }); var $mdgriffith$elm_ui$Element$Input$darkGrey = A3($mdgriffith$elm_ui$Element$rgb, 186 / 255, 189 / 255, 182 / 255); var $mdgriffith$elm_ui$Element$Input$defaultTextPadding = A2($mdgriffith$elm_ui$Element$paddingXY, 12, 12); var $mdgriffith$elm_ui$Element$Input$white = A3($mdgriffith$elm_ui$Element$rgb, 1, 1, 1); @@ -14222,9 +17070,6 @@ var $mdgriffith$elm_ui$Element$Input$getHeight = function (attr) { return $elm$core$Maybe$Nothing; } }; -var $mdgriffith$elm_ui$Internal$Model$Label = function (a) { - return {$: 'Label', a: a}; -}; var $mdgriffith$elm_ui$Element$Input$hiddenLabelAttribute = function (label) { if (label.$ === 'HiddenLabel') { var textLabel = label.a; @@ -14234,10 +17079,6 @@ var $mdgriffith$elm_ui$Element$Input$hiddenLabelAttribute = function (label) { return $mdgriffith$elm_ui$Internal$Model$NoAttribute; } }; -var $mdgriffith$elm_ui$Internal$Model$InFront = {$: 'InFront'}; -var $mdgriffith$elm_ui$Element$inFront = function (element) { - return A2($mdgriffith$elm_ui$Element$createNearby, $mdgriffith$elm_ui$Internal$Model$InFront, element); -}; var $mdgriffith$elm_ui$Element$Input$isConstrained = function (len) { isConstrained: while (true) { @@ -14317,7 +17158,6 @@ var $elm$html$Html$Events$onInput = function (tagger) { $elm$html$Html$Events$alwaysStop, A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); }; -var $mdgriffith$elm_ui$Element$htmlAttribute = $mdgriffith$elm_ui$Internal$Model$Attr; var $mdgriffith$elm_ui$Element$Input$isFill = function (len) { isFill: while (true) { @@ -14364,8 +17204,6 @@ var $mdgriffith$elm_ui$Element$Input$isPixel = function (len) { } } }; -var $elm$virtual_dom$VirtualDom$style = _VirtualDom_style; -var $elm$html$Html$Attributes$style = $elm$virtual_dom$VirtualDom$style; var $mdgriffith$elm_ui$Element$Input$redistributeOver = F4( function (isMultiline, stacked, attr, els) { switch (attr.$) { @@ -14879,942 +17717,164 @@ var $mdgriffith$elm_ui$Element$Input$text = $mdgriffith$elm_ui$Element$Input$tex spellchecked: false, type_: $mdgriffith$elm_ui$Element$Input$TextInputNode('text') }); -var $author$project$Widget$FilterSelect$viewInput = F3( - function (attributes, model, _v0) { - var msgMapper = _v0.msgMapper; - var placeholder = _v0.placeholder; - var label = _v0.label; - return A2( - $mdgriffith$elm_ui$Element$Input$text, - attributes, - { - label: $mdgriffith$elm_ui$Element$Input$labelHidden(label), - onChange: A2($elm$core$Basics$composeR, $author$project$Widget$FilterSelect$ChangedRaw, msgMapper), - placeholder: placeholder, - text: model.raw - }); - }); -var $elm$core$Dict$filter = F2( - function (isGood, dict) { - return A3( - $elm$core$Dict$foldl, - F3( - function (k, v, d) { - return A2(isGood, k, v) ? A3($elm$core$Dict$insert, k, v, d) : d; - }), - $elm$core$Dict$empty, - dict); - }); -var $elm$core$Set$filter = F2( - function (isGood, _v0) { - var dict = _v0.a; - return $elm$core$Set$Set_elm_builtin( - A2( - $elm$core$Dict$filter, - F2( - function (key, _v1) { - return isGood(key); - }), - dict)); - }); -var $elm$core$String$toUpper = _String_toUpper; -var $author$project$Widget$FilterSelect$viewOptions = function (_v0) { - var raw = _v0.raw; - var options = _v0.options; - return (raw === '') ? _List_Nil : $elm$core$Set$toList( - A2( - $elm$core$Set$filter, - A2( - $elm$core$Basics$composeR, - $elm$core$String$toUpper, - $elm$core$String$contains( - $elm$core$String$toUpper(raw))), - options)); -}; -var $elm$html$Html$Attributes$width = function (n) { - return A2( - _VirtualDom_attribute, - 'width', - $elm$core$String$fromInt(n)); -}; -var $mdgriffith$elm_ui$Internal$Model$Padding = F5( - function (a, b, c, d, e) { - return {$: 'Padding', a: a, b: b, c: c, d: d, e: e}; - }); -var $mdgriffith$elm_ui$Internal$Model$Spaced = F3( - function (a, b, c) { - return {$: 'Spaced', a: a, b: b, c: c}; - }); -var $mdgriffith$elm_ui$Internal$Model$extractSpacingAndPadding = function (attrs) { - return A3( - $elm$core$List$foldr, - F2( - function (attr, _v0) { - var pad = _v0.a; - var spacing = _v0.b; - return _Utils_Tuple2( - function () { - if (pad.$ === 'Just') { - var x = pad.a; - return pad; - } else { - if ((attr.$ === 'StyleClass') && (attr.b.$ === 'PaddingStyle')) { - var _v3 = attr.b; - var name = _v3.a; - var t = _v3.b; - var r = _v3.c; - var b = _v3.d; - var l = _v3.e; - return $elm$core$Maybe$Just( - A5($mdgriffith$elm_ui$Internal$Model$Padding, name, t, r, b, l)); - } else { - return $elm$core$Maybe$Nothing; - } - } - }(), - function () { - if (spacing.$ === 'Just') { - var x = spacing.a; - return spacing; - } else { - if ((attr.$ === 'StyleClass') && (attr.b.$ === 'SpacingStyle')) { - var _v6 = attr.b; - var name = _v6.a; - var x = _v6.b; - var y = _v6.c; - return $elm$core$Maybe$Just( - A3($mdgriffith$elm_ui$Internal$Model$Spaced, name, x, y)); - } else { - return $elm$core$Maybe$Nothing; - } - } - }()); - }), - _Utils_Tuple2($elm$core$Maybe$Nothing, $elm$core$Maybe$Nothing), - attrs); -}; -var $mdgriffith$elm_ui$Element$wrappedRow = F2( - function (attrs, children) { - var _v0 = $mdgriffith$elm_ui$Internal$Model$extractSpacingAndPadding(attrs); - var padded = _v0.a; - var spaced = _v0.b; - if (spaced.$ === 'Nothing') { - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asRow, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + ($mdgriffith$elm_ui$Internal$Style$classes.contentCenterY + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.wrapped)))), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), - attrs))), - $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); - } else { - var _v2 = spaced.a; - var spaceName = _v2.a; - var x = _v2.b; - var y = _v2.c; - var newPadding = function () { - if (padded.$ === 'Just') { - var _v5 = padded.a; - var name = _v5.a; - var t = _v5.b; - var r = _v5.c; - var b = _v5.d; - var l = _v5.e; - return ((_Utils_cmp(r, (x / 2) | 0) > -1) && (_Utils_cmp(b, (y / 2) | 0) > -1)) ? $elm$core$Maybe$Just( - $mdgriffith$elm_ui$Element$paddingEach( - {bottom: b - ((y / 2) | 0), left: l - ((x / 2) | 0), right: r - ((x / 2) | 0), top: t - ((y / 2) | 0)})) : $elm$core$Maybe$Nothing; - } else { - return $elm$core$Maybe$Nothing; - } - }(); - if (newPadding.$ === 'Just') { - var pad = newPadding.a; - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asRow, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + ($mdgriffith$elm_ui$Internal$Style$classes.contentCenterY + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.wrapped)))), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), - _Utils_ap( - attrs, - _List_fromArray( - [pad]))))), - $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); - } else { - var halfY = -(y / 2); - var halfX = -(x / 2); - return A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asEl, - $mdgriffith$elm_ui$Internal$Model$div, - attrs, - $mdgriffith$elm_ui$Internal$Model$Unkeyed( - _List_fromArray( - [ - A4( - $mdgriffith$elm_ui$Internal$Model$element, - $mdgriffith$elm_ui$Internal$Model$asRow, - $mdgriffith$elm_ui$Internal$Model$div, - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + ($mdgriffith$elm_ui$Internal$Style$classes.contentCenterY + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.wrapped)))), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$Attr( - A2( - $elm$html$Html$Attributes$style, - 'margin', - $elm$core$String$fromFloat(halfY) + ('px' + (' ' + ($elm$core$String$fromFloat(halfX) + 'px'))))), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$Attr( - A2( - $elm$html$Html$Attributes$style, - 'width', - 'calc(100% + ' + ($elm$core$String$fromInt(x) + 'px)'))), - A2( - $elm$core$List$cons, - $mdgriffith$elm_ui$Internal$Model$Attr( - A2( - $elm$html$Html$Attributes$style, - 'height', - 'calc(100% + ' + ($elm$core$String$fromInt(y) + 'px)'))), - A2( - $elm$core$List$cons, - A2( - $mdgriffith$elm_ui$Internal$Model$StyleClass, - $mdgriffith$elm_ui$Internal$Flag$spacing, - A3($mdgriffith$elm_ui$Internal$Model$SpacingStyle, spaceName, x, y)), - _List_Nil))))), - $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)) - ]))); - } - } - }); -var $elm$svg$Svg$Attributes$clipRule = _VirtualDom_attribute('clip-rule'); -var $elm$svg$Svg$Attributes$fillRule = _VirtualDom_attribute('fill-rule'); -var $jasonliang512$elm_heroicons$Heroicons$Solid$x = function (attrs) { - return A2( - $elm$svg$Svg$svg, - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$viewBox('0 0 20 20'), - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$fill('currentColor'), - attrs)), - _List_fromArray( - [ - A2( - $elm$svg$Svg$path, - _List_fromArray( - [ - $elm$svg$Svg$Attributes$fillRule('evenodd'), - $elm$svg$Svg$Attributes$d('M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z'), - $elm$svg$Svg$Attributes$clipRule('evenodd') - ]), - _List_Nil) - ])); -}; -var $author$project$Component$filterSelect = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Filter Select')), - function () { - var _v0 = model.selected; - if (_v0.$ === 'Just') { - var selected = _v0.a; - return A2( - $mdgriffith$elm_ui$Element$row, - $Orasund$elm_ui_framework$Framework$Grid$compact, - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap($Orasund$elm_ui_framework$Framework$Tag$simple, $Orasund$elm_ui_framework$Framework$Group$left), - $mdgriffith$elm_ui$Element$text(selected)), - A2( - $mdgriffith$elm_ui$Element$Input$button, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Tag$simple, - _Utils_ap($Orasund$elm_ui_framework$Framework$Group$right, $Orasund$elm_ui_framework$Framework$Color$danger)), - { - label: $mdgriffith$elm_ui$Element$html( - $jasonliang512$elm_heroicons$Heroicons$Solid$x( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(16) - ]))), - onPress: $elm$core$Maybe$Just( - $author$project$Component$FilterSelectSpecific( - $author$project$Widget$FilterSelect$Selected($elm$core$Maybe$Nothing))) - }) - ])); - } else { - return A2( - $mdgriffith$elm_ui$Element$column, - $Orasund$elm_ui_framework$Framework$Grid$simple, - _List_fromArray( - [ - A3( - $author$project$Widget$FilterSelect$viewInput, - $Orasund$elm_ui_framework$Framework$Input$simple, - model, - { - label: 'Fruit', - msgMapper: $author$project$Component$FilterSelectSpecific, - placeholder: $elm$core$Maybe$Just( - A2( - $mdgriffith$elm_ui$Element$Input$placeholder, - _List_Nil, - $mdgriffith$elm_ui$Element$text('Fruit'))) - }), - A2( - $mdgriffith$elm_ui$Element$wrappedRow, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$spacing(10) - ]), - A2( - $elm$core$List$map, - function (string) { - return A2( - $mdgriffith$elm_ui$Element$Input$button, - _Utils_ap($Orasund$elm_ui_framework$Framework$Button$simple, $Orasund$elm_ui_framework$Framework$Tag$simple), - { - label: $mdgriffith$elm_ui$Element$text(string), - onPress: $elm$core$Maybe$Just( - $author$project$Component$FilterSelectSpecific( - $author$project$Widget$FilterSelect$Selected( - $elm$core$Maybe$Just(string)))) - }); - }, - $author$project$Widget$FilterSelect$viewOptions(model))) - ])); - } - }() - ])); -}; -var $Orasund$elm_ui_framework$Framework$Heading$h2 = $Orasund$elm_ui_framework$Framework$Heading$h(2); -var $author$project$Component$scrollingNavCard = A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Scrolling Nav')), - A2( - $mdgriffith$elm_ui$Element$paragraph, - _List_Nil, - $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$text('Resize the screen and open the side-menu. Then start scrolling to see the scrolling navigation in action.'))) - ])); -var $Orasund$elm_ui_framework$Framework$Grid$section = _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$widthEach( - {bottom: 0, left: 0, right: 0, top: 2}), - $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lightGrey), - $mdgriffith$elm_ui$Element$paddingEach( - {bottom: 30, left: 0, right: 0, top: 10}) - ])); -var $author$project$Component$ValidatedInputSpecific = function (a) { - return {$: 'ValidatedInputSpecific', a: a}; -}; -var $jasonliang512$elm_heroicons$Heroicons$Solid$pencil = function (attrs) { - return A2( - $elm$svg$Svg$svg, - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$viewBox('0 0 20 20'), - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$fill('currentColor'), - attrs)), - _List_fromArray( - [ - A2( - $elm$svg$Svg$path, - _List_fromArray( - [ - $elm$svg$Svg$Attributes$d('M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z') - ]), - _List_Nil) - ])); -}; -var $author$project$Widget$ValidatedInput$ChangedRaw = function (a) { - return {$: 'ChangedRaw', a: a}; -}; -var $author$project$Widget$ValidatedInput$LostFocus = {$: 'LostFocus'}; -var $author$project$Widget$ValidatedInput$StartEditing = {$: 'StartEditing'}; -var $elm$html$Html$Events$onBlur = function (msg) { - return A2( - $elm$html$Html$Events$on, - 'blur', - $elm$json$Json$Decode$succeed(msg)); -}; -var $mdgriffith$elm_ui$Element$Events$onLoseFocus = A2($elm$core$Basics$composeL, $mdgriffith$elm_ui$Internal$Model$Attr, $elm$html$Html$Events$onBlur); -var $author$project$Widget$ValidatedInput$view = F3( - function (attributes, _v0, _v1) { - var model = _v0.a; - var msgMapper = _v1.msgMapper; - var placeholder = _v1.placeholder; - var label = _v1.label; - var readOnly = _v1.readOnly; - var _v2 = model.raw; - if (_v2.$ === 'Just') { - var string = _v2.a; - return A2( - $mdgriffith$elm_ui$Element$Input$text, - _Utils_ap( - attributes, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Events$onLoseFocus( - msgMapper($author$project$Widget$ValidatedInput$LostFocus)) - ])), - { - label: $mdgriffith$elm_ui$Element$Input$labelHidden(label), - onChange: A2($elm$core$Basics$composeR, $author$project$Widget$ValidatedInput$ChangedRaw, msgMapper), - placeholder: placeholder, - text: string - }); - } else { - return A2( - $mdgriffith$elm_ui$Element$Input$button, - _List_Nil, - { - label: readOnly(model.value), - onPress: $elm$core$Maybe$Just( - msgMapper($author$project$Widget$ValidatedInput$StartEditing)) - }); - } - }); -var $author$project$Component$validatedInput = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Validated Input')), - A3( - $author$project$Widget$ValidatedInput$view, - $Orasund$elm_ui_framework$Framework$Input$simple, - model, - { - label: 'First Name, Sir Name', - msgMapper: $author$project$Component$ValidatedInputSpecific, - placeholder: $elm$core$Maybe$Nothing, - readOnly: function (maybeTuple) { - return A2( - $mdgriffith$elm_ui$Element$row, - $Orasund$elm_ui_framework$Framework$Grid$compact, - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap($Orasund$elm_ui_framework$Framework$Tag$simple, $Orasund$elm_ui_framework$Framework$Group$left), - $mdgriffith$elm_ui$Element$text( - function (_v0) { - var a = _v0.a; - var b = _v0.b; - return a + (' ' + b); - }(maybeTuple))), - A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Tag$simple, - _Utils_ap($Orasund$elm_ui_framework$Framework$Group$right, $Orasund$elm_ui_framework$Framework$Color$primary)), - $mdgriffith$elm_ui$Element$html( - $jasonliang512$elm_heroicons$Heroicons$Solid$pencil( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(16) - ])))) - ])); - } - }) - ])); -}; -var $author$project$Component$view = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$section, - _List_fromArray( - [$mdgriffith$elm_ui$Element$centerX])), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h2, - $mdgriffith$elm_ui$Element$text('Components')), - A2( - $mdgriffith$elm_ui$Element$paragraph, - _List_Nil, - $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$text('Components have a Model, an Update- and sometimes even a Subscription-function. It takes some time to set them up correctly.'))), - A2( - $mdgriffith$elm_ui$Element$wrappedRow, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) - ])), - _List_fromArray( - [ - $author$project$Component$filterSelect(model.filterSelect), - $author$project$Component$validatedInput(model.validatedInput), - $author$project$Component$scrollingNavCard - ])) - ])); -}; -var $author$project$Layout$Left = {$: 'Left'}; -var $author$project$Layout$Right = {$: 'Right'}; -var $mdgriffith$elm_ui$Internal$Model$Bottom = {$: 'Bottom'}; -var $mdgriffith$elm_ui$Element$alignBottom = $mdgriffith$elm_ui$Internal$Model$AlignY($mdgriffith$elm_ui$Internal$Model$Bottom); var $author$project$Widget$Snackbar$current = function (model) { return A2($elm$core$Maybe$map, $elm$core$Tuple$first, model.current); }; -var $elm$core$List$drop = F2( - function (n, list) { - drop: - while (true) { - if (n <= 0) { - return list; - } else { - if (!list.b) { - return list; - } else { - var x = list.a; - var xs = list.b; - var $temp$n = n - 1, - $temp$list = xs; - n = $temp$n; - list = $temp$list; - continue drop; - } - } - } - }); -var $author$project$Core$Style$menuButton = F2( - function (config, _v0) { - var label = _v0.label; - var icon = _v0.icon; +var $author$project$Widget$textButton = F2( + function (style, _v0) { + var text = _v0.text; var onPress = _v0.onPress; return A2( - $mdgriffith$elm_ui$Element$Input$button, - config.menuButton, - { - label: A2( - $mdgriffith$elm_ui$Element$row, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$spacing(8) - ]), - _List_fromArray( - [ - A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), - $mdgriffith$elm_ui$Element$text(label) - ])), - onPress: onPress - }); + $author$project$Internal$Button$textButton, + style, + {onPress: onPress, text: text}); }); -var $author$project$Core$Style$menuIconButton = F2( - function (config, _v0) { - var label = _v0.label; - var icon = _v0.icon; - var onPress = _v0.onPress; +var $author$project$Widget$Snackbar$view = F3( + function (style, toMessage, model) { return A2( - $mdgriffith$elm_ui$Element$Input$button, - config.menuButton, - { - label: A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), - onPress: onPress - }); - }); -var $author$project$Core$Style$menuTabButton = F2( - function (config, _v0) { - var label = _v0.label; - var icon = _v0.icon; - var onPress = _v0.onPress; - return A2( - $mdgriffith$elm_ui$Element$Input$button, - _Utils_ap(config.menuButton, config.tabButton), - { - label: A2( - $mdgriffith$elm_ui$Element$row, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$spacing(8) - ]), - _List_fromArray( - [ - A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), - $mdgriffith$elm_ui$Element$text(label) - ])), - onPress: onPress - }); - }); -var $author$project$Core$Style$menuTabButtonSelected = F2( - function (config, _v0) { - var label = _v0.label; - var icon = _v0.icon; - var onPress = _v0.onPress; - return A2( - $mdgriffith$elm_ui$Element$Input$button, - _Utils_ap( - config.menuButton, - _Utils_ap(config.tabButton, config.tabButtonSelected)), - { - label: A2( - $mdgriffith$elm_ui$Element$row, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$spacing(8) - ]), - _List_fromArray( - [ - A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), - $mdgriffith$elm_ui$Element$text(label) - ])), - onPress: onPress - }); - }); -var $mdgriffith$elm_ui$Element$rgba255 = F4( - function (red, green, blue, a) { - return A4($mdgriffith$elm_ui$Internal$Model$Rgba, red / 255, green / 255, blue / 255, a); - }); -var $author$project$Widget$scrim = function (_v0) { - var onDismiss = _v0.onDismiss; - var content = _v0.content; - return $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$inFront( + $elm$core$Maybe$map, A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap( - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill), - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), - $mdgriffith$elm_ui$Element$Background$color( - A4($mdgriffith$elm_ui$Element$rgba255, 0, 0, 0, 0.5)) - ]), - A2( - $elm$core$Maybe$withDefault, - _List_Nil, - A2( - $elm$core$Maybe$map, - A2($elm$core$Basics$composeR, $mdgriffith$elm_ui$Element$Events$onClick, $elm$core$List$singleton), - onDismiss))), - content))); -}; -var $author$project$Core$Style$sheetButton = F2( - function (config, _v0) { - var label = _v0.label; - var icon = _v0.icon; - var onPress = _v0.onPress; - return A2( - $mdgriffith$elm_ui$Element$Input$button, - config.sheetButton, - { - label: A2( - $mdgriffith$elm_ui$Element$row, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$spacing(8) - ]), - _List_fromArray( - [ - A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), - $mdgriffith$elm_ui$Element$text(label) - ])), - onPress: onPress - }); + $elm$core$Basics$composeR, + toMessage, + function (_v0) { + var text = _v0.text; + var button = _v0.button; + return A2( + $mdgriffith$elm_ui$Element$row, + style.containerRow, + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$paragraph, + style.text, + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text(text))), + A2( + $elm$core$Maybe$withDefault, + $mdgriffith$elm_ui$Element$none, + A2( + $elm$core$Maybe$map, + $author$project$Widget$textButton(style.button), + button)) + ])); + }), + $author$project$Widget$Snackbar$current(model)); }); -var $author$project$Core$Style$sheetButtonSelected = F2( - function (config, _v0) { - var label = _v0.label; - var icon = _v0.icon; - var onPress = _v0.onPress; - return A2( - $mdgriffith$elm_ui$Element$Input$button, - _Utils_ap(config.sheetButton, config.sheetButtonSelected), - { - label: A2( - $mdgriffith$elm_ui$Element$row, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$spacing(8) - ]), - _List_fromArray( - [ - A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, icon), - $mdgriffith$elm_ui$Element$text(label) - ])), - onPress: onPress - }); - }); -var $mdgriffith$elm_ui$Element$spaceEvenly = A2($mdgriffith$elm_ui$Internal$Model$Class, $mdgriffith$elm_ui$Internal$Flag$spacing, $mdgriffith$elm_ui$Internal$Style$classes.spaceEvenly); -var $elm$core$List$takeReverse = F3( - function (n, list, kept) { - takeReverse: - while (true) { - if (n <= 0) { - return kept; - } else { - if (!list.b) { - return kept; - } else { - var x = list.a; - var xs = list.b; - var $temp$n = n - 1, - $temp$list = xs, - $temp$kept = A2($elm$core$List$cons, x, kept); - n = $temp$n; - list = $temp$list; - kept = $temp$kept; - continue takeReverse; - } - } - } - }); -var $elm$core$List$takeTailRec = F2( - function (n, list) { - return $elm$core$List$reverse( - A3($elm$core$List$takeReverse, n, list, _List_Nil)); - }); -var $elm$core$List$takeFast = F3( - function (ctr, n, list) { - if (n <= 0) { - return _List_Nil; - } else { - var _v0 = _Utils_Tuple2(n, list); - _v0$1: - while (true) { - _v0$5: - while (true) { - if (!_v0.b.b) { - return list; - } else { - if (_v0.b.b.b) { - switch (_v0.a) { - case 1: - break _v0$1; - case 2: - var _v2 = _v0.b; - var x = _v2.a; - var _v3 = _v2.b; - var y = _v3.a; - return _List_fromArray( - [x, y]); - case 3: - if (_v0.b.b.b.b) { - var _v4 = _v0.b; - var x = _v4.a; - var _v5 = _v4.b; - var y = _v5.a; - var _v6 = _v5.b; - var z = _v6.a; - return _List_fromArray( - [x, y, z]); - } else { - break _v0$5; - } - default: - if (_v0.b.b.b.b && _v0.b.b.b.b.b) { - var _v7 = _v0.b; - var x = _v7.a; - var _v8 = _v7.b; - var y = _v8.a; - var _v9 = _v8.b; - var z = _v9.a; - var _v10 = _v9.b; - var w = _v10.a; - var tl = _v10.b; - return (ctr > 1000) ? A2( - $elm$core$List$cons, - x, - A2( - $elm$core$List$cons, - y, - A2( - $elm$core$List$cons, - z, - A2( - $elm$core$List$cons, - w, - A2($elm$core$List$takeTailRec, n - 4, tl))))) : A2( - $elm$core$List$cons, - x, - A2( - $elm$core$List$cons, - y, - A2( - $elm$core$List$cons, - z, - A2( - $elm$core$List$cons, - w, - A3($elm$core$List$takeFast, ctr + 1, n - 4, tl))))); - } else { - break _v0$5; - } - } - } else { - if (_v0.a === 1) { - break _v0$1; - } else { - break _v0$5; - } - } - } - } - return list; - } - var _v1 = _v0.b; - var x = _v1.a; - return _List_fromArray( - [x]); - } - }); -var $elm$core$List$take = F2( - function (n, list) { - return A3($elm$core$List$takeFast, 0, n, list); - }); -var $author$project$Layout$view = F2( - function (attributes, _v0) { +var $author$project$Widget$Layout$view = F3( + function (style, _v0, content) { + var search = _v0.search; var title = _v0.title; var onChangedSidebar = _v0.onChangedSidebar; var menu = _v0.menu; var actions = _v0.actions; - var deviceClass = _v0.deviceClass; + var window = _v0.window; var dialog = _v0.dialog; - var content = _v0.content; - var style = _v0.style; var layout = _v0.layout; var snackbar = A2( $elm$core$Maybe$withDefault, $mdgriffith$elm_ui$Element$none, A2( $elm$core$Maybe$map, - A2( - $elm$core$Basics$composeR, - $mdgriffith$elm_ui$Element$text, - A2( - $elm$core$Basics$composeR, - $elm$core$List$singleton, - A2( - $elm$core$Basics$composeR, - $mdgriffith$elm_ui$Element$paragraph(style.snackbar), - $mdgriffith$elm_ui$Element$el( - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$padding(8), - $mdgriffith$elm_ui$Element$alignBottom, - $mdgriffith$elm_ui$Element$alignRight - ]))))), - $author$project$Widget$Snackbar$current(layout.snackbar))); + $mdgriffith$elm_ui$Element$el( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$padding(style.spacing), + $mdgriffith$elm_ui$Element$alignBottom, + $mdgriffith$elm_ui$Element$alignRight + ])), + A3($author$project$Widget$Snackbar$view, style.snackbar, $elm$core$Basics$identity, layout.snackbar))); + var deviceClass = $mdgriffith$elm_ui$Element$classifyDevice(window)._class; var _v1 = _Utils_Tuple2( ($elm$core$List$length(actions) > 4) ? A2($elm$core$List$take, 2, actions) : (($elm$core$List$length(actions) === 4) ? A2($elm$core$List$take, 1, actions) : (($elm$core$List$length(actions) === 3) ? _List_Nil : A2($elm$core$List$take, 2, actions))), ($elm$core$List$length(actions) > 4) ? A2($elm$core$List$drop, 2, actions) : (($elm$core$List$length(actions) === 4) ? A2($elm$core$List$drop, 1, actions) : (($elm$core$List$length(actions) === 3) ? actions : A2($elm$core$List$drop, 2, actions)))); var primaryActions = _v1.a; var moreActions = _v1.b; var sheet = function () { - var _v4 = layout.sheet; - if (_v4.$ === 'Just') { - if (_v4.a.$ === 'Left') { - var _v5 = _v4.a; - return A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap( - style.sheet, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), - $mdgriffith$elm_ui$Element$alignLeft - ])), - A2( - $mdgriffith$elm_ui$Element$column, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) - ]), + var _v5 = layout.active; + if (_v5.$ === 'Just') { + switch (_v5.a.$) { + case 'LeftSheet': + var _v6 = _v5.a; + return A2( + $mdgriffith$elm_ui$Element$el, + _Utils_ap( + style.sheet, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$alignLeft + ])), A2( - $elm$core$List$indexedMap, - function (i) { - return _Utils_eq(i, menu.selected) ? $author$project$Core$Style$sheetButtonSelected(style) : $author$project$Core$Style$sheetButton(style); - }, - menu.items))); - } else { - var _v6 = _v4.a; - return A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap( - style.sheet, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), - $mdgriffith$elm_ui$Element$alignRight - ])), - A2( - $mdgriffith$elm_ui$Element$column, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) - ]), + $mdgriffith$elm_ui$Element$column, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ]), + $elm$core$List$concat( + _List_fromArray( + [ + _List_fromArray( + [title]), + A2( + $elm$core$List$map, + $author$project$Widget$selectButton(style.sheetButton), + $author$project$Widget$select(menu)) + ])))); + case 'RightSheet': + var _v7 = _v5.a; + return A2( + $mdgriffith$elm_ui$Element$el, + _Utils_ap( + style.sheet, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill), + $mdgriffith$elm_ui$Element$alignRight + ])), A2( - $elm$core$List$map, - $author$project$Core$Style$sheetButton(style), - moreActions))); + $mdgriffith$elm_ui$Element$column, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ]), + A2( + $elm$core$List$map, + $author$project$Widget$button(style.sheetButton), + moreActions))); + default: + var _v8 = _v5.a; + if (search.$ === 'Just') { + var onChange = search.a.onChange; + var text = search.a.text; + var label = search.a.label; + return A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$alignTop, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ]), + A2( + $mdgriffith$elm_ui$Element$Input$text, + _Utils_ap( + style.searchFill, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) + ])), + { + label: $mdgriffith$elm_ui$Element$Input$labelHidden(label), + onChange: onChange, + placeholder: $elm$core$Maybe$Just( + A2( + $mdgriffith$elm_ui$Element$Input$placeholder, + _List_Nil, + $mdgriffith$elm_ui$Element$text(label))), + text: text + })); + } else { + return $mdgriffith$elm_ui$Element$none; + } } } else { return $mdgriffith$elm_ui$Element$none; @@ -15828,7 +17888,7 @@ var $author$project$Layout$view = F2( [ $mdgriffith$elm_ui$Element$padding(0), $mdgriffith$elm_ui$Element$centerX, - $mdgriffith$elm_ui$Element$spaceEvenly, + $mdgriffith$elm_ui$Element$spacing(style.spacing), $mdgriffith$elm_ui$Element$alignTop, $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) ])), @@ -15839,23 +17899,46 @@ var $author$project$Layout$view = F2( _List_fromArray( [ $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), - $mdgriffith$elm_ui$Element$spacing(8) + $mdgriffith$elm_ui$Element$spacing(style.spacing) ]), - (_Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Phone) || (_Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Tablet) || ($elm$core$List$length(menu.items) > 5))) ? _List_fromArray( + (_Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Phone) || (_Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Tablet) || ($elm$core$List$length(menu.options) > 5))) ? _List_fromArray( [ A2( - $mdgriffith$elm_ui$Element$Input$button, + $author$project$Widget$iconButton, style.menuButton, { - label: A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, style.menuIcon), + icon: A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, style.menuIcon), onPress: $elm$core$Maybe$Just( onChangedSidebar( - $elm$core$Maybe$Just($author$project$Layout$Left))) + $elm$core$Maybe$Just($author$project$Widget$Layout$LeftSheet))), + text: 'Menu' }), - title + A2( + $mdgriffith$elm_ui$Element$el, + style.title, + A2( + $elm$core$Maybe$withDefault, + title, + A2( + $elm$core$Maybe$map, + A2( + $elm$core$Basics$composeR, + function ($) { + return $.text; + }, + $mdgriffith$elm_ui$Element$text), + A2( + $elm$core$Maybe$andThen, + function (option) { + return A2( + $elm$core$Array$get, + option, + $elm$core$Array$fromList(menu.options)); + }, + menu.selected)))) ]) : _List_fromArray( [ - title, + A2($mdgriffith$elm_ui$Element$el, style.title, title), A2( $mdgriffith$elm_ui$Element$row, _List_fromArray( @@ -15863,12 +17946,34 @@ var $author$project$Layout$view = F2( $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink) ]), A2( - $elm$core$List$indexedMap, - function (i) { - return _Utils_eq(i, menu.selected) ? $author$project$Core$Style$menuTabButtonSelected(style) : $author$project$Core$Style$menuTabButton(style); - }, - menu.items)) + $elm$core$List$map, + $author$project$Widget$selectButton(style.menuTabButton), + $author$project$Widget$select(menu))) ])), + (_Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Phone) || _Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Tablet)) ? $mdgriffith$elm_ui$Element$none : A2( + $elm$core$Maybe$withDefault, + $mdgriffith$elm_ui$Element$none, + A2( + $elm$core$Maybe$map, + function (_v3) { + var onChange = _v3.onChange; + var text = _v3.text; + var label = _v3.label; + return A2( + $mdgriffith$elm_ui$Element$Input$text, + style.search, + { + label: $mdgriffith$elm_ui$Element$Input$labelHidden(label), + onChange: onChange, + placeholder: $elm$core$Maybe$Just( + A2( + $mdgriffith$elm_ui$Element$Input$placeholder, + _List_Nil, + $mdgriffith$elm_ui$Element$text(label))), + text: text + }); + }, + search)), A2( $mdgriffith$elm_ui$Element$row, _List_fromArray( @@ -15880,20 +17985,54 @@ var $author$project$Layout$view = F2( _List_fromArray( [ A2( + $elm$core$Maybe$withDefault, + _List_Nil, + A2( + $elm$core$Maybe$map, + function (_v4) { + var label = _v4.label; + return _Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Tablet) ? _List_fromArray( + [ + A2( + $author$project$Widget$button, + style.menuButton, + { + icon: style.searchIcon, + onPress: $elm$core$Maybe$Just( + onChangedSidebar( + $elm$core$Maybe$Just($author$project$Widget$Layout$Search))), + text: label + }) + ]) : (_Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Phone) ? _List_fromArray( + [ + A2( + $author$project$Widget$iconButton, + style.menuButton, + { + icon: style.searchIcon, + onPress: $elm$core$Maybe$Just( + onChangedSidebar( + $elm$core$Maybe$Just($author$project$Widget$Layout$Search))), + text: label + }) + ]) : _List_Nil); + }, + search)), + A2( $elm$core$List$map, - _Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Phone) ? $author$project$Core$Style$menuIconButton(style) : $author$project$Core$Style$menuButton(style), + _Utils_eq(deviceClass, $mdgriffith$elm_ui$Element$Phone) ? $author$project$Widget$iconButton(style.menuButton) : $author$project$Widget$button(style.menuButton), primaryActions), $elm$core$List$isEmpty(moreActions) ? _List_Nil : _List_fromArray( [ A2( - $author$project$Core$Style$menuButton, - style, + $author$project$Widget$iconButton, + style.menuButton, { icon: style.moreVerticalIcon, - label: '', onPress: $elm$core$Maybe$Just( onChangedSidebar( - $elm$core$Maybe$Just($author$project$Layout$Right))) + $elm$core$Maybe$Just($author$project$Widget$Layout$RightSheet))), + text: 'More' }) ]) ]))) @@ -15903,163 +18042,738 @@ var $author$project$Layout$view = F2( $elm$core$List$concat( _List_fromArray( [ - attributes, + style.container, _List_fromArray( [ $mdgriffith$elm_ui$Element$inFront(nav), $mdgriffith$elm_ui$Element$inFront(snackbar) ]), - ((!_Utils_eq(layout.sheet, $elm$core$Maybe$Nothing)) || (!_Utils_eq(dialog, $elm$core$Maybe$Nothing))) ? $author$project$Widget$scrim( - { - content: $mdgriffith$elm_ui$Element$none, - onDismiss: $elm$core$Maybe$Just( - function () { - if (dialog.$ === 'Just') { - var onDismiss = dialog.a.onDismiss; - return A2( - $elm$core$Maybe$withDefault, - onChangedSidebar($elm$core$Maybe$Nothing), - onDismiss); - } else { - return onChangedSidebar($elm$core$Maybe$Nothing); - } - }()) - }) : _List_Nil, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$inFront(sheet), - $mdgriffith$elm_ui$Element$inFront( - function () { - if (dialog.$ === 'Just') { - var element = dialog.a; - return element.content; - } else { - return $mdgriffith$elm_ui$Element$none; - } - }()) - ]) + function () { + if ((!_Utils_eq(layout.active, $elm$core$Maybe$Nothing)) || (!_Utils_eq(dialog, $elm$core$Maybe$Nothing))) { + if (dialog.$ === 'Just') { + var dialogConfig = dialog.a; + return dialogConfig; + } else { + return $author$project$Widget$modal( + { + content: sheet, + onDismiss: $elm$core$Maybe$Just( + onChangedSidebar($elm$core$Maybe$Nothing)) + }); + } + } else { + return _List_Nil; + } + }() ])), content); }); -var $author$project$Reusable$snackbar = function (addSnackbar) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Snackbar')), - A2( - $mdgriffith$elm_ui$Element$Input$button, - $Orasund$elm_ui_framework$Framework$Button$simple, - { - label: A2( - $mdgriffith$elm_ui$Element$paragraph, - _List_Nil, - $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$text('Add Notification'))), - onPress: $elm$core$Maybe$Just( - addSnackbar('This is a notification. It will disappear after 10 seconds.')) - }) - ])); +var $author$project$Data$Section$ReusableViews = {$: 'ReusableViews'}; +var $author$project$Data$Section$StatelessViews = {$: 'StatelessViews'}; +var $author$project$Main$ToggledExample = function (a) { + return {$: 'ToggledExample', a: a}; }; -var $author$project$Reusable$SortBy = function (a) { - return {$: 'SortBy', a: a}; -}; -var $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronDown = function (attrs) { +var $author$project$Internal$List$internal = F2( + function (style, list) { + return A2( + $elm$core$List$indexedMap, + function (i) { + return $mdgriffith$elm_ui$Element$el( + _Utils_ap( + style.element, + ($elm$core$List$length(list) === 1) ? _List_Nil : ((!i) ? style.ifFirst : (_Utils_eq( + i, + $elm$core$List$length(list) - 1) ? style.ifLast : style.otherwise)))); + }, + list); + }); +var $author$project$Internal$List$column = function (style) { return A2( - $elm$svg$Svg$svg, + $elm$core$Basics$composeR, + $author$project$Internal$List$internal(style), + $mdgriffith$elm_ui$Element$column(style.containerColumn)); +}; +var $author$project$Widget$column = $author$project$Internal$List$column; +var $author$project$Internal$ExpansionPanel$expansionPanel = F2( + function (style, model) { + return A2( + $mdgriffith$elm_ui$Element$column, + style.containerColumn, + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$row, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$Events$onClick( + model.onToggle(!model.isExpanded)), + style.panelRow), + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$row, + style.labelRow, + _List_fromArray( + [ + A2($mdgriffith$elm_ui$Element$map, $elm$core$Basics$never, model.icon), + $mdgriffith$elm_ui$Element$text(model.text) + ])), + A2( + $mdgriffith$elm_ui$Element$map, + $elm$core$Basics$never, + model.isExpanded ? style.collapseIcon : style.expandIcon) + ])), + model.isExpanded ? A2($mdgriffith$elm_ui$Element$el, style.content, model.content) : $mdgriffith$elm_ui$Element$none + ])); + }); +var $author$project$Widget$expansionPanel = $author$project$Internal$ExpansionPanel$expansionPanel; +var $elm$html$Html$Attributes$id = $elm$html$Html$Attributes$stringProperty('id'); +var $Orasund$elm_ui_framework$Framework$Grid$section = _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$Border$widthEach( + {bottom: 0, left: 0, right: 0, top: 2}), + $mdgriffith$elm_ui$Element$Border$color($Orasund$elm_ui_framework$Framework$Color$lightGrey), + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 30, left: 0, right: 0, top: 10}) + ])); +var $author$project$Reusable$layout = function (_v0) { + return _Utils_Tuple3( + 'Layout', A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$viewBox('0 0 20 20'), - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$fill('currentColor'), - attrs)), - _List_fromArray( - [ - A2( - $elm$svg$Svg$path, - _List_fromArray( - [ - $elm$svg$Svg$Attributes$fillRule('evenodd'), - $elm$svg$Svg$Attributes$d('M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z'), - $elm$svg$Svg$Attributes$clipRule('evenodd') - ]), - _List_Nil) - ])); + $mdgriffith$elm_ui$Element$paragraph, + _List_Nil, + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text('The layout combines the menu bar, both side bar, the dialog window and the snackbar. Try using all of them and also try resizing the window to see how they interact with each other.'))), + $mdgriffith$elm_ui$Element$none); }; -var $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronUp = function (attrs) { - return A2( - $elm$svg$Svg$svg, +var $author$project$Reusable$scrollingNavCard = function (_v0) { + return _Utils_Tuple3( + 'Scrolling Nav', A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$viewBox('0 0 20 20'), + $mdgriffith$elm_ui$Element$paragraph, + _List_Nil, + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text('Resize the screen and open the side-menu. Then start scrolling to see the scrolling navigation in action.'))), + $mdgriffith$elm_ui$Element$none); +}; +var $author$project$Reusable$snackbar = F2( + function (style, addSnackbar) { + return _Utils_Tuple3( + 'Snackbar', A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$fill('currentColor'), - attrs)), - _List_fromArray( - [ - A2( - $elm$svg$Svg$path, + $mdgriffith$elm_ui$Element$column, + $Orasund$elm_ui_framework$Framework$Grid$simple, _List_fromArray( [ - $elm$svg$Svg$Attributes$fillRule('evenodd'), - $elm$svg$Svg$Attributes$d('M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z'), - $elm$svg$Svg$Attributes$clipRule('evenodd') - ]), - _List_Nil) - ])); + A2( + $author$project$Widget$button, + style.button, + { + icon: $mdgriffith$elm_ui$Element$none, + onPress: $elm$core$Maybe$Just( + addSnackbar( + _Utils_Tuple2('This is a notification. It will disappear after 10 seconds.', false))), + text: 'Add Notification' + }), + A2( + $author$project$Widget$button, + style.button, + { + icon: $mdgriffith$elm_ui$Element$none, + onPress: $elm$core$Maybe$Just( + addSnackbar( + _Utils_Tuple2('You can add another notification if you want.', true))), + text: 'Add Notification with Action' + }) + ])), + $mdgriffith$elm_ui$Element$none); + }); +var $author$project$Reusable$view = function (_v0) { + var theme = _v0.theme; + var addSnackbar = _v0.addSnackbar; + var style = $author$project$Data$Theme$toStyle(theme); + return { + description: 'Reusable views have an internal state but no update function. You will need to do some wiring, but nothing complicated.', + items: _List_fromArray( + [ + A2($author$project$Reusable$snackbar, style, addSnackbar), + $author$project$Reusable$scrollingNavCard(style), + $author$project$Reusable$layout(style) + ]), + title: 'Reusable Views' + }; }; -var $author$project$Widget$SortTable$FloatColumn = function (a) { +var $author$project$Stateless$Idle = {$: 'Idle'}; +var $author$project$Data$Example$get = function (example) { + switch (example.$) { + case 'ButtonExample': + return function ($) { + return $.button; + }; + case 'SelectExample': + return function ($) { + return $.select; + }; + case 'MultiSelectExample': + return function ($) { + return $.multiSelect; + }; + case 'ExpansionPanelExample': + return function ($) { + return $.expansionPanel; + }; + case 'TabExample': + return function ($) { + return $.tab; + }; + case 'SortTableExample': + return function ($) { + return $.sortTable; + }; + case 'ModalExample': + return function ($) { + return $.modal; + }; + case 'DialogExample': + return function ($) { + return $.dialog; + }; + case 'TextInputExample': + return function ($) { + return $.textInput; + }; + default: + return function ($) { + return $.list; + }; + } +}; +var $author$project$Icons$triangle = A2( + $author$project$Icons$svgFeatherIcon, + 'triangle', + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z') + ]), + _List_Nil) + ])); +var $author$project$View$Test$button = F2( + function (idle, style) { + return _List_fromArray( + [ + _Utils_Tuple2( + 'Button', + A2( + $author$project$Widget$button, + style.button, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + onPress: $elm$core$Maybe$Just(idle), + text: 'Button' + })), + _Utils_Tuple2( + 'Text button', + A2( + $author$project$Widget$textButton, + style.button, + { + onPress: $elm$core$Maybe$Just(idle), + text: 'Button' + })), + _Utils_Tuple2( + 'Icon button', + A2( + $author$project$Widget$iconButton, + style.button, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + onPress: $elm$core$Maybe$Just(idle), + text: 'Button' + })), + _Utils_Tuple2( + 'Disabled button', + A2( + $author$project$Widget$button, + style.button, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + onPress: $elm$core$Maybe$Nothing, + text: 'Button' + })), + _Utils_Tuple2( + 'Inactive Select button', + A2( + $author$project$Widget$selectButton, + style.button, + _Utils_Tuple2( + false, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + onPress: $elm$core$Maybe$Just(idle), + text: 'Button' + }))), + _Utils_Tuple2( + 'Active Select button', + A2( + $author$project$Widget$selectButton, + style.button, + _Utils_Tuple2( + true, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + onPress: $elm$core$Maybe$Just(idle), + text: 'Button' + }))) + ]); + }); +var $author$project$View$Test$dialog = F2( + function (_v0, _v1) { + return _List_Nil; + }); +var $author$project$View$Test$expansionPanel = F2( + function (idle, style) { + return _List_fromArray( + [ + _Utils_Tuple2( + 'Collapsed', + A2( + $author$project$Widget$expansionPanel, + style.expansionPanel, + { + content: $mdgriffith$elm_ui$Element$text('Hidden Message'), + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + isExpanded: false, + onToggle: $elm$core$Basics$always(idle), + text: 'Button' + })), + _Utils_Tuple2( + 'Expanded', + A2( + $author$project$Widget$expansionPanel, + style.expansionPanel, + { + content: $mdgriffith$elm_ui$Element$text('Hidden Message'), + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + isExpanded: true, + onToggle: $elm$core$Basics$always(idle), + text: 'Button' + })) + ]); + }); +var $author$project$Internal$List$row = function (style) { + return A2( + $elm$core$Basics$composeR, + $author$project$Internal$List$internal(style), + $mdgriffith$elm_ui$Element$row(style.containerRow)); +}; +var $author$project$Widget$row = $author$project$Internal$List$row; +var $author$project$View$Test$list = F2( + function (_v0, style) { + return _List_fromArray( + [ + _Utils_Tuple2( + 'Row', + A2( + $author$project$Widget$row, + style.row, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$text('A'), + $mdgriffith$elm_ui$Element$text('B'), + $mdgriffith$elm_ui$Element$text('C') + ]))), + _Utils_Tuple2( + 'Column', + A2( + $author$project$Widget$column, + style.cardColumn, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$text('A'), + $mdgriffith$elm_ui$Element$text('B'), + $mdgriffith$elm_ui$Element$text('C') + ]))), + _Utils_Tuple2( + 'Singleton List', + A2( + $author$project$Widget$column, + style.cardColumn, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$text('A') + ]))), + _Utils_Tuple2( + 'Empty List', + A2($author$project$Widget$column, style.cardColumn, _List_Nil)) + ]); + }); +var $author$project$View$Test$modal = F2( + function (_v0, _v1) { + return _List_Nil; + }); +var $author$project$Internal$List$internalButton = F2( + function (style, list) { + return A2( + $elm$core$List$indexedMap, + function (i) { + return A2( + $elm$core$Basics$composeR, + $author$project$Internal$Select$selectButton( + { + container: _Utils_ap( + style.button.container, + _Utils_ap( + style.list.element, + ($elm$core$List$length(list) === 1) ? _List_Nil : ((!i) ? style.list.ifFirst : (_Utils_eq( + i, + $elm$core$List$length(list) - 1) ? style.list.ifLast : style.list.otherwise)))), + ifActive: style.button.ifActive, + ifDisabled: style.button.ifDisabled, + labelRow: style.button.labelRow, + otherwise: style.button.otherwise, + text: style.button.text + }), + $mdgriffith$elm_ui$Element$el(_List_Nil)); + }, + list); + }); +var $author$project$Internal$List$buttonRow = function (style) { + return A2( + $elm$core$Basics$composeR, + $author$project$Internal$List$internalButton(style), + $mdgriffith$elm_ui$Element$row(style.list.containerRow)); +}; +var $author$project$Widget$buttonRow = $author$project$Internal$List$buttonRow; +var $elm$core$Set$fromList = function (list) { + return A3($elm$core$List$foldl, $elm$core$Set$insert, $elm$core$Set$empty, list); +}; +var $author$project$Internal$Select$multiSelect = function (_v0) { + var selected = _v0.selected; + var options = _v0.options; + var onSelect = _v0.onSelect; + return A2( + $elm$core$List$indexedMap, + F2( + function (i, a) { + return _Utils_Tuple2( + A2($elm$core$Set$member, i, selected), + { + icon: a.icon, + onPress: onSelect(i), + text: a.text + }); + }), + options); +}; +var $author$project$Widget$multiSelect = $author$project$Internal$Select$multiSelect; +var $elm$core$Dict$singleton = F2( + function (key, value) { + return A5($elm$core$Dict$RBNode_elm_builtin, $elm$core$Dict$Black, key, value, $elm$core$Dict$RBEmpty_elm_builtin, $elm$core$Dict$RBEmpty_elm_builtin); + }); +var $elm$core$Set$singleton = function (key) { + return $elm$core$Set$Set_elm_builtin( + A2($elm$core$Dict$singleton, key, _Utils_Tuple0)); +}; +var $author$project$View$Test$multiSelect = F2( + function (idle, style) { + return _List_fromArray( + [ + _Utils_Tuple2( + 'Some selected', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$multiSelect( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Set$fromList( + _List_fromArray( + [0, 1])) + }))), + _Utils_Tuple2( + 'Nothing selected', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$multiSelect( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Set$empty + }))), + _Utils_Tuple2( + 'Invalid selection', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$multiSelect( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Set$singleton(-1) + }))), + _Utils_Tuple2( + 'Disabled selection', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$multiSelect( + { + onSelect: $elm$core$Basics$always($elm$core$Maybe$Nothing), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Set$singleton(0) + }))), + _Utils_Tuple2( + 'Empty Options', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$multiSelect( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_Nil), + selected: $elm$core$Set$empty + }))) + ]); + }); +var $author$project$View$Test$select = F2( + function (idle, style) { + return _List_fromArray( + [ + _Utils_Tuple2( + 'First selected', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$select( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Maybe$Just(0) + }))), + _Utils_Tuple2( + 'Nothing selected', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$select( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Maybe$Nothing + }))), + _Utils_Tuple2( + 'Invalid selection', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$select( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Maybe$Just(-1) + }))), + _Utils_Tuple2( + 'Disabled selection', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$select( + { + onSelect: $elm$core$Basics$always($elm$core$Maybe$Nothing), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: $elm$core$Maybe$Just(0) + }))), + _Utils_Tuple2( + 'Empty Options', + A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$select( + { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_Nil), + selected: $elm$core$Maybe$Nothing + }))) + ]); + }); +var $author$project$Internal$SortTable$Column = function (a) { + return {$: 'Column', a: a}; +}; +var $author$project$Internal$SortTable$FloatColumn = function (a) { return {$: 'FloatColumn', a: a}; }; -var $author$project$Widget$SortTable$floatColumn = function (_v0) { +var $author$project$Internal$SortTable$floatColumn = function (_v0) { var title = _v0.title; var value = _v0.value; var toString = _v0.toString; - return { - content: $author$project$Widget$SortTable$FloatColumn( - {toString: toString, value: value}), - title: title - }; + var width = _v0.width; + return $author$project$Internal$SortTable$Column( + { + content: $author$project$Internal$SortTable$FloatColumn( + {toString: toString, value: value}), + title: title, + width: width + }); }; -var $author$project$Widget$SortTable$IntColumn = function (a) { +var $author$project$Widget$floatColumn = $author$project$Internal$SortTable$floatColumn; +var $author$project$Internal$SortTable$IntColumn = function (a) { return {$: 'IntColumn', a: a}; }; -var $author$project$Widget$SortTable$intColumn = function (_v0) { +var $author$project$Internal$SortTable$intColumn = function (_v0) { var title = _v0.title; var value = _v0.value; var toString = _v0.toString; - return { - content: $author$project$Widget$SortTable$IntColumn( - {toString: toString, value: value}), - title: title - }; -}; -var $author$project$Widget$SortTable$StringColumn = function (a) { - return {$: 'StringColumn', a: a}; -}; -var $author$project$Widget$SortTable$stringColumn = function (_v0) { - var title = _v0.title; - var value = _v0.value; - var toString = _v0.toString; - return { - content: $author$project$Widget$SortTable$StringColumn( - {toString: toString, value: value}), - title: title - }; + var width = _v0.width; + return $author$project$Internal$SortTable$Column( + { + content: $author$project$Internal$SortTable$IntColumn( + {toString: toString, value: value}), + title: title, + width: width + }); }; +var $author$project$Widget$intColumn = $author$project$Internal$SortTable$intColumn; var $mdgriffith$elm_ui$Element$InternalColumn = function (a) { return {$: 'InternalColumn', a: a}; }; @@ -16284,926 +18998,1641 @@ var $mdgriffith$elm_ui$Element$table = F2( data: config.data }); }); -var $elm$core$List$sortBy = _List_sortBy; -var $author$project$Widget$SortTable$view = function (_v0) { - var content = _v0.content; - var columns = _v0.columns; - var model = _v0.model; - var findTitle = function (list) { - findTitle: - while (true) { - if (!list.b) { - return $elm$core$Maybe$Nothing; - } else { - var head = list.a; - var tail = list.b; - if (_Utils_eq(head.title, model.title)) { - return $elm$core$Maybe$Just(head.content); +var $author$project$Internal$SortTable$sortTable = F2( + function (style, model) { + var findTitle = function (list) { + findTitle: + while (true) { + if (!list.b) { + return $elm$core$Maybe$Nothing; } else { - var $temp$list = tail; - list = $temp$list; - continue findTitle; + var head = list.a.a; + var tail = list.b; + if (_Utils_eq(head.title, model.sortBy)) { + return $elm$core$Maybe$Just(head.content); + } else { + var $temp$list = tail; + list = $temp$list; + continue findTitle; + } } } - } - }; - return { - columns: A2( - $elm$core$List$map, - function (column) { - return { - header: column.title, - view: function () { - var _v2 = column.content; - switch (_v2.$) { - case 'IntColumn': - var value = _v2.a.value; - var toString = _v2.a.toString; - return A2($elm$core$Basics$composeR, value, toString); - case 'FloatColumn': - var value = _v2.a.value; - var toString = _v2.a.toString; - return A2($elm$core$Basics$composeR, value, toString); - default: - var value = _v2.a.value; - var toString = _v2.a.toString; - return A2($elm$core$Basics$composeR, value, toString); - } - }() - }; - }, - columns), - data: (model.asc ? $elm$core$Basics$identity : $elm$core$List$reverse)( - A3( - $elm$core$Basics$apR, - A2( - $elm$core$Maybe$map, - function (c) { - switch (c.$) { - case 'StringColumn': - var value = c.a.value; - return $elm$core$List$sortBy(value); - case 'IntColumn': - var value = c.a.value; - return $elm$core$List$sortBy(value); - default: - var value = c.a.value; - return $elm$core$List$sortBy(value); - } - }, - findTitle(columns)), - $elm$core$Maybe$withDefault($elm$core$Basics$identity), - content)) - }; -}; -var $author$project$Reusable$sortTable = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Sort Table')), - A2( - $mdgriffith$elm_ui$Element$table, - $Orasund$elm_ui_framework$Framework$Grid$simple, - function (_v0) { - var data = _v0.data; - var columns = _v0.columns; - return { - columns: A2( - $elm$core$List$map, - function (config) { - return { - header: A2( - $mdgriffith$elm_ui$Element$Input$button, - _List_fromArray( - [$mdgriffith$elm_ui$Element$Font$bold]), - { - label: _Utils_eq(config.header, model.title) ? A2( - $mdgriffith$elm_ui$Element$row, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _List_fromArray( - [$mdgriffith$elm_ui$Element$Font$bold])), - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$text(config.header), - $mdgriffith$elm_ui$Element$html( - model.asc ? $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronUp( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(16) - ])) : $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronDown( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(16) - ]))) - ])) : $mdgriffith$elm_ui$Element$text(config.header), - onPress: $elm$core$Maybe$Just( - $author$project$Reusable$SortBy( - { - asc: _Utils_eq(config.header, model.title) ? (!model.asc) : true, - title: config.header - })) - }), - view: A2($elm$core$Basics$composeR, config.view, $mdgriffith$elm_ui$Element$text), - width: $mdgriffith$elm_ui$Element$fill - }; - }, - columns), - data: data - }; - }( - $author$project$Widget$SortTable$view( - { - columns: _List_fromArray( - [ - $author$project$Widget$SortTable$intColumn( - { - title: 'Id', - toString: function (_int) { - return '#' + $elm$core$String$fromInt(_int); - }, - value: function ($) { - return $.id; + }; + return A2( + $mdgriffith$elm_ui$Element$table, + style.containerTable, + { + columns: A2( + $elm$core$List$map, + function (_v1) { + var column = _v1.a; + return { + header: A2( + $author$project$Internal$Button$button, + style.headerButton, + { + icon: _Utils_eq(column.title, model.sortBy) ? (model.asc ? style.ascIcon : style.descIcon) : style.defaultIcon, + onPress: function () { + var _v2 = column.content; + if (_v2.$ === 'UnsortableColumn') { + return $elm$core$Maybe$Nothing; + } else { + return $elm$core$Maybe$Just( + model.onChange(column.title)); } - }), - $author$project$Widget$SortTable$stringColumn( - { - title: 'Name', - toString: $elm$core$Basics$identity, - value: function ($) { - return $.name; - } - }), - $author$project$Widget$SortTable$floatColumn( - { - title: 'rating', - toString: $elm$core$String$fromFloat, - value: function ($) { - return $.rating; - } - }) - ]), - content: _List_fromArray( - [ - {id: 1, name: 'Antonio', rating: 2.456}, - {id: 2, name: 'Ana', rating: 1.34}, - {id: 3, name: 'Alfred', rating: 4.22}, - {id: 4, name: 'Thomas', rating: 3} - ]), - model: model - }))) - ])); -}; -var $author$project$Reusable$view = function (_v0) { - var addSnackbar = _v0.addSnackbar; - var msgMapper = _v0.msgMapper; - var model = _v0.model; - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$section, - _List_fromArray( - [$mdgriffith$elm_ui$Element$centerX])), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h2, - $mdgriffith$elm_ui$Element$text('Reusable Views')), - A2( - $mdgriffith$elm_ui$Element$paragraph, - _List_Nil, - $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$text('Reusable views have an internal state but no update function. You will need to do some wiring, but nothing complicated.'))), - A2( - $mdgriffith$elm_ui$Element$wrappedRow, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) - ])), - _List_fromArray( - [ - $author$project$Reusable$snackbar(addSnackbar), - A2( - $mdgriffith$elm_ui$Element$map, - msgMapper, - $author$project$Reusable$sortTable(model)) - ])) - ])); -}; -var $author$project$Stateless$SetCarousel = function (a) { - return {$: 'SetCarousel', a: a}; -}; -var $elm$core$Array$bitMask = 4294967295 >>> (32 - $elm$core$Array$shiftStep); -var $elm$core$Elm$JsArray$unsafeGet = _JsArray_unsafeGet; -var $elm$core$Array$getHelp = F3( - function (shift, index, tree) { - getHelp: - while (true) { - var pos = $elm$core$Array$bitMask & (index >>> shift); - var _v0 = A2($elm$core$Elm$JsArray$unsafeGet, pos, tree); - if (_v0.$ === 'SubTree') { - var subTree = _v0.a; - var $temp$shift = shift - $elm$core$Array$shiftStep, - $temp$index = index, - $temp$tree = subTree; - shift = $temp$shift; - index = $temp$index; - tree = $temp$tree; - continue getHelp; - } else { - var values = _v0.a; - return A2($elm$core$Elm$JsArray$unsafeGet, $elm$core$Array$bitMask & index, values); - } - } - }); -var $elm$core$Array$tailIndex = function (len) { - return (len >>> 5) << 5; -}; -var $elm$core$Array$get = F2( - function (index, _v0) { - var len = _v0.a; - var startShift = _v0.b; - var tree = _v0.c; - var tail = _v0.d; - return ((index < 0) || (_Utils_cmp(index, len) > -1)) ? $elm$core$Maybe$Nothing : ((_Utils_cmp( - index, - $elm$core$Array$tailIndex(len)) > -1) ? $elm$core$Maybe$Just( - A2($elm$core$Elm$JsArray$unsafeGet, $elm$core$Array$bitMask & index, tail)) : $elm$core$Maybe$Just( - A3($elm$core$Array$getHelp, startShift, index, tree))); - }); -var $elm$core$Array$length = function (_v0) { - var len = _v0.a; - return len; -}; -var $author$project$Widget$carousel = function (_v0) { - var content = _v0.content; - var current = _v0.current; - var label = _v0.label; - var _v1 = content; - var head = _v1.a; - var tail = _v1.b; - return label( - (current <= 0) ? head : ((_Utils_cmp( - current, - $elm$core$Array$length(tail)) > 0) ? A2( - $elm$core$Maybe$withDefault, - head, - A2( - $elm$core$Array$get, - $elm$core$Array$length(tail) - 1, - tail)) : A2( - $elm$core$Maybe$withDefault, - head, - A2($elm$core$Array$get, current - 1, tail)))); -}; -var $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronLeft = function (attrs) { - return A2( - $elm$svg$Svg$svg, - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$viewBox('0 0 20 20'), - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$fill('currentColor'), - attrs)), - _List_fromArray( - [ - A2( - $elm$svg$Svg$path, - _List_fromArray( - [ - $elm$svg$Svg$Attributes$fillRule('evenodd'), - $elm$svg$Svg$Attributes$d('M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z'), - $elm$svg$Svg$Attributes$clipRule('evenodd') - ]), - _List_Nil) - ])); -}; -var $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronRight = function (attrs) { - return A2( - $elm$svg$Svg$svg, - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$viewBox('0 0 20 20'), - A2( - $elm$core$List$cons, - $elm$svg$Svg$Attributes$fill('currentColor'), - attrs)), - _List_fromArray( - [ - A2( - $elm$svg$Svg$path, - _List_fromArray( - [ - $elm$svg$Svg$Attributes$fillRule('evenodd'), - $elm$svg$Svg$Attributes$d('M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z'), - $elm$svg$Svg$Attributes$clipRule('evenodd') - ]), - _List_Nil) - ])); -}; -var $Orasund$elm_ui_framework$Framework$Color$cyan = A3($mdgriffith$elm_ui$Element$rgb255, 32, 156, 238); -var $elm$core$Array$fromListHelp = F3( - function (list, nodeList, nodeListSize) { - fromListHelp: - while (true) { - var _v0 = A2($elm$core$Elm$JsArray$initializeFromList, $elm$core$Array$branchFactor, list); - var jsArray = _v0.a; - var remainingItems = _v0.b; - if (_Utils_cmp( - $elm$core$Elm$JsArray$length(jsArray), - $elm$core$Array$branchFactor) < 0) { - return A2( - $elm$core$Array$builderToArray, - true, - {nodeList: nodeList, nodeListSize: nodeListSize, tail: jsArray}); - } else { - var $temp$list = remainingItems, - $temp$nodeList = A2( - $elm$core$List$cons, - $elm$core$Array$Leaf(jsArray), - nodeList), - $temp$nodeListSize = nodeListSize + 1; - list = $temp$list; - nodeList = $temp$nodeList; - nodeListSize = $temp$nodeListSize; - continue fromListHelp; - } - } - }); -var $elm$core$Array$fromList = function (list) { - if (!list.b) { - return $elm$core$Array$empty; - } else { - return A3($elm$core$Array$fromListHelp, list, _List_Nil, 0); - } -}; -var $Orasund$elm_ui_framework$Framework$Color$green = A3($mdgriffith$elm_ui$Element$rgb255, 35, 209, 96); -var $Orasund$elm_ui_framework$Framework$Color$yellow = A3($mdgriffith$elm_ui$Element$rgb255, 255, 221, 87); -var $author$project$Stateless$carousel = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Carousel')), - $author$project$Widget$carousel( - { - content: _Utils_Tuple2( - $Orasund$elm_ui_framework$Framework$Color$cyan, - $elm$core$Array$fromList( - _List_fromArray( - [$Orasund$elm_ui_framework$Framework$Color$yellow, $Orasund$elm_ui_framework$Framework$Color$green, $Orasund$elm_ui_framework$Framework$Color$red]))), - current: model.carousel, - label: function (c) { - return A2( - $mdgriffith$elm_ui$Element$row, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$centerX, - $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink) - ])), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$Input$button, - _List_fromArray( - [$mdgriffith$elm_ui$Element$centerY]), - { - label: $mdgriffith$elm_ui$Element$html( - $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronLeft( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(20) - ]))), - onPress: $elm$core$Maybe$Just( - $author$project$Stateless$SetCarousel(model.carousel - 1)) - }), - A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$simple, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Background$color(c), - $mdgriffith$elm_ui$Element$height( - $mdgriffith$elm_ui$Element$px(100)), - $mdgriffith$elm_ui$Element$width( - $mdgriffith$elm_ui$Element$px(100)) - ])), - $mdgriffith$elm_ui$Element$none), - A2( - $mdgriffith$elm_ui$Element$Input$button, - _List_fromArray( - [$mdgriffith$elm_ui$Element$centerY]), - { - label: $mdgriffith$elm_ui$Element$html( - $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronRight( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(20) - ]))), - onPress: $elm$core$Maybe$Just( - $author$project$Stateless$SetCarousel(model.carousel + 1)) - }) - ])); - } - }) - ])); -}; -var $author$project$Stateless$ToggleCollapsable = function (a) { - return {$: 'ToggleCollapsable', a: a}; -}; -var $author$project$Widget$collapsable = function (_v0) { - var onToggle = _v0.onToggle; - var isCollapsed = _v0.isCollapsed; - var label = _v0.label; - var content = _v0.content; - return A2( - $mdgriffith$elm_ui$Element$column, - _List_Nil, - _Utils_ap( - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$Input$button, - _List_Nil, - { - label: label, - onPress: $elm$core$Maybe$Just( - onToggle(!isCollapsed)) - }) - ]), - isCollapsed ? _List_Nil : _List_fromArray( - [content]))); -}; -var $Orasund$elm_ui_framework$Framework$Heading$h4 = $Orasund$elm_ui_framework$Framework$Heading$h(4); -var $author$project$Stateless$collapsable = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Collapsable')), - $author$project$Widget$collapsable( - { - content: $mdgriffith$elm_ui$Element$text('Hello World'), - isCollapsed: model.isCollapsed, - label: A2( - $mdgriffith$elm_ui$Element$row, - $Orasund$elm_ui_framework$Framework$Grid$compact, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$html( - model.isCollapsed ? $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronRight( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(20) - ])) : $jasonliang512$elm_heroicons$Heroicons$Solid$cheveronDown( - _List_fromArray( - [ - $elm$html$Html$Attributes$width(20) - ]))), + }(), + text: column.title + }), + view: A2( + $elm$core$Basics$composeR, + function () { + var _v3 = column.content; + switch (_v3.$) { + case 'IntColumn': + var value = _v3.a.value; + var toString = _v3.a.toString; + return A2($elm$core$Basics$composeR, value, toString); + case 'FloatColumn': + var value = _v3.a.value; + var toString = _v3.a.toString; + return A2($elm$core$Basics$composeR, value, toString); + case 'StringColumn': + var value = _v3.a.value; + var toString = _v3.a.toString; + return A2($elm$core$Basics$composeR, value, toString); + default: + var toString = _v3.a; + return toString; + } + }(), A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h4, - $mdgriffith$elm_ui$Element$text('Title')) - ])), - onToggle: $author$project$Stateless$ToggleCollapsable - }) - ])); -}; -var $author$project$Stateless$ChangedMultiSelected = function (a) { - return {$: 'ChangedMultiSelected', a: a}; -}; -var $author$project$Widget$multiSelect = function (_v0) { - var selected = _v0.selected; - var options = _v0.options; - var label = _v0.label; - var onChange = _v0.onChange; - var attributes = _v0.attributes; - return A2( - $elm$core$List$map, - function (a) { - return A2( - $mdgriffith$elm_ui$Element$Input$button, - attributes( - A2($elm$core$Set$member, a, selected)), - { - label: label(a), - onPress: $elm$core$Maybe$Just( - onChange(a)) - }); - }, - options); -}; -var $author$project$Stateless$multiSelect = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Multi Select')), - A2( - $mdgriffith$elm_ui$Element$row, - $Orasund$elm_ui_framework$Framework$Grid$compact, - A2( - $elm$core$List$indexedMap, - function (i) { - return $mdgriffith$elm_ui$Element$el( - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _Utils_ap( - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$padding(0) - ]), - (!i) ? $Orasund$elm_ui_framework$Framework$Group$left : ((i === 2) ? $Orasund$elm_ui_framework$Framework$Group$right : $Orasund$elm_ui_framework$Framework$Group$center)))); + $elm$core$Basics$composeR, + $mdgriffith$elm_ui$Element$text, + A2( + $elm$core$Basics$composeR, + $elm$core$List$singleton, + $mdgriffith$elm_ui$Element$paragraph(_List_Nil)))), + width: column.width + }; }, - $author$project$Widget$multiSelect( - { - attributes: function (selected) { - return _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _Utils_ap( - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$width(0), - $mdgriffith$elm_ui$Element$Border$rounded(0) - ]), - selected ? $Orasund$elm_ui_framework$Framework$Color$primary : _List_Nil)); + model.columns), + data: (model.asc ? $elm$core$Basics$identity : $elm$core$List$reverse)( + A3( + $elm$core$Basics$apR, + A2( + $elm$core$Maybe$andThen, + function (c) { + switch (c.$) { + case 'StringColumn': + var value = c.a.value; + return $elm$core$Maybe$Just( + $elm$core$List$sortBy(value)); + case 'IntColumn': + var value = c.a.value; + return $elm$core$Maybe$Just( + $elm$core$List$sortBy(value)); + case 'FloatColumn': + var value = c.a.value; + return $elm$core$Maybe$Just( + $elm$core$List$sortBy(value)); + default: + return $elm$core$Maybe$Nothing; + } }, - label: A2($elm$core$Basics$composeR, $elm$core$String$fromInt, $mdgriffith$elm_ui$Element$text), - onChange: $author$project$Stateless$ChangedMultiSelected, - options: _List_fromArray( - [1, 2, 42]), - selected: model.multiSelected - }))) - ])); -}; -var $author$project$Stateless$scrim = F2( - function (_v0, model) { - var showDialog = _v0.showDialog; - var changedSheet = _v0.changedSheet; - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Scrim')), - A2( - $mdgriffith$elm_ui$Element$Input$button, - $Orasund$elm_ui_framework$Framework$Button$simple, - { - label: $mdgriffith$elm_ui$Element$text('Show dialog'), - onPress: $elm$core$Maybe$Just(showDialog) - }), - A2( - $mdgriffith$elm_ui$Element$Input$button, - $Orasund$elm_ui_framework$Framework$Button$simple, - { - label: $mdgriffith$elm_ui$Element$text('show left sheet'), - onPress: $elm$core$Maybe$Just( - changedSheet( - $elm$core$Maybe$Just($author$project$Layout$Left))) - }), - A2( - $mdgriffith$elm_ui$Element$Input$button, - $Orasund$elm_ui_framework$Framework$Button$simple, - { - label: $mdgriffith$elm_ui$Element$text('show right sheet'), - onPress: $elm$core$Maybe$Just( - changedSheet( - $elm$core$Maybe$Just($author$project$Layout$Right))) - }) - ])); + findTitle(model.columns)), + $elm$core$Maybe$withDefault($elm$core$Basics$identity), + model.content)) + }); }); -var $author$project$Stateless$ChangedSelected = function (a) { - return {$: 'ChangedSelected', a: a}; +var $author$project$Widget$sortTable = $author$project$Internal$SortTable$sortTable; +var $author$project$Internal$SortTable$StringColumn = function (a) { + return {$: 'StringColumn', a: a}; }; -var $author$project$Widget$select = function (_v0) { - var selected = _v0.selected; - var options = _v0.options; - var label = _v0.label; - var onChange = _v0.onChange; - var attributes = _v0.attributes; - return A2( - $elm$core$List$map, - function (a) { - return A2( - $mdgriffith$elm_ui$Element$Input$button, - attributes( - _Utils_eq( - selected, - $elm$core$Maybe$Just(a))), - { - label: label(a), - onPress: $elm$core$Maybe$Just( - onChange(a)) - }); - }, - options); +var $author$project$Internal$SortTable$stringColumn = function (_v0) { + var title = _v0.title; + var value = _v0.value; + var toString = _v0.toString; + var width = _v0.width; + return $author$project$Internal$SortTable$Column( + { + content: $author$project$Internal$SortTable$StringColumn( + {toString: toString, value: value}), + title: title, + width: width + }); }; -var $author$project$Stateless$select = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( +var $author$project$Widget$stringColumn = $author$project$Internal$SortTable$stringColumn; +var $author$project$Internal$SortTable$UnsortableColumn = function (a) { + return {$: 'UnsortableColumn', a: a}; +}; +var $author$project$Internal$SortTable$unsortableColumn = function (_v0) { + var title = _v0.title; + var toString = _v0.toString; + var width = _v0.width; + return $author$project$Internal$SortTable$Column( + { + content: $author$project$Internal$SortTable$UnsortableColumn(toString), + title: title, + width: width + }); +}; +var $author$project$Widget$unsortableColumn = $author$project$Internal$SortTable$unsortableColumn; +var $author$project$View$Test$sortTable = F2( + function (idle, style) { + return _List_fromArray( [ + _Utils_Tuple2( + 'Int column', A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Select')), + $author$project$Widget$sortTable, + style.sortTable, + { + asc: true, + columns: _List_fromArray( + [ + $author$project$Widget$intColumn( + { + title: 'Id', + toString: function (_int) { + return '#' + $elm$core$String$fromInt(_int); + }, + value: function ($) { + return $.id; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$stringColumn( + { + title: 'Name', + toString: $elm$core$Basics$identity, + value: function ($) { + return $.name; + }, + width: $mdgriffith$elm_ui$Element$fill + }) + ]), + content: _List_fromArray( + [ + {hash: $elm$core$Maybe$Nothing, id: 1, name: 'Antonio', rating: 2.456}, + { + hash: $elm$core$Maybe$Just('45jf'), + id: 2, + name: 'Ana', + rating: 1.34 + } + ]), + onChange: $elm$core$Basics$always(idle), + sortBy: 'Id' + })), + _Utils_Tuple2( + 'Name column', A2( - $mdgriffith$elm_ui$Element$row, - $Orasund$elm_ui_framework$Framework$Grid$compact, + $author$project$Widget$sortTable, + style.sortTable, + { + asc: true, + columns: _List_fromArray( + [ + $author$project$Widget$stringColumn( + { + title: 'Name', + toString: $elm$core$Basics$identity, + value: function ($) { + return $.name; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$floatColumn( + { + title: 'Rating', + toString: $elm$core$String$fromFloat, + value: function ($) { + return $.rating; + }, + width: $mdgriffith$elm_ui$Element$fill + }) + ]), + content: _List_fromArray( + [ + {hash: $elm$core$Maybe$Nothing, id: 1, name: 'Antonio', rating: 2.456}, + { + hash: $elm$core$Maybe$Just('45jf'), + id: 2, + name: 'Ana', + rating: 1.34 + } + ]), + onChange: $elm$core$Basics$always(idle), + sortBy: 'Name' + })), + _Utils_Tuple2( + 'Float column', A2( - $elm$core$List$indexedMap, - function (i) { - return $mdgriffith$elm_ui$Element$el( - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _Utils_ap( - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$padding(0) - ]), - (!i) ? $Orasund$elm_ui_framework$Framework$Group$left : ((i === 2) ? $Orasund$elm_ui_framework$Framework$Group$right : $Orasund$elm_ui_framework$Framework$Group$center)))); - }, - $author$project$Widget$select( - { - attributes: function (selected) { - return _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _Utils_ap( - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$width(0), - $mdgriffith$elm_ui$Element$Border$rounded(0) - ]), - selected ? $Orasund$elm_ui_framework$Framework$Color$primary : _List_Nil)); - }, - label: A2($elm$core$Basics$composeR, $elm$core$String$fromInt, $mdgriffith$elm_ui$Element$text), - onChange: $author$project$Stateless$ChangedSelected, - options: _List_fromArray( - [1, 2, 42]), - selected: model.selected - }))) - ])); -}; -var $author$project$Stateless$ChangedTab = function (a) { - return {$: 'ChangedTab', a: a}; -}; -var $Orasund$elm_ui_framework$Framework$Group$bottom = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$roundEach( - {bottomLeft: 4, bottomRight: 4, topLeft: 0, topRight: 0}) - ]); -var $Orasund$elm_ui_framework$Framework$Card$small = $Orasund$elm_ui_framework$Framework$Card$withSize(240); -var $author$project$Widget$tab = F2( - function (atts, _v0) { - var selected = _v0.selected; - var options = _v0.options; - var onChange = _v0.onChange; - var label = _v0.label; + $author$project$Widget$sortTable, + style.sortTable, + { + asc: false, + columns: _List_fromArray( + [ + $author$project$Widget$floatColumn( + { + title: 'Rating', + toString: $elm$core$String$fromFloat, + value: function ($) { + return $.rating; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$unsortableColumn( + { + title: 'Hash', + toString: A2( + $elm$core$Basics$composeR, + function ($) { + return $.hash; + }, + $elm$core$Maybe$withDefault('None')), + width: $mdgriffith$elm_ui$Element$fill + }) + ]), + content: _List_fromArray( + [ + {hash: $elm$core$Maybe$Nothing, id: 1, name: 'Antonio', rating: 2.456}, + { + hash: $elm$core$Maybe$Just('45jf'), + id: 2, + name: 'Ana', + rating: 1.34 + } + ]), + onChange: $elm$core$Basics$always(idle), + sortBy: 'Rating' + })), + _Utils_Tuple2( + 'Unsortable column', + A2( + $author$project$Widget$sortTable, + style.sortTable, + { + asc: true, + columns: _List_fromArray( + [ + $author$project$Widget$floatColumn( + { + title: 'Rating', + toString: $elm$core$String$fromFloat, + value: function ($) { + return $.rating; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$unsortableColumn( + { + title: 'Hash', + toString: A2( + $elm$core$Basics$composeR, + function ($) { + return $.hash; + }, + $elm$core$Maybe$withDefault('None')), + width: $mdgriffith$elm_ui$Element$fill + }) + ]), + content: _List_fromArray( + [ + {hash: $elm$core$Maybe$Nothing, id: 1, name: 'Antonio', rating: 2.456}, + { + hash: $elm$core$Maybe$Just('45jf'), + id: 2, + name: 'Ana', + rating: 1.34 + } + ]), + onChange: $elm$core$Basics$always(idle), + sortBy: 'Hash' + })), + _Utils_Tuple2( + 'Empty Table', + A2( + $author$project$Widget$sortTable, + style.sortTable, + { + asc: true, + columns: _List_Nil, + content: _List_fromArray( + [ + {hash: $elm$core$Maybe$Nothing, id: 1, name: 'Antonio', rating: 2.456}, + { + hash: $elm$core$Maybe$Just('45jf'), + id: 2, + name: 'Ana', + rating: 1.34 + } + ]), + onChange: $elm$core$Basics$always(idle), + sortBy: '' + })) + ]); + }); +var $author$project$Internal$Tab$tab = F2( + function (style, _v0) { + var tabs = _v0.tabs; var content = _v0.content; - var attributes = _v0.attributes; return A2( $mdgriffith$elm_ui$Element$column, - _List_Nil, + style.containerColumn, _List_fromArray( [ A2( $mdgriffith$elm_ui$Element$row, - atts, - $author$project$Widget$select( - { - attributes: attributes, - label: label, - onChange: onChange, - options: options, - selected: $elm$core$Maybe$Just(selected) - })), - content(selected) + style.optionRow, + A2( + $elm$core$List$map, + $author$project$Internal$Select$selectButton(style.button), + $author$project$Internal$Select$select(tabs))), + A2( + $mdgriffith$elm_ui$Element$el, + style.content, + content(tabs.selected)) ])); }); -var $Orasund$elm_ui_framework$Framework$Group$top = _List_fromArray( - [ - $mdgriffith$elm_ui$Element$Border$roundEach( - {bottomLeft: 0, bottomRight: 0, topLeft: 4, topRight: 4}) - ]); -var $author$project$Stateless$tab = function (model) { - return A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$fill) - ]))), - _List_fromArray( +var $author$project$Widget$tab = $author$project$Internal$Tab$tab; +var $author$project$View$Test$tab = F2( + function (idle, style) { + return _List_fromArray( [ + _Utils_Tuple2( + 'Nothing selected', A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Tab')), - A2( - $author$project$Widget$tab, - $Orasund$elm_ui_framework$Framework$Grid$simple, - { - attributes: function (selected) { - return _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Group$top, - selected ? $Orasund$elm_ui_framework$Framework$Color$primary : _List_Nil)); - }, - content: function (selected) { - return A2( - $mdgriffith$elm_ui$Element$el, - _Utils_ap($Orasund$elm_ui_framework$Framework$Card$small, $Orasund$elm_ui_framework$Framework$Group$bottom), - $mdgriffith$elm_ui$Element$text( + $author$project$Widget$tab, + style.tab, + { + content: function (selected) { + return $mdgriffith$elm_ui$Element$text( function () { - switch (selected) { - case 1: - return 'This is Tab 1'; - case 2: - return 'This is the second tab'; - case 3: - return 'The thrid and last tab'; - default: - return 'Please select a tab'; + if (selected.$ === 'Nothing') { + return 'Please select a tab'; + } else { + return ''; } - }())); - }, - label: function (_int) { - return $mdgriffith$elm_ui$Element$text( - 'Tab ' + $elm$core$String$fromInt(_int)); - }, - onChange: $author$project$Stateless$ChangedTab, - options: _List_fromArray( - [1, 2, 3]), - selected: model.tab - }) - ])); -}; -var $author$project$Stateless$view = F2( - function (_v0, model) { - var msgMapper = _v0.msgMapper; - var showDialog = _v0.showDialog; - var changedSheet = _v0.changedSheet; + }()); + }, + tabs: { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 3])), + selected: $elm$core$Maybe$Nothing + } + })), + _Utils_Tuple2( + 'Tab selected', + A2( + $author$project$Widget$tab, + style.tab, + { + content: function (selected) { + return $mdgriffith$elm_ui$Element$text( + function () { + if ((selected.$ === 'Just') && (!selected.a)) { + return 'First Tab selected'; + } else { + return 'Please select a tab'; + } + }()); + }, + tabs: { + onSelect: A2( + $elm$core$Basics$composeR, + $elm$core$Basics$always(idle), + $elm$core$Maybe$Just), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 3])), + selected: $elm$core$Maybe$Just(0) + } + })) + ]); + }); +var $author$project$Icons$circle = A2( + $author$project$Icons$svgFeatherIcon, + 'circle', + _List_fromArray( + [ + A2( + $elm$svg$Svg$circle, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$cx('12'), + $elm$svg$Svg$Attributes$cy('12'), + $elm$svg$Svg$Attributes$r('10') + ]), + _List_Nil) + ])); +var $author$project$Internal$TextInput$textInput = F2( + function (style, _v0) { + var chips = _v0.chips; + var placeholder = _v0.placeholder; + var label = _v0.label; + var text = _v0.text; + var onChange = _v0.onChange; return A2( - $mdgriffith$elm_ui$Element$column, - $Orasund$elm_ui_framework$Framework$Grid$section, + $mdgriffith$elm_ui$Element$row, + style.containerRow, + _List_fromArray( + [ + $elm$core$List$isEmpty(chips) ? $mdgriffith$elm_ui$Element$none : A2( + $mdgriffith$elm_ui$Element$row, + style.chipsRow, + A2( + $elm$core$List$map, + A2( + $elm$core$Basics$composeR, + $author$project$Internal$Button$button(style.chipButton), + $mdgriffith$elm_ui$Element$el(_List_Nil)), + chips)), + A2( + $mdgriffith$elm_ui$Element$Input$text, + style.input, + { + label: $mdgriffith$elm_ui$Element$Input$labelHidden(label), + onChange: onChange, + placeholder: placeholder, + text: text + }) + ])); + }); +var $author$project$Widget$textInput = $author$project$Internal$TextInput$textInput; +var $author$project$View$Test$textInput = F2( + function (idle, style) { + return _List_fromArray( + [ + _Utils_Tuple2( + 'Nothing Selected', + A2( + $author$project$Widget$textInput, + style.textInput, + { + chips: _List_Nil, + label: 'Label', + onChange: $elm$core$Basics$always(idle), + placeholder: $elm$core$Maybe$Nothing, + text: '' + })), + _Utils_Tuple2( + 'Some chips', + A2( + $author$project$Widget$textInput, + style.textInput, + { + chips: _List_fromArray( + [ + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), + onPress: $elm$core$Maybe$Just(idle), + text: 'A' + }, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$circle)), + onPress: $elm$core$Maybe$Just(idle), + text: 'B' + } + ]), + label: 'Label', + onChange: $elm$core$Basics$always(idle), + placeholder: $elm$core$Maybe$Nothing, + text: '' + })) + ]); + }); +var $author$project$Data$Example$toTests = function (example) { + switch (example.$) { + case 'ButtonExample': + return $author$project$View$Test$button; + case 'SelectExample': + return $author$project$View$Test$select; + case 'MultiSelectExample': + return $author$project$View$Test$multiSelect; + case 'ExpansionPanelExample': + return $author$project$View$Test$expansionPanel; + case 'TabExample': + return $author$project$View$Test$tab; + case 'SortTableExample': + return $author$project$View$Test$sortTable; + case 'ModalExample': + return $author$project$View$Test$modal; + case 'DialogExample': + return $author$project$View$Test$dialog; + case 'TextInputExample': + return $author$project$View$Test$textInput; + default: + return $author$project$View$Test$list; + } +}; +var $author$project$Example$Button$ChangedButtonStatus = function (a) { + return {$: 'ChangedButtonStatus', a: a}; +}; +var $feathericons$elm_feather$FeatherIcons$Icon = function (a) { + return {$: 'Icon', a: a}; +}; +var $feathericons$elm_feather$FeatherIcons$defaultAttributes = function (name) { + return { + _class: $elm$core$Maybe$Just('feather feather-' + name), + size: 24, + sizeUnit: '', + strokeWidth: 2, + viewBox: '0 0 24 24' + }; +}; +var $feathericons$elm_feather$FeatherIcons$makeBuilder = F2( + function (name, src) { + return $feathericons$elm_feather$FeatherIcons$Icon( + { + attrs: $feathericons$elm_feather$FeatherIcons$defaultAttributes(name), + src: src + }); + }); +var $feathericons$elm_feather$FeatherIcons$repeat = A2( + $feathericons$elm_feather$FeatherIcons$makeBuilder, + 'repeat', + _List_fromArray( + [ + A2( + $elm$svg$Svg$polyline, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$points('17 1 21 5 17 9') + ]), + _List_Nil), + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M3 11V9a4 4 0 0 1 4-4h14') + ]), + _List_Nil), + A2( + $elm$svg$Svg$polyline, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$points('7 23 3 19 7 15') + ]), + _List_Nil), + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M21 13v2a4 4 0 0 1-4 4H3') + ]), + _List_Nil) + ])); +var $feathericons$elm_feather$FeatherIcons$slash = A2( + $feathericons$elm_feather$FeatherIcons$makeBuilder, + 'slash', + _List_fromArray( + [ + A2( + $elm$svg$Svg$circle, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$cx('12'), + $elm$svg$Svg$Attributes$cy('12'), + $elm$svg$Svg$Attributes$r('10') + ]), + _List_Nil), + A2( + $elm$svg$Svg$line, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$x1('4.93'), + $elm$svg$Svg$Attributes$y1('4.93'), + $elm$svg$Svg$Attributes$x2('19.07'), + $elm$svg$Svg$Attributes$y2('19.07') + ]), + _List_Nil) + ])); +var $elm$svg$Svg$map = $elm$virtual_dom$VirtualDom$map; +var $feathericons$elm_feather$FeatherIcons$toHtml = F2( + function (attributes, _v0) { + var src = _v0.a.src; + var attrs = _v0.a.attrs; + var strSize = $elm$core$String$fromFloat(attrs.size); + var baseAttributes = _List_fromArray( + [ + $elm$svg$Svg$Attributes$fill('none'), + $elm$svg$Svg$Attributes$height( + _Utils_ap(strSize, attrs.sizeUnit)), + $elm$svg$Svg$Attributes$width( + _Utils_ap(strSize, attrs.sizeUnit)), + $elm$svg$Svg$Attributes$stroke('currentColor'), + $elm$svg$Svg$Attributes$strokeLinecap('round'), + $elm$svg$Svg$Attributes$strokeLinejoin('round'), + $elm$svg$Svg$Attributes$strokeWidth( + $elm$core$String$fromFloat(attrs.strokeWidth)), + $elm$svg$Svg$Attributes$viewBox(attrs.viewBox) + ]); + var combinedAttributes = _Utils_ap( + function () { + var _v1 = attrs._class; + if (_v1.$ === 'Just') { + var c = _v1.a; + return A2( + $elm$core$List$cons, + $elm$svg$Svg$Attributes$class(c), + baseAttributes); + } else { + return baseAttributes; + } + }(), + attributes); + return A2( + $elm$svg$Svg$svg, + combinedAttributes, + A2( + $elm$core$List$map, + $elm$svg$Svg$map($elm$core$Basics$never), + src)); + }); +var $feathericons$elm_feather$FeatherIcons$withSize = F2( + function (size, _v0) { + var attrs = _v0.a.attrs; + var src = _v0.a.src; + return $feathericons$elm_feather$FeatherIcons$Icon( + { + attrs: _Utils_update( + attrs, + {size: size}), + src: src + }); + }); +var $author$project$Example$Button$view = F3( + function (msgMapper, style, _v0) { + var isButtonEnabled = _v0.a; + return A2( + $author$project$Widget$row, + style.row, _List_fromArray( [ A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h2, - $mdgriffith$elm_ui$Element$text('Stateless Views')), + $author$project$Widget$button, + style.primaryButton, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html( + A2( + $feathericons$elm_feather$FeatherIcons$toHtml, + _List_Nil, + A2($feathericons$elm_feather$FeatherIcons$withSize, 16, $feathericons$elm_feather$FeatherIcons$slash)))), + onPress: isButtonEnabled ? $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Button$ChangedButtonStatus(false))) : $elm$core$Maybe$Nothing, + text: 'disable me' + }), A2( - $mdgriffith$elm_ui$Element$paragraph, - _List_Nil, - $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$text('Stateless views are simple functions that view some content. No wiring required.'))), + $author$project$Widget$iconButton, + style.button, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html( + A2( + $feathericons$elm_feather$FeatherIcons$toHtml, + _List_Nil, + A2($feathericons$elm_feather$FeatherIcons$withSize, 16, $feathericons$elm_feather$FeatherIcons$repeat)))), + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Button$ChangedButtonStatus(true))), + text: 'reset' + }) + ])); + }); +var $author$project$Example$Dialog$OpenDialog = function (a) { + return {$: 'OpenDialog', a: a}; +}; +var $feathericons$elm_feather$FeatherIcons$eye = A2( + $feathericons$elm_feather$FeatherIcons$makeBuilder, + 'eye', + _List_fromArray( + [ + A2( + $elm$svg$Svg$path, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$d('M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z') + ]), + _List_Nil), + A2( + $elm$svg$Svg$circle, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$cx('12'), + $elm$svg$Svg$Attributes$cy('12'), + $elm$svg$Svg$Attributes$r('3') + ]), + _List_Nil) + ])); +var $author$project$Example$Dialog$view = F3( + function (msgMapper, style, _v0) { + var isOpen = _v0.a; + return A2( + $mdgriffith$elm_ui$Element$el, + _Utils_ap( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + A2($mdgriffith$elm_ui$Element$minimum, 200, $mdgriffith$elm_ui$Element$fill)), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$minimum, 400, $mdgriffith$elm_ui$Element$fill)) + ]), + isOpen ? A2( + $author$project$Widget$dialog, + style.dialog, + { + accept: $elm$core$Maybe$Just( + { + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Dialog$OpenDialog(false))), + text: 'Ok' + }), + dismiss: $elm$core$Maybe$Just( + { + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Dialog$OpenDialog(false))), + text: 'Dismiss' + }), + text: 'This is a dialog window', + title: $elm$core$Maybe$Just('Dialog') + }) : _List_Nil), + A2( + $author$project$Widget$button, + style.primaryButton, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html( + A2( + $feathericons$elm_feather$FeatherIcons$toHtml, + _List_Nil, + A2($feathericons$elm_feather$FeatherIcons$withSize, 16, $feathericons$elm_feather$FeatherIcons$eye)))), + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Dialog$OpenDialog(true))), + text: 'show Dialog' + })); + }); +var $author$project$Example$ExpansionPanel$ToggleCollapsable = function (a) { + return {$: 'ToggleCollapsable', a: a}; +}; +var $author$project$Example$ExpansionPanel$view = F3( + function (msgMapper, style, _v0) { + var isExpanded = _v0.a; + return A2( + $author$project$Widget$expansionPanel, + style.expansionPanel, + { + content: $mdgriffith$elm_ui$Element$text('Hello World'), + icon: $mdgriffith$elm_ui$Element$none, + isExpanded: isExpanded, + onToggle: A2($elm$core$Basics$composeR, $author$project$Example$ExpansionPanel$ToggleCollapsable, msgMapper), + text: 'Title' + }); + }); +var $author$project$Example$List$view = F3( + function (_v0, style, _v1) { + return A2( + $author$project$Widget$column, + style.cardColumn, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$text('A'), + $mdgriffith$elm_ui$Element$text('B'), + $mdgriffith$elm_ui$Element$text('C') + ])); + }); +var $author$project$Example$Modal$ToggleModal = function (a) { + return {$: 'ToggleModal', a: a}; +}; +var $author$project$Example$Modal$view = F3( + function (msgMapper, style, _v0) { + var isEnabled = _v0.a; + return A2( + $mdgriffith$elm_ui$Element$el, + _Utils_ap( + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + A2($mdgriffith$elm_ui$Element$minimum, 200, $mdgriffith$elm_ui$Element$fill)), + $mdgriffith$elm_ui$Element$width( + A2($mdgriffith$elm_ui$Element$minimum, 400, $mdgriffith$elm_ui$Element$fill)) + ]), + isEnabled ? $author$project$Widget$modal( + { + content: A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(100)), + $mdgriffith$elm_ui$Element$width( + $mdgriffith$elm_ui$Element$px(250)), + $mdgriffith$elm_ui$Element$centerX, + $mdgriffith$elm_ui$Element$centerY + ]), + A2( + $author$project$Widget$column, + style.cardColumn, + $elm$core$List$singleton( + A2( + $mdgriffith$elm_ui$Element$paragraph, + _List_Nil, + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text('Click on the area around this box to close it.')))))), + onDismiss: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Modal$ToggleModal(false))) + }) : _List_Nil), + A2( + $author$project$Widget$button, + style.primaryButton, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html( + A2( + $feathericons$elm_feather$FeatherIcons$toHtml, + _List_Nil, + A2($feathericons$elm_feather$FeatherIcons$withSize, 16, $feathericons$elm_feather$FeatherIcons$eye)))), + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$Modal$ToggleModal(true))), + text: 'show Modal' + })); + }); +var $author$project$Example$MultiSelect$ChangedSelected = function (a) { + return {$: 'ChangedSelected', a: a}; +}; +var $author$project$Example$MultiSelect$view = F3( + function (msgMapper, style, _v0) { + var selected = _v0.a; + return A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$multiSelect( + { + onSelect: A2( + $elm$core$Basics$composeR, + $author$project$Example$MultiSelect$ChangedSelected, + A2($elm$core$Basics$composeR, msgMapper, $elm$core$Maybe$Just)), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: selected + })); + }); +var $author$project$Example$Select$ChangedSelected = function (a) { + return {$: 'ChangedSelected', a: a}; +}; +var $author$project$Example$Select$view = F3( + function (msgMapper, style, _v0) { + var selected = _v0.a; + return A2( + $author$project$Widget$buttonRow, + {button: style.selectButton, list: style.buttonRow}, + $author$project$Widget$select( + { + onSelect: A2( + $elm$core$Basics$composeR, + $author$project$Example$Select$ChangedSelected, + A2($elm$core$Basics$composeR, msgMapper, $elm$core$Maybe$Just)), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 42])), + selected: selected + })); + }); +var $author$project$Example$SortTable$ChangedSorting = function (a) { + return {$: 'ChangedSorting', a: a}; +}; +var $author$project$Example$SortTable$view = F3( + function (msgMapper, style, model) { + return A2( + $author$project$Widget$sortTable, + style.sortTable, + { + asc: model.asc, + columns: _List_fromArray( + [ + $author$project$Widget$intColumn( + { + title: 'Id', + toString: function (_int) { + return '#' + $elm$core$String$fromInt(_int); + }, + value: function ($) { + return $.id; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$stringColumn( + { + title: 'Name', + toString: $elm$core$Basics$identity, + value: function ($) { + return $.name; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$floatColumn( + { + title: 'Rating', + toString: $elm$core$String$fromFloat, + value: function ($) { + return $.rating; + }, + width: $mdgriffith$elm_ui$Element$fill + }), + $author$project$Widget$unsortableColumn( + { + title: 'Hash', + toString: A2( + $elm$core$Basics$composeR, + function ($) { + return $.hash; + }, + $elm$core$Maybe$withDefault('None')), + width: $mdgriffith$elm_ui$Element$fill + }) + ]), + content: _List_fromArray( + [ + {hash: $elm$core$Maybe$Nothing, id: 1, name: 'Antonio', rating: 2.456}, + { + hash: $elm$core$Maybe$Just('45jf'), + id: 2, + name: 'Ana', + rating: 1.34 + }, + { + hash: $elm$core$Maybe$Just('6fs1'), + id: 3, + name: 'Alfred', + rating: 4.22 + }, + { + hash: $elm$core$Maybe$Just('k52f'), + id: 4, + name: 'Thomas', + rating: 3 + } + ]), + onChange: A2($elm$core$Basics$composeR, $author$project$Example$SortTable$ChangedSorting, msgMapper), + sortBy: model.title + }); + }); +var $author$project$Example$Tab$ChangedTab = function (a) { + return {$: 'ChangedTab', a: a}; +}; +var $author$project$Example$Tab$view = F3( + function (msgMapper, style, _v0) { + var selected = _v0.a; + return A2( + $author$project$Widget$tab, + style.tab, + { + content: function (s) { + return $mdgriffith$elm_ui$Element$text( + function () { + _v1$3: + while (true) { + if (s.$ === 'Just') { + switch (s.a) { + case 0: + return 'This is Tab 1'; + case 1: + return 'This is the second tab'; + case 2: + return 'The thrid and last tab'; + default: + break _v1$3; + } + } else { + break _v1$3; + } + } + return 'Please select a tab'; + }()); + }, + tabs: { + onSelect: A2( + $elm$core$Basics$composeR, + $author$project$Example$Tab$ChangedTab, + A2($elm$core$Basics$composeR, msgMapper, $elm$core$Maybe$Just)), + options: A2( + $elm$core$List$map, + function (_int) { + return { + icon: $mdgriffith$elm_ui$Element$none, + text: 'Tab ' + $elm$core$String$fromInt(_int) + }; + }, + _List_fromArray( + [1, 2, 3])), + selected: selected + } + }); + }); +var $author$project$Example$TextInput$SetTextInput = function (a) { + return {$: 'SetTextInput', a: a}; +}; +var $author$project$Example$TextInput$ToggleTextInputChip = function (a) { + return {$: 'ToggleTextInputChip', a: a}; +}; +var $elm$core$Dict$diff = F2( + function (t1, t2) { + return A3( + $elm$core$Dict$foldl, + F3( + function (k, v, t) { + return A2($elm$core$Dict$remove, k, t); + }), + t1, + t2); + }); +var $elm$core$Set$diff = F2( + function (_v0, _v1) { + var dict1 = _v0.a; + var dict2 = _v1.a; + return $elm$core$Set$Set_elm_builtin( + A2($elm$core$Dict$diff, dict1, dict2)); + }); +var $mdgriffith$elm_ui$Internal$Model$Padding = F5( + function (a, b, c, d, e) { + return {$: 'Padding', a: a, b: b, c: c, d: d, e: e}; + }); +var $mdgriffith$elm_ui$Internal$Model$Spaced = F3( + function (a, b, c) { + return {$: 'Spaced', a: a, b: b, c: c}; + }); +var $mdgriffith$elm_ui$Internal$Model$extractSpacingAndPadding = function (attrs) { + return A3( + $elm$core$List$foldr, + F2( + function (attr, _v0) { + var pad = _v0.a; + var spacing = _v0.b; + return _Utils_Tuple2( + function () { + if (pad.$ === 'Just') { + var x = pad.a; + return pad; + } else { + if ((attr.$ === 'StyleClass') && (attr.b.$ === 'PaddingStyle')) { + var _v3 = attr.b; + var name = _v3.a; + var t = _v3.b; + var r = _v3.c; + var b = _v3.d; + var l = _v3.e; + return $elm$core$Maybe$Just( + A5($mdgriffith$elm_ui$Internal$Model$Padding, name, t, r, b, l)); + } else { + return $elm$core$Maybe$Nothing; + } + } + }(), + function () { + if (spacing.$ === 'Just') { + var x = spacing.a; + return spacing; + } else { + if ((attr.$ === 'StyleClass') && (attr.b.$ === 'SpacingStyle')) { + var _v6 = attr.b; + var name = _v6.a; + var x = _v6.b; + var y = _v6.c; + return $elm$core$Maybe$Just( + A3($mdgriffith$elm_ui$Internal$Model$Spaced, name, x, y)); + } else { + return $elm$core$Maybe$Nothing; + } + } + }()); + }), + _Utils_Tuple2($elm$core$Maybe$Nothing, $elm$core$Maybe$Nothing), + attrs); +}; +var $mdgriffith$elm_ui$Element$wrappedRow = F2( + function (attrs, children) { + var _v0 = $mdgriffith$elm_ui$Internal$Model$extractSpacingAndPadding(attrs); + var padded = _v0.a; + var spaced = _v0.b; + if (spaced.$ === 'Nothing') { + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asRow, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + ($mdgriffith$elm_ui$Internal$Style$classes.contentCenterY + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.wrapped)))), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), + attrs))), + $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); + } else { + var _v2 = spaced.a; + var spaceName = _v2.a; + var x = _v2.b; + var y = _v2.c; + var newPadding = function () { + if (padded.$ === 'Just') { + var _v5 = padded.a; + var name = _v5.a; + var t = _v5.b; + var r = _v5.c; + var b = _v5.d; + var l = _v5.e; + return ((_Utils_cmp(r, (x / 2) | 0) > -1) && (_Utils_cmp(b, (y / 2) | 0) > -1)) ? $elm$core$Maybe$Just( + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: b - ((y / 2) | 0), left: l - ((x / 2) | 0), right: r - ((x / 2) | 0), top: t - ((y / 2) | 0)})) : $elm$core$Maybe$Nothing; + } else { + return $elm$core$Maybe$Nothing; + } + }(); + if (newPadding.$ === 'Just') { + var pad = newPadding.a; + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asRow, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + ($mdgriffith$elm_ui$Internal$Style$classes.contentCenterY + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.wrapped)))), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), + _Utils_ap( + attrs, + _List_fromArray( + [pad]))))), + $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)); + } else { + var halfY = -(y / 2); + var halfX = -(x / 2); + return A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asEl, + $mdgriffith$elm_ui$Internal$Model$div, + attrs, + $mdgriffith$elm_ui$Internal$Model$Unkeyed( + _List_fromArray( + [ + A4( + $mdgriffith$elm_ui$Internal$Model$element, + $mdgriffith$elm_ui$Internal$Model$asRow, + $mdgriffith$elm_ui$Internal$Model$div, + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$htmlClass($mdgriffith$elm_ui$Internal$Style$classes.contentLeft + (' ' + ($mdgriffith$elm_ui$Internal$Style$classes.contentCenterY + (' ' + $mdgriffith$elm_ui$Internal$Style$classes.wrapped)))), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$Attr( + A2( + $elm$html$Html$Attributes$style, + 'margin', + $elm$core$String$fromFloat(halfY) + ('px' + (' ' + ($elm$core$String$fromFloat(halfX) + 'px'))))), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$Attr( + A2( + $elm$html$Html$Attributes$style, + 'width', + 'calc(100% + ' + ($elm$core$String$fromInt(x) + 'px)'))), + A2( + $elm$core$List$cons, + $mdgriffith$elm_ui$Internal$Model$Attr( + A2( + $elm$html$Html$Attributes$style, + 'height', + 'calc(100% + ' + ($elm$core$String$fromInt(y) + 'px)'))), + A2( + $elm$core$List$cons, + A2( + $mdgriffith$elm_ui$Internal$Model$StyleClass, + $mdgriffith$elm_ui$Internal$Flag$spacing, + A3($mdgriffith$elm_ui$Internal$Model$SpacingStyle, spaceName, x, y)), + _List_Nil))))), + $mdgriffith$elm_ui$Internal$Model$Unkeyed(children)) + ]))); + } + } + }); +var $author$project$Example$TextInput$view = F3( + function (msgMapper, style, model) { + return A2( + $author$project$Widget$column, + style.column, + _List_fromArray( + [ + A2( + $author$project$Widget$textInput, + style.textInput, + { + chips: A2( + $elm$core$List$map, + function (string) { + return { + icon: $mdgriffith$elm_ui$Element$none, + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$TextInput$ToggleTextInputChip(string))), + text: string + }; + }, + $elm$core$Set$toList(model.chipTextInput)), + label: 'Chips', + onChange: A2($elm$core$Basics$composeR, $author$project$Example$TextInput$SetTextInput, msgMapper), + placeholder: $elm$core$Maybe$Nothing, + text: model.textInput + }), A2( $mdgriffith$elm_ui$Element$wrappedRow, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$spacing(10) + ]), + A2( + $elm$core$List$map, + function (string) { + return A2( + $author$project$Widget$button, + style.textInput.chipButton, + { + icon: $mdgriffith$elm_ui$Element$none, + onPress: $elm$core$Maybe$Just( + msgMapper( + $author$project$Example$TextInput$ToggleTextInputChip(string))), + text: string + }); + }, + $elm$core$Set$toList( + A2( + $elm$core$Set$diff, + $elm$core$Set$fromList( + _List_fromArray( + ['A', 'B', 'C'])), + model.chipTextInput)))) + ])); + }); +var $author$project$Data$Example$view = F3( + function (msgMapper, style, model) { + return { + button: A3( + $author$project$Example$Button$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$Button, msgMapper), + style, + function ($) { + return $.button; + }(model)), + dialog: A3( + $author$project$Example$Dialog$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$Dialog, msgMapper), + style, + function ($) { + return $.dialog; + }(model)), + expansionPanel: A3( + $author$project$Example$ExpansionPanel$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$ExpansionPanel, msgMapper), + style, + function ($) { + return $.expansionPanel; + }(model)), + list: A3( + $author$project$Example$List$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$List, msgMapper), + style, + function ($) { + return $.list; + }(model)), + modal: A3( + $author$project$Example$Modal$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$Modal, msgMapper), + style, + function ($) { + return $.modal; + }(model)), + multiSelect: A3( + $author$project$Example$MultiSelect$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$MultiSelect, msgMapper), + style, + function ($) { + return $.multiSelect; + }(model)), + select: A3( + $author$project$Example$Select$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$Select, msgMapper), + style, + function ($) { + return $.select; + }(model)), + sortTable: A3( + $author$project$Example$SortTable$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$SortTable, msgMapper), + style, + function ($) { + return $.sortTable; + }(model)), + tab: A3( + $author$project$Example$Tab$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$Tab, msgMapper), + style, + function ($) { + return $.tab; + }(model)), + textInput: A3( + $author$project$Example$TextInput$view, + A2($elm$core$Basics$composeR, $author$project$Data$Example$TextInput, msgMapper), + style, + function ($) { + return $.textInput; + }(model)) + }; + }); +var $author$project$Data$Example$toCardList = function (_v0) { + var idle = _v0.idle; + var msgMapper = _v0.msgMapper; + var style = _v0.style; + var model = _v0.model; + return A2( + $elm$core$List$map, + function (_v1) { + var title = _v1.title; + var example = _v1.example; + var test = _v1.test; + return _Utils_Tuple3( + title, + example( + A3($author$project$Data$Example$view, msgMapper, style, model)), + A2( + $mdgriffith$elm_ui$Element$column, _Utils_ap( $Orasund$elm_ui_framework$Framework$Grid$simple, _List_fromArray( [ - $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) - ])), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$map, - msgMapper, - $author$project$Stateless$select(model)), - A2( - $mdgriffith$elm_ui$Element$map, - msgMapper, - $author$project$Stateless$multiSelect(model)), - A2( - $mdgriffith$elm_ui$Element$map, - msgMapper, - $author$project$Stateless$collapsable(model)), - A2( - $author$project$Stateless$scrim, - {changedSheet: changedSheet, showDialog: showDialog}, - model), - A2( - $mdgriffith$elm_ui$Element$map, - msgMapper, - $author$project$Stateless$carousel(model)), - A2( - $mdgriffith$elm_ui$Element$map, - msgMapper, - $author$project$Stateless$tab(model)) - ])) - ])); - }); -var $elm$html$Html$Attributes$id = $elm$html$Html$Attributes$stringProperty('id'); -var $author$project$Widget$ScrollingNav$view = F2( - function (asElement, _v0) { - var labels = _v0.labels; - var arrangement = _v0.arrangement; - return A2( - $mdgriffith$elm_ui$Element$column, - $Orasund$elm_ui_framework$Framework$Grid$simple, - A2( - $elm$core$List$map, - function (header) { - return A2( - $mdgriffith$elm_ui$Element$el, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$htmlAttribute( - $elm$html$Html$Attributes$id( - labels(header))), $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$fill) - ]), - asElement(header)); - }, - arrangement)); - }); -var $author$project$Example$view = function (model) { + ])), + A2( + $elm$core$List$map, + function (_v2) { + var name = _v2.a; + var elem = _v2.b; + return A2( + $mdgriffith$elm_ui$Element$row, + $Orasund$elm_ui_framework$Framework$Grid$spacedEvenly, + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$wrappedRow, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink) + ]), + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text(name))), + A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$paddingEach( + {bottom: 0, left: 8, right: 0, top: 0}), + $mdgriffith$elm_ui$Element$width($mdgriffith$elm_ui$Element$shrink) + ]), + elem) + ])); + }, + A2(test, idle, style)))); + }, + A2( + $elm$core$List$map, + function (example) { + return { + example: $author$project$Data$Example$get(example), + test: $author$project$Data$Example$toTests(example), + title: $author$project$Data$Example$toString(example) + }; + }, + $author$project$Data$Example$asList)); +}; +var $author$project$Stateless$view = function (_v0) { + var theme = _v0.theme; + var msgMapper = _v0.msgMapper; + var model = _v0.model; + var style = $author$project$Data$Theme$toStyle(theme); + return { + description: 'Stateless views are simple functions that view some content. No wiring required.', + items: $author$project$Data$Example$toCardList( + { + idle: msgMapper($author$project$Stateless$Idle), + model: model.example, + msgMapper: A2($elm$core$Basics$composeR, $author$project$Stateless$ExampleSpecific, msgMapper), + style: style + }), + title: 'Stateless Views' + }; +}; +var $author$project$Main$viewLoaded = function (m) { + var style = $author$project$Data$Theme$toStyle(m.theme); + return A2( + $mdgriffith$elm_ui$Element$column, + $Orasund$elm_ui_framework$Framework$Grid$compact, + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$el, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height( + $mdgriffith$elm_ui$Element$px(42)) + ]), + $mdgriffith$elm_ui$Element$none), + A2( + $mdgriffith$elm_ui$Element$column, + _Utils_ap($Orasund$elm_ui_framework$Framework$container, style.layout.container), + A2( + $elm$core$List$map, + function (section) { + return function (_v1) { + var title = _v1.title; + var description = _v1.description; + var items = _v1.items; + return A2( + $mdgriffith$elm_ui$Element$column, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$section, + _List_fromArray( + [$mdgriffith$elm_ui$Element$centerX])), + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$el, + $Orasund$elm_ui_framework$Framework$Heading$h2, + $mdgriffith$elm_ui$Element$text(title)), + (m.search.current === '') ? A2( + $mdgriffith$elm_ui$Element$paragraph, + _List_Nil, + $elm$core$List$singleton( + $mdgriffith$elm_ui$Element$text(description))) : $mdgriffith$elm_ui$Element$none, + A2( + $mdgriffith$elm_ui$Element$wrappedRow, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink) + ])), + A2( + $elm$core$List$map, + function (_v3) { + var name = _v3.a; + var elem = _v3.b; + var more = _v3.c; + return A2( + $author$project$Widget$column, + style.cardColumn, + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$column, + $Orasund$elm_ui_framework$Framework$Grid$simple, + _List_fromArray( + [ + A2( + $mdgriffith$elm_ui$Element$el, + _Utils_ap( + $Orasund$elm_ui_framework$Framework$Heading$h3, + _List_fromArray( + [ + $mdgriffith$elm_ui$Element$height($mdgriffith$elm_ui$Element$shrink), + $mdgriffith$elm_ui$Element$htmlAttribute( + $elm$html$Html$Attributes$id(name)) + ])), + $mdgriffith$elm_ui$Element$text(name)), + elem + ])), + A2( + $author$project$Widget$expansionPanel, + style.expansionPanel, + { + content: more, + icon: $mdgriffith$elm_ui$Element$none, + isExpanded: A2( + $elm$core$Maybe$withDefault, + false, + A2( + $elm$core$Maybe$map, + function (example) { + return A2($turboMaCk$any_set$Set$Any$member, example, m.expanded); + }, + $author$project$Data$Example$fromString(name))), + onToggle: $elm$core$Basics$always( + A2( + $elm$core$Maybe$withDefault, + $author$project$Main$Idle, + A2( + $elm$core$Maybe$map, + $author$project$Main$ToggledExample, + $author$project$Data$Example$fromString(name)))), + text: 'States' + }) + ])); + }, + ((m.search.current !== '') ? $elm$core$List$filter( + function (_v2) { + var a = _v2.a; + return A2( + $elm$core$String$contains, + $elm$core$String$toLower(m.search.current), + $elm$core$String$toLower(a)); + }) : $elm$core$Basics$identity)(items))) + ])); + }( + function () { + if (section.$ === 'ReusableViews') { + return $author$project$Reusable$view( + {addSnackbar: $author$project$Main$AddSnackbar, theme: m.theme}); + } else { + return $author$project$Stateless$view( + {model: m.stateless, msgMapper: $author$project$Main$StatelessSpecific, theme: m.theme}); + } + }()); + }, + _List_fromArray( + [$author$project$Data$Section$StatelessViews, $author$project$Data$Section$ReusableViews]))) + ])); +}; +var $author$project$Main$view = function (model) { if (model.$ === 'Loading') { return A2($Orasund$elm_ui_framework$Framework$responsiveLayout, _List_Nil, $mdgriffith$elm_ui$Element$none); } else { var m = model.a; + var style = $author$project$Data$Theme$toStyle(m.theme); return A2( $elm$html$Html$map, - $author$project$Example$LoadedSpecific, - A2( - $author$project$Layout$view, - _List_Nil, + $author$project$Main$LoadedSpecific, + A3( + $author$project$Widget$Layout$view, + style.layout, { actions: _List_fromArray( [ @@ -17212,181 +20641,107 @@ var $author$project$Example$view = function (model) { $mdgriffith$elm_ui$Element$el, _List_Nil, $mdgriffith$elm_ui$Element$html($author$project$Icons$book)), - label: 'Docs', onPress: $elm$core$Maybe$Just( - $author$project$Example$Load('https://package.elm-lang.org/packages/Orasund/elm-ui-widgets/latest/')) + $author$project$Main$Load('https://package.elm-lang.org/packages/Orasund/elm-ui-widgets/latest/')), + text: 'Docs' }, { icon: A2( $mdgriffith$elm_ui$Element$el, _List_Nil, $mdgriffith$elm_ui$Element$html($author$project$Icons$github)), - label: 'Github', onPress: $elm$core$Maybe$Just( - $author$project$Example$Load('https://github.com/Orasund/elm-ui-widgets')) + $author$project$Main$Load('https://github.com/Orasund/elm-ui-widgets')), + text: 'Github' }, { icon: A2( $mdgriffith$elm_ui$Element$el, _List_Nil, - $mdgriffith$elm_ui$Element$html($author$project$Icons$circle)), - label: 'Placeholder', - onPress: $elm$core$Maybe$Nothing + $mdgriffith$elm_ui$Element$html($author$project$Icons$penTool)), + onPress: (!_Utils_eq(m.theme, $author$project$Data$Theme$Material)) ? $elm$core$Maybe$Just( + $author$project$Main$SetTheme($author$project$Data$Theme$Material)) : $elm$core$Maybe$Nothing, + text: 'Material Theme' }, { icon: A2( $mdgriffith$elm_ui$Element$el, _List_Nil, - $mdgriffith$elm_ui$Element$html($author$project$Icons$triangle)), - label: 'Placeholder', - onPress: $elm$core$Maybe$Nothing + $mdgriffith$elm_ui$Element$html($author$project$Icons$penTool)), + onPress: (!_Utils_eq(m.theme, $author$project$Data$Theme$DarkMaterial)) ? $elm$core$Maybe$Just( + $author$project$Main$SetTheme($author$project$Data$Theme$DarkMaterial)) : $elm$core$Maybe$Nothing, + text: 'Dark Material Theme' }, { icon: A2( $mdgriffith$elm_ui$Element$el, _List_Nil, - $mdgriffith$elm_ui$Element$html($author$project$Icons$square)), - label: 'Placeholder', - onPress: $elm$core$Maybe$Nothing + $mdgriffith$elm_ui$Element$html($author$project$Icons$penTool)), + onPress: (!_Utils_eq(m.theme, $author$project$Data$Theme$ElmUiFramework)) ? $elm$core$Maybe$Just( + $author$project$Main$SetTheme($author$project$Data$Theme$ElmUiFramework)) : $elm$core$Maybe$Nothing, + text: 'Elm-Ui-Framework Theme' + }, + { + icon: A2( + $mdgriffith$elm_ui$Element$el, + _List_Nil, + $mdgriffith$elm_ui$Element$html($author$project$Icons$penTool)), + onPress: (!_Utils_eq(m.theme, $author$project$Data$Theme$Template)) ? $elm$core$Maybe$Just( + $author$project$Main$SetTheme($author$project$Data$Theme$Template)) : $elm$core$Maybe$Nothing, + text: 'Template Theme' } ]), - content: A2( - $mdgriffith$elm_ui$Element$column, - $Orasund$elm_ui_framework$Framework$Grid$compact, - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - _List_fromArray( - [ - $mdgriffith$elm_ui$Element$height( - $mdgriffith$elm_ui$Element$px(42)) - ]), - $mdgriffith$elm_ui$Element$none), - A2( - $mdgriffith$elm_ui$Element$column, - $Orasund$elm_ui_framework$Framework$container, - _List_fromArray( - [ - A2( - $author$project$Widget$ScrollingNav$view, - function (section) { - switch (section.$) { - case 'ComponentViews': - return A2( - $mdgriffith$elm_ui$Element$map, - $author$project$Example$ComponentSpecific, - $author$project$Component$view(m.component)); - case 'ReusableViews': - return $author$project$Reusable$view( - {addSnackbar: $author$project$Example$AddSnackbar, model: m.reusable, msgMapper: $author$project$Example$ReusableSpecific}); - default: - return A2( - $author$project$Stateless$view, - { - changedSheet: $author$project$Example$ChangedSidebar, - msgMapper: $author$project$Example$StatelessSpecific, - showDialog: $author$project$Example$ToggleDialog(true) - }, - m.stateless); - } - }, - m.scrollingNav) - ])) - ])), - deviceClass: m.deviceClass, dialog: m.displayDialog ? $elm$core$Maybe$Just( - { - content: A2( - $mdgriffith$elm_ui$Element$column, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Grid$simple, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Card$large, - _List_fromArray( - [$mdgriffith$elm_ui$Element$centerX, $mdgriffith$elm_ui$Element$centerY]))), - _List_fromArray( - [ - A2( - $mdgriffith$elm_ui$Element$el, - $Orasund$elm_ui_framework$Framework$Heading$h3, - $mdgriffith$elm_ui$Element$text('Dialog')), - A2( - $mdgriffith$elm_ui$Element$paragraph, - _List_Nil, - $elm$core$List$singleton( - $mdgriffith$elm_ui$Element$text('This is a dialog window'))), - A2( - $mdgriffith$elm_ui$Element$Input$button, - _Utils_ap( - $Orasund$elm_ui_framework$Framework$Button$simple, - _List_fromArray( - [$mdgriffith$elm_ui$Element$alignRight])), - { - label: $mdgriffith$elm_ui$Element$text('Ok'), - onPress: $elm$core$Maybe$Just( - $author$project$Example$ToggleDialog(false)) - }) - ])), - onDismiss: $elm$core$Maybe$Just( - $author$project$Example$ToggleDialog(false)) - }) : $elm$core$Maybe$Nothing, + A2( + $author$project$Widget$dialog, + style.dialog, + { + accept: $elm$core$Maybe$Just( + { + onPress: $elm$core$Maybe$Just( + $author$project$Main$ToggleDialog(false)), + text: 'Ok' + }), + dismiss: $elm$core$Maybe$Just( + { + onPress: $elm$core$Maybe$Just( + $author$project$Main$ToggleDialog(false)), + text: 'Dismiss' + }), + text: 'This is a dialog window', + title: $elm$core$Maybe$Just('Dialog') + })) : $elm$core$Maybe$Nothing, layout: m.layout, - menu: { - items: A2( - $elm$core$List$map, - function (label) { - return { - icon: $mdgriffith$elm_ui$Element$none, - label: $author$project$Data$Section$toString(label), - onPress: $elm$core$Maybe$Just( - $author$project$Example$JumpTo(label)) - }; - }, - $author$project$Data$Section$asList), - selected: A2( - $elm$core$Maybe$withDefault, - 0, - $elm$core$List$head( + menu: A2( + $author$project$Widget$ScrollingNav$toSelect, + function (_int) { + return A2( + $elm$core$Maybe$map, + $author$project$Main$JumpTo, A2( - $elm$core$List$filterMap, - function (_v2) { - var i = _v2.a; - var s = _v2.b; - return _Utils_eq( - $elm$core$Maybe$Just(s), - A2($author$project$Widget$ScrollingNav$current, $author$project$Data$Section$fromString, m.scrollingNav)) ? $elm$core$Maybe$Just(i) : $elm$core$Maybe$Nothing; - }, - A2( - $elm$core$List$indexedMap, - F2( - function (i, s) { - return _Utils_Tuple2(i, s); - }), - $author$project$Data$Section$asList)))) - }, - onChangedSidebar: $author$project$Example$ChangedSidebar, - style: $author$project$Example$style, + $elm$core$Array$get, + _int, + $elm$core$Array$fromList(m.scrollingNav.arrangement))); + }, + m.scrollingNav), + onChangedSidebar: $author$project$Main$ChangedSidebar, + search: $elm$core$Maybe$Just( + {label: 'Search', onChange: $author$project$Main$ChangedSearch, text: m.search.raw}), title: A2( $mdgriffith$elm_ui$Element$el, $Orasund$elm_ui_framework$Framework$Heading$h1, - $mdgriffith$elm_ui$Element$text( - (_Utils_eq(m.deviceClass, $mdgriffith$elm_ui$Element$Phone) || _Utils_eq(m.deviceClass, $mdgriffith$elm_ui$Element$Tablet)) ? A2( - $elm$core$Maybe$withDefault, - 'Elm-Ui-Widgets', - A2( - $elm$core$Maybe$map, - $author$project$Data$Section$toString, - A2($author$project$Widget$ScrollingNav$current, $author$project$Data$Section$fromString, m.scrollingNav))) : 'Elm-Ui-Widgets')) - })); + $mdgriffith$elm_ui$Element$text('Elm-Ui-Widgets')), + window: m.window + }, + $author$project$Main$viewLoaded(m))); } }; -var $author$project$Example$main = $elm$browser$Browser$element( - {init: $author$project$Example$init, subscriptions: $author$project$Example$subscriptions, update: $author$project$Example$update, view: $author$project$Example$view}); -_Platform_export({'Example':{'init':$author$project$Example$main( +var $author$project$Main$main = $elm$browser$Browser$element( + {init: $author$project$Main$init, subscriptions: $author$project$Main$subscriptions, update: $author$project$Main$update, view: $author$project$Main$view}); +_Platform_export({'Main':{'init':$author$project$Main$main( $elm$json$Json$Decode$succeed(_Utils_Tuple0))(0)}});}(this)); - var app = Elm.Example.init({ node: document.getElementById("elm") }); + var app = Elm.Main.init({ node: document.getElementById("elm") }); } catch (e) { diff --git a/docs/select.png b/docs/select.png deleted file mode 100644 index b544c66..0000000 Binary files a/docs/select.png and /dev/null differ diff --git a/docs/unstable/index.html b/docs/unstable/index.html deleted file mode 100644 index 65102e7..0000000 --- a/docs/unstable/index.html +++ /dev/null @@ -1,20213 +0,0 @@ - - - - - - Main - - - - - -

-
-	
-
-
-
-
\ No newline at end of file
diff --git a/elm.json b/elm.json
index e347336..d259fd4 100644
--- a/elm.json
+++ b/elm.json
@@ -6,22 +6,26 @@
     "version": "1.0.0",
     "exposed-modules": [
         "Widget",
-        "Widget.FilterSelect",
-        "Widget.ValidatedInput",
+        "Widget.Style",
+        "Widget.Style.Material",
+        "Widget.Style.Template",
+        "Widget.Layout",
         "Widget.ScrollingNav",
-        "Widget.Snackbar",
-        "Widget.SortTable"
+        "Widget.Snackbar"
     ],
     "elm-version": "0.19.0 <= v < 0.20.0",
     "dependencies": {
         "Orasund/elm-ui-framework": "1.6.1 <= v < 2.0.0",
+        "avh4/elm-color": "1.0.0 <= v < 2.0.0",
         "elm/browser": "1.0.2 <= v < 2.0.0",
         "elm/core": "1.0.0 <= v < 2.0.0",
         "elm/html": "1.0.0 <= v < 2.0.0",
+        "elm/svg": "1.0.1 <= v < 2.0.0",
         "elm/time": "1.0.0 <= v < 2.0.0",
         "elm-community/intdict": "3.0.0 <= v < 4.0.0",
         "jasonliang512/elm-heroicons": "1.0.2 <= v < 2.0.0",
         "mdgriffith/elm-ui": "1.1.5 <= v < 2.0.0",
+        "noahzgordon/elm-color-extra": "1.0.2 <= v < 2.0.0",
         "turboMaCk/queue": "1.0.2 <= v < 2.0.0",
         "wernerdegroot/listzipper": "4.0.0 <= v < 5.0.0"
     },
diff --git a/example/elm.json b/example/elm.json
index e7ae95b..c04d182 100644
--- a/example/elm.json
+++ b/example/elm.json
@@ -8,21 +8,29 @@
     "dependencies": {
         "direct": {
             "Orasund/elm-ui-framework": "1.6.1",
+            "avh4/elm-color": "1.0.0",
             "elm/browser": "1.0.2",
             "elm/core": "1.0.5",
             "elm/html": "1.0.0",
             "elm/svg": "1.0.1",
             "elm/time": "1.0.0",
             "elm-community/intdict": "3.0.0",
+            "feathericons/elm-feather": "1.4.0",
             "jasonliang512/elm-heroicons": "1.0.2",
             "mdgriffith/elm-ui": "1.1.5",
+            "noahzgordon/elm-color-extra": "1.0.2",
+            "ryannhg/elm-spa": "4.1.0",
+            "turboMaCk/any-set": "1.4.0",
             "turboMaCk/queue": "1.0.2",
             "wernerdegroot/listzipper": "4.0.0"
         },
         "indirect": {
             "elm/json": "1.1.3",
+            "elm/regex": "1.0.0",
             "elm/url": "1.0.0",
-            "elm/virtual-dom": "1.0.2"
+            "elm/virtual-dom": "1.0.2",
+            "fredcy/elm-parseint": "2.0.1",
+            "turboMaCk/any-dict": "2.3.0"
         }
     },
     "test-dependencies": {
diff --git a/example/src/Component.elm b/example/src/Component.elm
deleted file mode 100644
index 3da1e98..0000000
--- a/example/src/Component.elm
+++ /dev/null
@@ -1,181 +0,0 @@
-module Component exposing (Model, Msg(..), init, update, view)
-
-import Browser
-import Element exposing (Color, Element)
-import Element.Background as Background
-import Element.Input as Input
-import Framework
-import Framework.Button as Button
-import Framework.Card as Card
-import Framework.Color as Color
-import Framework.Grid as Grid
-import Framework.Group as Group
-import Framework.Heading as Heading
-import Framework.Input as Input
-import Framework.Tag as Tag
-import Heroicons.Solid as Heroicons
-import Html exposing (Html)
-import Html.Attributes as Attributes
-import Set exposing (Set)
-import Time
-import Widget
-import Widget.FilterSelect as FilterSelect
-import Widget.ScrollingNav as ScrollingNav
-import Widget.Snackbar as Snackbar
-import Widget.ValidatedInput as ValidatedInput
-
-
-type alias Model =
-    { filterSelect : FilterSelect.Model
-    , validatedInput : ValidatedInput.Model () ( String, String )
-    }
-
-
-type Msg
-    = FilterSelectSpecific FilterSelect.Msg
-    | ValidatedInputSpecific ValidatedInput.Msg
-
-
-init : Model
-init =
-    { filterSelect =
-        [ "Apple"
-        , "Kiwi"
-        , "Strawberry"
-        , "Pineapple"
-        , "Mango"
-        , "Grapes"
-        , "Watermelon"
-        , "Orange"
-        , "Lemon"
-        , "Blueberry"
-        , "Grapefruit"
-        , "Coconut"
-        , "Cherry"
-        , "Banana"
-        ]
-            |> Set.fromList
-            |> FilterSelect.init
-    , validatedInput =
-        ValidatedInput.init
-            { value = ( "John", "Doe" )
-            , validator =
-                \string ->
-                    case string |> String.split " " of
-                        [ first, second ] ->
-                            Ok ( first, second )
-
-                        _ ->
-                            Err ()
-            , toString =
-                \( first, second ) -> first ++ " " ++ second
-            }
-    }
-
-
-update : Msg -> Model -> ( Model, Cmd Msg )
-update msg model =
-    case msg of
-        FilterSelectSpecific m ->
-            ( { model
-                | filterSelect = model.filterSelect |> FilterSelect.update m
-              }
-            , Cmd.none
-            )
-
-        ValidatedInputSpecific m ->
-            ( { model
-                | validatedInput = model.validatedInput |> ValidatedInput.update m
-              }
-            , Cmd.none
-            )
-
-
-filterSelect : FilterSelect.Model -> Element Msg
-filterSelect model =
-    Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill]) <|
-        [ Element.el Heading.h3 <| Element.text "Filter Select"
-        , case model.selected of
-            Just selected ->
-                Element.row Grid.compact
-                    [ Element.el (Tag.simple ++ Group.left) <| Element.text <| selected
-                    , Input.button (Tag.simple ++ Group.right ++ Color.danger)
-                        { onPress = Just <| FilterSelectSpecific <| FilterSelect.Selected Nothing
-                        , label = Element.html <| Heroicons.x [ Attributes.width 16 ]
-                        }
-                    ]
-
-            Nothing ->
-                Element.column Grid.simple
-                    [ FilterSelect.viewInput Input.simple
-                        model
-                        { msgMapper = FilterSelectSpecific
-                        , placeholder =
-                            Just <|
-                                Input.placeholder [] <|
-                                    Element.text <|
-                                        "Fruit"
-                        , label = "Fruit"
-                        }
-                    , model
-                        |> FilterSelect.viewOptions
-                        |> List.map
-                            (\string ->
-                                Input.button (Button.simple ++ Tag.simple)
-                                    { onPress = Just <| FilterSelectSpecific <| FilterSelect.Selected <| Just <| string
-                                    , label = Element.text string
-                                    }
-                            )
-                        |> Element.wrappedRow [ Element.spacing 10 ]
-                    ]
-        ]
-
-
-validatedInput : ValidatedInput.Model () ( String, String ) -> Element Msg
-validatedInput model =
-    Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill]) <|
-        [ Element.el Heading.h3 <| Element.text "Validated Input"
-        , ValidatedInput.view Input.simple
-            model
-            { label = "First Name, Sir Name"
-            , msgMapper = ValidatedInputSpecific
-            , placeholder = Nothing
-            , readOnly =
-                \maybeTuple ->
-                    Element.row Grid.compact
-                        [ maybeTuple
-                            |> (\( a, b ) -> a ++ " " ++ b)
-                            |> Element.text
-                            |> Element.el (Tag.simple ++ Group.left)
-                        , Heroicons.pencil [ Attributes.width 16 ]
-                            |> Element.html
-                            |> Element.el (Tag.simple ++ Group.right ++ Color.primary)
-                        ]
-            }
-        ]
-
-
-scrollingNavCard : Element msg
-scrollingNavCard =
-    [ Element.el Heading.h3 <| Element.text "Scrolling Nav"
-    , Element.text "Resize the screen and open the side-menu. Then start scrolling to see the scrolling navigation in action."
-        |> List.singleton
-        |> Element.paragraph []
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-view : Model -> Element Msg
-view model =
-    Element.column (Grid.section ++ [ Element.centerX ])
-        [ Element.el Heading.h2 <| Element.text "Components"
-        , "Components have a Model, an Update- and sometimes even a Subscription-function. It takes some time to set them up correctly."
-            |> Element.text
-            |> List.singleton
-            |> Element.paragraph []
-        , Element.wrappedRow (Grid.simple ++ [Element.height <| Element.shrink]) <|
-            [ filterSelect model.filterSelect
-            , validatedInput model.validatedInput
-            , scrollingNavCard
-            ]
-        ]
diff --git a/example/src/Data/Example.elm b/example/src/Data/Example.elm
new file mode 100644
index 0000000..9572ebb
--- /dev/null
+++ b/example/src/Data/Example.elm
@@ -0,0 +1,536 @@
+module Data.Example exposing (Example, Model, Msg, asList, fromString, init, subscriptions, toCardList, toString, update, view)
+
+import Data.Style exposing (Style)
+import Element exposing (Element)
+import Example.Button as Button
+import Example.Dialog as Dialog
+import Example.ExpansionPanel as ExpansionPanel
+import Example.List as List
+import Example.Modal as Modal
+import Example.MultiSelect as MultiSelect
+import Example.Select as Select
+import Example.SortTable as SortTable
+import Example.Tab as Tab
+import Example.TextInput as TextInput
+import Framework.Grid as Grid
+import View.Test as Test
+
+
+type Example
+    = ButtonExample
+    | SelectExample
+    | MultiSelectExample
+    | ExpansionPanelExample
+    | TabExample
+    | SortTableExample
+    | ModalExample
+    | DialogExample
+    | TextInputExample
+    | ListExample
+
+
+asList : List Example
+asList =
+    [ ButtonExample
+    , SelectExample
+    , MultiSelectExample
+    , ExpansionPanelExample
+    , TabExample
+    , SortTableExample
+    , ModalExample
+    , DialogExample
+    , TextInputExample
+    , ListExample
+    ]
+        |> List.sortBy toString
+
+
+toString : Example -> String
+toString example =
+    case example of
+        ButtonExample ->
+            "Button"
+
+        SelectExample ->
+            "Select"
+
+        MultiSelectExample ->
+            "Multi Select"
+
+        ExpansionPanelExample ->
+            "ExpansionPanel"
+
+        TabExample ->
+            "Tab"
+
+        SortTableExample ->
+            "SortTable"
+
+        ModalExample ->
+            "Modal"
+
+        DialogExample ->
+            "Dialog"
+
+        TextInputExample ->
+            "TextInput"
+
+        ListExample ->
+            "List"
+
+
+fromString : String -> Maybe Example
+fromString string =
+    case string of
+        "Button" ->
+            Just ButtonExample
+
+        "Select" ->
+            Just SelectExample
+
+        "Multi Select" ->
+            Just MultiSelectExample
+
+        "ExpansionPanel" ->
+            Just ExpansionPanelExample
+
+        "Tab" ->
+            Just TabExample
+
+        "SortTable" ->
+            Just SortTableExample
+
+        "Modal" ->
+            Just ModalExample
+
+        "Dialog" ->
+            Just DialogExample
+
+        "TextInput" ->
+            Just TextInputExample
+
+        "List" ->
+            Just ListExample
+
+        _ ->
+            Nothing
+
+
+get : Example -> ExampleView msg -> Element msg
+get example =
+    case example of
+        ButtonExample ->
+            .button
+
+        SelectExample ->
+            .select
+
+        MultiSelectExample ->
+            .multiSelect
+
+        ExpansionPanelExample ->
+            .expansionPanel
+
+        TabExample ->
+            .tab
+
+        SortTableExample ->
+            .sortTable
+
+        ModalExample ->
+            .modal
+
+        DialogExample ->
+            .dialog
+
+        TextInputExample ->
+            .textInput
+
+        ListExample ->
+            .list
+
+
+toTests : Example -> msg -> Style msg -> List ( String, Element msg )
+toTests example =
+    case example of
+        ButtonExample ->
+            Test.button
+
+        SelectExample ->
+            Test.select
+
+        MultiSelectExample ->
+            Test.multiSelect
+
+        ExpansionPanelExample ->
+            Test.expansionPanel
+
+        TabExample ->
+            Test.tab
+
+        SortTableExample ->
+            Test.sortTable
+
+        ModalExample ->
+            Test.modal
+
+        DialogExample ->
+            Test.dialog
+
+        TextInputExample ->
+            Test.textInput
+
+        ListExample ->
+            Test.list
+
+
+type Msg
+    = Button Button.Msg
+    | Select Select.Msg
+    | MultiSelect MultiSelect.Msg
+    | ExpansionPanel ExpansionPanel.Msg
+    | Tab Tab.Msg
+    | SortTable SortTable.Msg
+    | Modal Modal.Msg
+    | Dialog Dialog.Msg
+    | TextInput TextInput.Msg
+    | List List.Msg
+
+
+type alias Model =
+    { button : Button.Model
+    , select : Select.Model
+    , multiSelect : MultiSelect.Model
+    , expansionPanel : ExpansionPanel.Model
+    , tab : Tab.Model
+    , sortTable : SortTable.Model
+    , modal : Modal.Model
+    , dialog : Dialog.Model
+    , textInput : TextInput.Model
+    , list : List.Model
+    }
+
+
+type alias UpgradeRecord model msg =
+    { from : Model -> model
+    , to : Model -> model -> Model
+    , msgMapper : msg -> Msg
+    , updateFun : msg -> model -> ( model, Cmd msg )
+    , subscriptionsFun : model -> Sub msg
+    }
+
+
+type alias UpgradeCollection =
+    { button : UpgradeRecord Button.Model Button.Msg
+    , select : UpgradeRecord Select.Model Select.Msg
+    , multiSelect : UpgradeRecord MultiSelect.Model MultiSelect.Msg
+    , expansionPanel : UpgradeRecord ExpansionPanel.Model ExpansionPanel.Msg
+    , tab : UpgradeRecord Tab.Model Tab.Msg
+    , sortTable : UpgradeRecord SortTable.Model SortTable.Msg
+    , modal : UpgradeRecord Modal.Model Modal.Msg
+    , dialog : UpgradeRecord Dialog.Model Dialog.Msg
+    , textInput : UpgradeRecord TextInput.Model TextInput.Msg
+    , list : UpgradeRecord List.Model List.Msg
+    }
+
+
+type alias ExampleView msg =
+    { button : Element msg
+    , select : Element msg
+    , multiSelect : Element msg
+    , expansionPanel : Element msg
+    , tab : Element msg
+    , sortTable : Element msg
+    , modal : Element msg
+    , dialog : Element msg
+    , textInput : Element msg
+    , list : Element msg
+    }
+
+
+init : ( Model, Cmd Msg )
+init =
+    let
+        ( buttonModel, buttonMsg ) =
+            Button.init
+
+        ( selectModel, selectMsg ) =
+            Select.init
+
+        ( multiSelectModel, multiSelectMsg ) =
+            MultiSelect.init
+
+        ( expansionPanelModel, expansionPanelMsg ) =
+            ExpansionPanel.init
+
+        ( tabModel, tabMsg ) =
+            Tab.init
+
+        ( sortTableModel, sortTableMsg ) =
+            SortTable.init
+
+        ( modalModel, modalMsg ) =
+            Modal.init
+
+        ( dialogModel, dialogMsg ) =
+            Dialog.init
+
+        ( textInputModel, textInputMsg ) =
+            TextInput.init
+
+        ( listModel, listMsg ) =
+            List.init
+    in
+    ( { button = buttonModel
+      , select = selectModel
+      , multiSelect = multiSelectModel
+      , expansionPanel = expansionPanelModel
+      , tab = tabModel
+      , sortTable = sortTableModel
+      , modal = modalModel
+      , dialog = dialogModel
+      , textInput = textInputModel
+      , list = listModel
+      }
+    , [ Cmd.map Button buttonMsg
+      , Cmd.map Select selectMsg
+      , Cmd.map MultiSelect multiSelectMsg
+      , Cmd.map ExpansionPanel expansionPanelMsg
+      , Cmd.map Tab tabMsg
+      , Cmd.map SortTable sortTableMsg
+      , Cmd.map Modal modalMsg
+      , Cmd.map Dialog dialogMsg
+      , Cmd.map TextInput textInputMsg
+      , Cmd.map List listMsg
+      ]
+        |> Cmd.batch
+    )
+
+
+upgradeRecord : UpgradeCollection
+upgradeRecord =
+    { button =
+        { from = .button
+        , to = \model a -> { model | button = a }
+        , msgMapper = Button
+        , updateFun = Button.update
+        , subscriptionsFun = Button.subscriptions
+        }
+    , select =
+        { from = .select
+        , to = \model a -> { model | select = a }
+        , msgMapper = Select
+        , updateFun = Select.update
+        , subscriptionsFun = Select.subscriptions
+        }
+    , multiSelect =
+        { from = .multiSelect
+        , to = \model a -> { model | multiSelect = a }
+        , msgMapper = MultiSelect
+        , updateFun = MultiSelect.update
+        , subscriptionsFun = MultiSelect.subscriptions
+        }
+    , expansionPanel =
+        { from = .expansionPanel
+        , to = \model a -> { model | expansionPanel = a }
+        , msgMapper = ExpansionPanel
+        , updateFun = ExpansionPanel.update
+        , subscriptionsFun = ExpansionPanel.subscriptions
+        }
+    , tab =
+        { from = .tab
+        , to = \model a -> { model | tab = a }
+        , msgMapper = Tab
+        , updateFun = Tab.update
+        , subscriptionsFun = Tab.subscriptions
+        }
+    , sortTable =
+        { from = .sortTable
+        , to = \model a -> { model | sortTable = a }
+        , msgMapper = SortTable
+        , updateFun = SortTable.update
+        , subscriptionsFun = SortTable.subscriptions
+        }
+    , modal =
+        { from = .modal
+        , to = \model a -> { model | modal = a }
+        , msgMapper = Modal
+        , updateFun = Modal.update
+        , subscriptionsFun = Modal.subscriptions
+        }
+    , dialog =
+        { from = .dialog
+        , to = \model a -> { model | dialog = a }
+        , msgMapper = Dialog
+        , updateFun = Dialog.update
+        , subscriptionsFun = Dialog.subscriptions
+        }
+    , textInput =
+        { from = .textInput
+        , to = \model a -> { model | textInput = a }
+        , msgMapper = TextInput
+        , updateFun = TextInput.update
+        , subscriptionsFun = TextInput.subscriptions
+        }
+    , list =
+        { from = .list
+        , to = \model a -> { model | list = a }
+        , msgMapper = List
+        , updateFun = List.update
+        , subscriptionsFun = List.subscriptions
+        }
+    }
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    (case msg of
+        Button m ->
+            updateField .button m
+
+        Select m ->
+            updateField .select m
+
+        MultiSelect m ->
+            updateField .multiSelect m
+
+        ExpansionPanel m ->
+            updateField .expansionPanel m
+
+        Tab m ->
+            updateField .tab m
+
+        SortTable m ->
+            updateField .sortTable m
+
+        Modal m ->
+            updateField .modal m
+
+        Dialog m ->
+            updateField .dialog m
+
+        TextInput m ->
+            updateField .textInput m
+
+        List m ->
+            updateField .list m
+    )
+        model
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+    let
+        subFun { from, msgMapper, subscriptionsFun } =
+            subscriptionsFun (from model) |> Sub.map msgMapper
+    in
+    [ upgradeRecord.button |> subFun
+    , upgradeRecord.select |> subFun
+    , upgradeRecord.multiSelect |> subFun
+    , upgradeRecord.expansionPanel |> subFun
+    , upgradeRecord.tab |> subFun
+    , upgradeRecord.sortTable |> subFun
+    , upgradeRecord.modal |> subFun
+    , upgradeRecord.dialog |> subFun
+    , upgradeRecord.textInput |> subFun
+    , upgradeRecord.list |> subFun
+    ]
+        |> Sub.batch
+
+
+view :
+    (Msg -> msg)
+    -> Style msg
+    -> Model
+    -> ExampleView msg
+view msgMapper style model =
+    { button =
+        Button.view (Button >> msgMapper) style (.button model)
+    , select =
+        Select.view (Select >> msgMapper) style (.select model)
+    , multiSelect =
+        MultiSelect.view (MultiSelect >> msgMapper) style (.multiSelect model)
+    , expansionPanel =
+        ExpansionPanel.view (ExpansionPanel >> msgMapper) style (.expansionPanel model)
+    , tab =
+        Tab.view (Tab >> msgMapper) style (.tab model)
+    , sortTable =
+        SortTable.view (SortTable >> msgMapper) style (.sortTable model)
+    , modal =
+        Modal.view (Modal >> msgMapper) style (.modal model)
+    , dialog =
+        Dialog.view (Dialog >> msgMapper) style (.dialog model)
+    , textInput =
+        TextInput.view (TextInput >> msgMapper) style (.textInput model)
+    , list =
+        List.view (List >> msgMapper) style (.list model)
+    }
+
+
+toCardList :
+    { idle : msg
+    , msgMapper : Msg -> msg
+    , style : Style msg
+    , model : Model
+    }
+    -> List ( String, Element msg, Element msg )
+toCardList { idle, msgMapper, style, model } =
+    asList
+        |> List.map
+            (\example ->
+                { title = example |> toString
+                , example = example |> get
+                , test = example |> toTests
+                }
+            )
+        |> List.map
+            (\{ title, example, test } ->
+                ( title
+                , model
+                    |> view msgMapper style
+                    |> example
+                , test idle style
+                    |> List.map
+                        (\( name, elem ) ->
+                            Element.row Grid.spacedEvenly
+                                [ name
+                                    |> Element.text
+                                    |> List.singleton
+                                    |> Element.wrappedRow [ Element.width <| Element.shrink ]
+                                , elem
+                                    |> Element.el
+                                        [ Element.paddingEach
+                                            { top = 0
+                                            , right = 0
+                                            , bottom = 0
+                                            , left = 8
+                                            }
+                                        , Element.width <| Element.shrink
+                                        ]
+                                ]
+                        )
+                    |> Element.column
+                        (Grid.simple
+                            ++ [ Element.width <| Element.fill ]
+                        )
+                )
+            )
+
+
+
+{-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------}
+
+
+updateField :
+    (UpgradeCollection -> UpgradeRecord model msg)
+    -> msg
+    -> Model
+    -> ( Model, Cmd Msg )
+updateField getter msg model =
+    let
+        { from, to, msgMapper, updateFun } =
+            getter upgradeRecord
+    in
+    updateFun msg (from model)
+        |> Tuple.mapBoth (to model) (Cmd.map msgMapper)
diff --git a/example/src/Data/Section.elm b/example/src/Data/Section.elm
index 4dfb07c..ffb9f47 100644
--- a/example/src/Data/Section.elm
+++ b/example/src/Data/Section.elm
@@ -1,32 +1,29 @@
-module Data.Section exposing (Section(..),asList,toString,fromString)
+module Data.Section exposing (Section(..), asList, fromString, toString)
+
 
 type Section
-    = ComponentViews
-    | ReusableViews
+    = ReusableViews
     | StatelessViews
 
+
 asList : List Section
 asList =
-    [ StatelessViews, ReusableViews, ComponentViews ]
+    [ StatelessViews, ReusableViews ]
+
 
 toString : Section -> String
 toString section =
     case section of
-        ComponentViews ->
-            "Component"
-
         ReusableViews ->
             "Reusable"
 
         StatelessViews ->
             "Stateless"
 
+
 fromString : String -> Maybe Section
 fromString string =
     case string of
-        "Component" ->
-            Just ComponentViews
-
         "Reusable" ->
             Just ReusableViews
 
@@ -34,4 +31,4 @@ fromString string =
             Just StatelessViews
 
         _ ->
-            Nothing
\ No newline at end of file
+            Nothing
diff --git a/example/src/Data/Style.elm b/example/src/Data/Style.elm
new file mode 100644
index 0000000..7886b7f
--- /dev/null
+++ b/example/src/Data/Style.elm
@@ -0,0 +1,32 @@
+module Data.Style exposing (Style)
+
+import Widget.Style
+    exposing
+        ( ButtonStyle
+        , ColumnStyle
+        , DialogStyle
+        , ExpansionPanelStyle
+        , LayoutStyle
+        , RowStyle
+        , SortTableStyle
+        , TabStyle
+        , TextInputStyle
+        )
+
+
+type alias Style msg =
+    { dialog : DialogStyle msg
+    , expansionPanel : ExpansionPanelStyle msg
+    , button : ButtonStyle msg
+    , primaryButton : ButtonStyle msg
+    , tab : TabStyle msg
+    , textInput : TextInputStyle msg
+    , chipButton : ButtonStyle msg
+    , row : RowStyle msg
+    , buttonRow : RowStyle msg
+    , column : ColumnStyle msg
+    , cardColumn : ColumnStyle msg
+    , sortTable : SortTableStyle msg
+    , selectButton : ButtonStyle msg
+    , layout : LayoutStyle msg
+    }
diff --git a/example/src/Data/Style/ElmUiFramework.elm b/example/src/Data/Style/ElmUiFramework.elm
new file mode 100644
index 0000000..6cb4486
--- /dev/null
+++ b/example/src/Data/Style/ElmUiFramework.elm
@@ -0,0 +1,339 @@
+module Data.Style.ElmUiFramework exposing (style)
+
+import Data.Style exposing (Style)
+import Element
+import Element.Border as Border
+import Element.Font as Font
+import Framework
+import Framework.Button as Button
+import Framework.Card as Card
+import Framework.Color as Color
+import Framework.Grid as Grid
+import Framework.Group as Group
+import Framework.Heading as Heading
+import Framework.Tag as Tag
+import Icons
+import Widget.Style
+    exposing
+        ( ButtonStyle
+        , ColumnStyle
+        , DialogStyle
+        , ExpansionPanelStyle
+        , LayoutStyle
+        , RowStyle
+        , SnackbarStyle
+        , SortTableStyle
+        , TabStyle
+        , TextInputStyle
+        )
+
+
+textButton : ButtonStyle msg
+textButton =
+    { container = Button.simple
+    , labelRow = Grid.simple
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+simpleButton : ButtonStyle msg
+simpleButton =
+    { container = Button.simple ++ Color.success
+    , labelRow = Grid.simple
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+menuTabButton : ButtonStyle msg
+menuTabButton =
+    { container =
+        [ Element.height <| Element.px <| 42
+        , Border.widthEach
+            { top = 0
+            , left = 0
+            , right = 0
+            , bottom = 4
+            }
+        , Element.paddingEach
+            { top = 12
+            , left = 8
+            , right = 8
+            , bottom = 4
+            }
+        , Border.color Color.black
+        ]
+    , labelRow = Grid.simple
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = [ Border.color Color.turquoise ]
+    , otherwise = []
+    }
+
+
+menuButton : ButtonStyle msg
+menuButton =
+    { labelRow = Grid.simple
+    , container = Button.simple ++ Group.center ++ Color.dark
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+sheetButton : ButtonStyle msg
+sheetButton =
+    { container =
+        Button.fill
+            ++ Group.center
+            ++ Color.light
+            ++ [ Font.alignLeft ]
+    , labelRow = Grid.simple
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+buttonStyle : ButtonStyle msg
+buttonStyle =
+    { labelRow = [ Element.spacing 8 ]
+    , container = Button.simple
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+snackbarButton : ButtonStyle msg
+snackbarButton =
+    { labelRow = Grid.simple
+    , container = Button.simple ++ Color.dark
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+tabButtonStyle : ButtonStyle msg
+tabButtonStyle =
+    { labelRow = [ Element.spacing 8 ]
+    , container = Button.simple ++ Group.top
+    , text = []
+    , ifDisabled = Color.disabled
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+textInputStyle : TextInputStyle msg
+textInputStyle =
+    { chipButton = chipButtonStyle
+    , chipsRow =
+        [ Element.width <| Element.shrink
+        , Element.spacing <| 4
+        , Element.paddingEach
+            { top = 8
+            , left = 0
+            , right = 0
+            , bottom = 8
+            }
+        ]
+    , containerRow =
+        Button.simple
+            ++ Color.light
+            ++ [ Border.color <| Element.rgb255 186 189 182
+               , Font.alignLeft
+               , Element.paddingXY 8 0
+               , Element.height <| Element.px <| 42
+               ]
+            ++ Grid.simple
+    , input =
+        Color.light
+            ++ [ Element.padding 8
+               ]
+    }
+
+
+chipButtonStyle : ButtonStyle msg
+chipButtonStyle =
+    { container = Tag.simple
+    , text = []
+    , ifDisabled = []
+    , labelRow = Grid.simple
+    , ifActive = Color.primary
+    , otherwise = []
+    }
+
+
+expansionPanelStyle : ExpansionPanelStyle msg
+expansionPanelStyle =
+    { containerColumn = Card.simple ++ Grid.simple ++ [ Element.height <| Element.shrink ]
+    , panelRow = Grid.spacedEvenly ++ [ Element.height <| Element.shrink ]
+    , labelRow = Grid.simple ++ [ Element.height <| Element.shrink ]
+    , content = []
+    , expandIcon = Icons.chevronDown |> Element.html |> Element.el []
+    , collapseIcon = Icons.chevronUp |> Element.html |> Element.el []
+    }
+
+
+dialog : DialogStyle msg
+dialog =
+    { containerColumn =
+        Card.simple
+            ++ Grid.simple
+            ++ [ Element.centerY
+               , Element.width <| Element.minimum 280 <| Element.maximum 560 <| Element.fill
+               ]
+    , title = Heading.h3
+    , text = []
+    , buttonRow =
+        Grid.simple
+            ++ [ Element.paddingEach
+                    { top = 28
+                    , bottom = 0
+                    , left = 0
+                    , right = 0
+                    }
+               ]
+    , acceptButton = simpleButton
+    , dismissButton = textButton
+    }
+
+
+snackbar : SnackbarStyle msg
+snackbar =
+    { containerRow =
+        Card.simple
+            ++ Color.dark
+            ++ Grid.simple
+            ++ [ Element.paddingXY 8 6
+               , Element.height <| Element.px <| 54
+               ]
+    , button = snackbarButton
+    , text = [ Element.paddingXY 8 0 ]
+    }
+
+
+tab : TabStyle msg
+tab =
+    { button = tabButtonStyle
+    , optionRow = Grid.simple
+    , containerColumn = Grid.compact
+    , content = Card.small ++ Group.bottom
+    }
+
+
+row : RowStyle msg
+row =
+    { containerRow = Grid.simple
+    , element = []
+    , ifFirst = Group.left
+    , ifLast = Group.right
+    , otherwise = Group.center
+    }
+
+
+buttonRow : RowStyle msg
+buttonRow =
+    { containerRow = Grid.compact
+    , element = []
+    , ifFirst = Group.left
+    , ifLast = Group.right
+    , otherwise = Group.center
+    }
+
+
+cardColumn : ColumnStyle msg
+cardColumn =
+    { containerColumn = Grid.compact ++ [ Element.height <| Element.fill ]
+    , element = Card.large ++ [ Element.height <| Element.fill ]
+    , ifFirst = Group.top
+    , ifLast = Group.bottom
+    , otherwise = Group.center
+    }
+
+
+column : ColumnStyle msg
+column =
+    { containerColumn = Grid.compact
+    , element = []
+    , ifFirst = Group.top
+    , ifLast = Group.bottom
+    , otherwise = Group.center
+    }
+
+
+sortTable : SortTableStyle msg
+sortTable =
+    { containerTable = Grid.simple
+    , headerButton = tabButtonStyle
+    , ascIcon = Icons.chevronUp |> Element.html |> Element.el []
+    , descIcon = Icons.chevronDown |> Element.html |> Element.el []
+    , defaultIcon = Element.none
+    }
+
+
+layout : LayoutStyle msg
+layout =
+    { container = []
+    , snackbar = snackbar
+    , layout = Framework.responsiveLayout
+    , header =
+        Framework.container
+            ++ Color.dark
+            ++ [ Element.padding <| 0
+               , Element.height <| Element.px <| 42
+               ]
+    , menuButton = menuButton
+    , sheetButton = sheetButton
+    , menuTabButton = menuTabButton
+    , sheet =
+        Color.light ++ [ Element.width <| Element.maximum 256 <| Element.fill ]
+    , menuIcon =
+        Icons.menu |> Element.html |> Element.el []
+    , moreVerticalIcon =
+        Icons.moreVertical |> Element.html |> Element.el []
+    , spacing = 8
+    , title = Heading.h2
+    , searchIcon =
+        Icons.search |> Element.html |> Element.el []
+    , search =
+        Color.simple
+            ++ Card.large
+            ++ [ Font.color <| Element.rgb255 0 0 0
+               , Element.padding 6
+               , Element.centerY
+               , Element.alignRight
+               ]
+    , searchFill =
+        Color.light ++ Group.center
+    }
+
+
+style : Style msg
+style =
+    { sortTable = sortTable
+    , row = row
+    , buttonRow = buttonRow
+    , cardColumn = cardColumn
+    , column = column
+    , button = buttonStyle
+    , primaryButton = simpleButton
+    , tab = tab
+    , textInput = textInputStyle
+    , chipButton = chipButtonStyle
+    , expansionPanel = expansionPanelStyle
+    , dialog = dialog
+    , selectButton = buttonStyle
+    , layout = layout
+    }
diff --git a/example/src/Data/Style/Material.elm b/example/src/Data/Style/Material.elm
new file mode 100644
index 0000000..890a166
--- /dev/null
+++ b/example/src/Data/Style/Material.elm
@@ -0,0 +1,56 @@
+module Data.Style.Material exposing (style)
+
+import Color exposing (Color)
+import Color.Accessibility as Accessibility
+import Color.Convert as Convert
+import Data.Style exposing (Style)
+import Element exposing (Attribute, Element)
+import Element.Background as Background
+import Element.Border as Border
+import Element.Font as Font
+import Html.Attributes as Attributes
+import Icons
+import Widget.Style
+    exposing
+        ( ButtonStyle
+        , ColumnStyle
+        , DialogStyle
+        , ExpansionPanelStyle
+        , LayoutStyle
+        , RowStyle
+        , SnackbarStyle
+        , SortTableStyle
+        , TabStyle
+        , TextInputStyle
+        )
+import Widget.Style.Material as Material exposing (Palette)
+import Widget.Style.Template as Template
+
+
+sortTable : Palette -> SortTableStyle msg
+sortTable palette =
+    { containerTable = []
+    , headerButton = Material.textButton palette
+    , ascIcon = Icons.chevronUp |> Element.html |> Element.el []
+    , descIcon = Icons.chevronDown |> Element.html |> Element.el []
+    , defaultIcon = Element.none
+    }
+
+
+style : Palette -> Style msg
+style palette =
+    { sortTable = sortTable palette
+    , row = Material.row
+    , buttonRow = Material.buttonRow
+    , cardColumn = Material.cardColumn palette
+    , column = Material.column
+    , button = Material.outlinedButton palette
+    , primaryButton = Material.containedButton palette
+    , selectButton = Material.toggleButton palette
+    , tab = Material.tab palette
+    , textInput = Material.textInput palette
+    , chipButton = Material.chip palette
+    , expansionPanel = Material.expansionPanel palette
+    , dialog = Material.alertDialog palette
+    , layout = Material.layout palette
+    }
diff --git a/example/src/Data/Style/Template.elm b/example/src/Data/Style/Template.elm
new file mode 100644
index 0000000..937c718
--- /dev/null
+++ b/example/src/Data/Style/Template.elm
@@ -0,0 +1,27 @@
+module Data.Style.Template exposing (style)
+
+import Data.Style exposing (Style)
+import Element exposing (Attribute, Element)
+import Element.Background as Background
+import Element.Border as Border
+import Element.Font as Font
+import Widget.Style.Template as Template
+
+
+style : Style msg
+style =
+    { sortTable = Template.sortTable <| "sortTable"
+    , row = Template.row <| "row"
+    , buttonRow = Template.row <| "buttonRow"
+    , cardColumn = Template.column <| "cardRow"
+    , column = Template.column <| "column"
+    , button = Template.button <| "button"
+    , primaryButton = Template.button <| "primaryButton"
+    , tab = Template.tab <| "tab"
+    , textInput = Template.textInput <| "textInput"
+    , chipButton = Template.button <| "chipButton"
+    , expansionPanel = Template.expansionPanel "expansionPanel"
+    , selectButton = Template.button "selectButton"
+    , dialog = Template.dialog "dialog"
+    , layout = Template.layout "layout"
+    }
diff --git a/example/src/Data/Theme.elm b/example/src/Data/Theme.elm
new file mode 100644
index 0000000..dfaf9b0
--- /dev/null
+++ b/example/src/Data/Theme.elm
@@ -0,0 +1,30 @@
+module Data.Theme exposing (Theme(..), toStyle)
+
+import Data.Style exposing (Style)
+import Data.Style.ElmUiFramework
+import Data.Style.Material
+import Data.Style.Template
+import Widget.Style.Material
+
+
+type Theme
+    = ElmUiFramework
+    | Template
+    | Material
+    | DarkMaterial
+
+
+toStyle : Theme -> Style msg
+toStyle theme =
+    case theme of
+        ElmUiFramework ->
+            Data.Style.ElmUiFramework.style
+
+        Template ->
+            Data.Style.Template.style
+
+        Material ->
+            Data.Style.Material.style Widget.Style.Material.defaultPalette
+
+        DarkMaterial ->
+            Data.Style.Material.style Widget.Style.Material.darkPalette
diff --git a/example/src/Example.elm b/example/src/Example.elm
deleted file mode 100644
index 78bd0a8..0000000
--- a/example/src/Example.elm
+++ /dev/null
@@ -1,395 +0,0 @@
-module Example exposing (main)
-
-import Browser
-import Browser.Dom as Dom exposing (Viewport)
-import Browser.Events as Events
-import Browser.Navigation as Navigation
-import Component
-import Element exposing (DeviceClass(..), Element)
-import Element.Input as Input
-import Element.Font as Font
-import Element.Border as Border
-import Framework
-import Framework.Button as Button
-import Framework.Card as Card
-import Framework.Color as Color
-import Framework.Grid as Grid
-import Framework.Group as Group
-import Framework.Heading as Heading
-import Framework.Input as Input
-import Framework.Tag as Tag
-import Html exposing (Html)
-import Html.Attributes as Attributes
-import Icons
-import Layout exposing (Direction, Layout)
-import Core.Style exposing (Style)
-import Reusable
-import Set exposing (Set)
-import Stateless
-import Task
-import Time
-import Widget
-import Widget.FilterSelect as FilterSelect
-import Widget.ScrollingNav as ScrollingNav
-import Widget.Snackbar as Snackbar
-import Widget.ValidatedInput as ValidatedInput
-import Data.Section as Section exposing (Section(..))
-
-type alias LoadedModel =
-    { component : Component.Model
-    , stateless : Stateless.Model
-    , reusable : Reusable.Model
-    , scrollingNav : ScrollingNav.Model Section
-    , layout : Layout
-    , displayDialog : Bool
-    , deviceClass : DeviceClass
-    }
-
-
-type Model
-    = Loading
-    | Loaded LoadedModel
-
-
-type LoadedMsg
-    = StatelessSpecific Stateless.Msg
-    | ReusableSpecific Reusable.Msg
-    | ComponentSpecific Component.Msg
-    | ScrollingNavSpecific (ScrollingNav.Msg Section)
-    | TimePassed Int
-    | AddSnackbar String
-    | ToggleDialog Bool
-    | ChangedSidebar (Maybe Direction)
-    | Resized { width : Int, height : Int }
-    | Load String
-    | JumpTo Section
-
-
-type Msg
-    = LoadedSpecific LoadedMsg
-    | GotViewport Viewport
-
-style : Style msg
-style =
-    { snackbar = Card.simple ++ Color.dark
-    , layout = Framework.responsiveLayout
-    , header =
-        Framework.container
-            ++ Color.dark
-            ++ [ Element.padding <| 0
-                , Element.height <| Element.px <| 42
-                ]
-    , menuButton =
-        Button.simple ++ Group.center ++ Color.dark
-    , menuButtonSelected =
-        Color.primary
-    , sheetButton =
-        Button.fill
-        ++ Group.center 
-        ++ Color.light
-        ++ [Font.alignLeft]
-    , sheetButtonSelected =
-        Color.primary
-    , tabButton = 
-        [ Element.height <| Element.px <| 42
-        , Border.widthEach 
-            { top = 0,
-            left = 0,
-            right = 0,
-            bottom = 8
-            }
-        ]
-    , tabButtonSelected =
-        [ Border.color Color.turquoise
-        ]
-    , sheet =
-        Color.light ++ [ Element.width <| Element.maximum 256 <| Element.fill]
-    , menuIcon =
-        Icons.menu |> Element.html |> Element.el []
-    , moreVerticalIcon =
-        Icons.moreVertical |> Element.html |> Element.el []
-    , spacing = 8
-    }
-
-
-initialModel : Viewport -> ( LoadedModel, Cmd LoadedMsg )
-initialModel { viewport } =
-    let
-        ( scrollingNav, cmd ) =
-            ScrollingNav.init
-                { labels = Section.toString
-                , arrangement = Section.asList
-                }
-    in
-    ( { component = Component.init
-      , stateless = Stateless.init
-      , reusable = Reusable.init
-      , scrollingNav = scrollingNav
-      , layout = Layout.init
-      , displayDialog = False
-      , deviceClass =
-            { width = viewport.width |> round
-            , height = viewport.height |> round
-            }
-                |> Element.classifyDevice
-                |> .class
-      }
-    , cmd |> Cmd.map ScrollingNavSpecific
-    )
-
-
-init : () -> ( Model, Cmd Msg )
-init () =
-    ( Loading
-    , Task.perform GotViewport Dom.getViewport
-    )
-
-
-view : Model -> Html Msg
-view model =
-    case model of
-        Loading ->
-            Element.none |> Framework.responsiveLayout []
-
-        Loaded m ->
-            Html.map LoadedSpecific <|
-                Layout.view []
-                    { dialog =
-                        if m.displayDialog then
-                            Just
-                                { onDismiss = Just <| ToggleDialog False
-                                , content =
-                                    [ Element.el Heading.h3 <| Element.text "Dialog"
-                                    , "This is a dialog window"
-                                        |> Element.text
-                                        |> List.singleton
-                                        |> Element.paragraph []
-                                    , Input.button (Button.simple ++ [ Element.alignRight ])
-                                        { onPress = Just <| ToggleDialog False
-                                        , label = Element.text "Ok"
-                                        }
-                                    ]
-                                        |> Element.column 
-                                            ( Grid.simple
-                                                ++ Card.large
-                                                ++ [Element.centerX, Element.centerY]
-                                            )
-                                }
-
-                        else
-                            Nothing
-                    , content =
-                        [ Element.el [ Element.height <| Element.px <| 42 ] <| Element.none
-                        , [ m.scrollingNav
-                                |> ScrollingNav.view
-                                    (\section ->
-                                        case section of
-                                            ComponentViews ->
-                                                m.component
-                                                    |> Component.view
-                                                    |> Element.map ComponentSpecific
-
-                                            ReusableViews ->
-                                                Reusable.view
-                                                    { addSnackbar = AddSnackbar
-                                                    , model = m.reusable
-                                                    , msgMapper = ReusableSpecific
-                                                    }
-
-                                            StatelessViews ->
-                                                Stateless.view
-                                                    { msgMapper = StatelessSpecific
-                                                    , showDialog = ToggleDialog True
-                                                    , changedSheet = ChangedSidebar
-                                                    }
-                                                    m.stateless
-                                    )
-                          ]
-                            |> Element.column Framework.container
-                        ]
-                            |> Element.column Grid.compact
-                    , style = style
-                    , layout = m.layout
-                    , deviceClass = m.deviceClass
-                    , menu =
-                        { selected = 
-                            Section.asList
-                            |> List.indexedMap (\i s -> (i,s))
-                            |> List.filterMap
-                                ( \(i,s) ->
-                                    if  m.scrollingNav
-                                        |> ScrollingNav.current Section.fromString
-                                        |> (==) (Just s)
-                                    then
-                                        Just i
-                                    else
-                                        Nothing
-                                )
-                            |> List.head
-                            |> Maybe.withDefault 0
-                        , items =
-                            Section.asList
-                            |> List.map
-                                (\label ->
-                                    { icon = Element.none
-                                    , label = label |> Section.toString
-                                    , onPress = Just <| JumpTo <| label
-                                    }
-                                )
-                        }
-                    , actions =
-                        [ { onPress = Just <| Load "https://package.elm-lang.org/packages/Orasund/elm-ui-widgets/latest/"
-                          , label = "Docs"
-                          , icon = Icons.book|> Element.html |> Element.el []
-                          }
-                        , { onPress = Just <| Load "https://github.com/Orasund/elm-ui-widgets"
-                          , label = "Github"
-                          , icon = Icons.github|> Element.html |> Element.el []
-                          }
-                        , { onPress = Nothing
-                          , label = "Placeholder"
-                          , icon = Icons.circle|> Element.html |> Element.el []
-                          }
-                        , { onPress = Nothing
-                          , label = "Placeholder"
-                          , icon = Icons.triangle|> Element.html |> Element.el []
-                          }
-                        , { onPress = Nothing
-                          , label = "Placeholder"
-                          , icon = Icons.square|> Element.html |> Element.el []
-                          }
-                        ]
-                    , onChangedSidebar = ChangedSidebar
-                    , title = 
-                        (if m.deviceClass == Phone || m.deviceClass == Tablet then
-                            m.scrollingNav
-                            |> ScrollingNav.current Section.fromString
-                            |> Maybe.map Section.toString
-                            |> Maybe.withDefault "Elm-Ui-Widgets"
-                        else
-                            "Elm-Ui-Widgets"
-                        )
-                        |> Element.text 
-                        |> Element.el Heading.h1
-                    }
-
-
-updateLoaded : LoadedMsg -> LoadedModel -> ( LoadedModel, Cmd LoadedMsg )
-updateLoaded msg model =
-    case msg of
-        ComponentSpecific m ->
-            model.component
-                |> Component.update m
-                |> Tuple.mapBoth
-                    (\component ->
-                        { model
-                            | component = component
-                        }
-                    )
-                    (Cmd.map ComponentSpecific)
-
-        ReusableSpecific m ->
-            ( model.reusable
-                |> Reusable.update m
-                |> (\reusable ->
-                        { model
-                            | reusable = reusable
-                        }
-                   )
-            , Cmd.none
-            )
-
-        StatelessSpecific m ->
-            model.stateless
-                |> Stateless.update m
-                |> Tuple.mapBoth
-                    (\stateless ->
-                        { model
-                            | stateless = stateless
-                        }
-                    )
-                    (Cmd.map StatelessSpecific)
-
-        ScrollingNavSpecific m ->
-            model.scrollingNav
-                |> ScrollingNav.update m
-                |> Tuple.mapBoth
-                    (\scrollingNav ->
-                        { model
-                            | scrollingNav = scrollingNav
-                        }
-                    )
-                    (Cmd.map ScrollingNavSpecific)
-
-        TimePassed int ->
-            ( { model
-                | layout = model.layout |> Layout.timePassed int
-              }
-            , Cmd.none
-            )
-
-        AddSnackbar string ->
-            ( { model | layout = model.layout |> Layout.queueMessage string }
-            , Cmd.none
-            )
-
-        ToggleDialog bool ->
-            ( { model | displayDialog = bool }
-            , Cmd.none
-            )
-
-        Resized screen ->
-            ( { model | deviceClass = screen |> Element.classifyDevice |> .class }
-            , Cmd.none
-            )
-
-        ChangedSidebar sidebar ->
-            ( { model | layout = model.layout |> Layout.setSidebar sidebar }
-            , Cmd.none
-            )
-        
-        Load string ->
-            ( model, Navigation.load string)
-        
-        JumpTo section ->
-            ( model
-            , model.scrollingNav
-                |> ScrollingNav.jumpTo section
-                |> Cmd.map ScrollingNavSpecific
-            )
-
-
-update : Msg -> Model -> ( Model, Cmd Msg )
-update msg model =
-    case ( model, msg ) of
-        ( Loading, GotViewport viewport ) ->
-            initialModel viewport
-                |> Tuple.mapBoth Loaded (Cmd.map LoadedSpecific)
-
-        ( Loaded state, LoadedSpecific m ) ->
-            updateLoaded m state
-                |> Tuple.mapBoth Loaded (Cmd.map LoadedSpecific)
-
-        _ ->
-            ( model, Cmd.none )
-
-
-subscriptions : Model -> Sub Msg
-subscriptions model =
-    Sub.batch
-        [ ScrollingNav.subscriptions
-            |> Sub.map ScrollingNavSpecific
-        , Time.every 50 (always (TimePassed 50))
-        , Events.onResize (\h w -> Resized { height = h, width = w })
-        ]
-        |> Sub.map LoadedSpecific
-
-
-main : Program () Model Msg
-main =
-    Browser.element
-        { init = init
-        , view = view
-        , update = update
-        , subscriptions = subscriptions
-        }
diff --git a/example/src/Example/Button.elm b/example/src/Example/Button.elm
new file mode 100644
index 0000000..0ba4857
--- /dev/null
+++ b/example/src/Example/Button.elm
@@ -0,0 +1,96 @@
+module Example.Button exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import FeatherIcons
+import Widget
+import Widget.Style exposing (ButtonStyle, RowStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | primaryButton : ButtonStyle msg
+        , button : ButtonStyle msg
+        , row : RowStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { primaryButton = Material.containedButton Material.defaultPalette
+    , button = Material.outlinedButton Material.defaultPalette
+    , row = Material.row 
+    }
+
+
+type Model
+    = IsButtonEnabled Bool
+
+
+type Msg
+    = ChangedButtonStatus Bool
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( IsButtonEnabled True
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg _ =
+    case msg of
+        ChangedButtonStatus bool ->
+            ( IsButtonEnabled bool
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (IsButtonEnabled isButtonEnabled) =
+    [ Widget.button style.primaryButton
+        { text = "disable me"
+        , icon =
+            FeatherIcons.slash
+                |> FeatherIcons.withSize 16
+                |> FeatherIcons.toHtml []
+                |> Element.html
+                |> Element.el []
+        , onPress =
+            if isButtonEnabled then
+                ChangedButtonStatus False
+                    |> msgMapper
+                    |> Just
+
+            else
+                Nothing
+        }
+    , Widget.iconButton style.button
+        { text = "reset"
+        , icon =
+            FeatherIcons.repeat
+                |> FeatherIcons.withSize 16
+                |> FeatherIcons.toHtml []
+                |> Element.html
+                |> Element.el []
+        , onPress =
+            ChangedButtonStatus True
+                |> msgMapper
+                |> Just
+        }
+    ]
+        |> Widget.row style.row
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/Dialog.elm b/example/src/Example/Dialog.elm
new file mode 100644
index 0000000..b587c3d
--- /dev/null
+++ b/example/src/Example/Dialog.elm
@@ -0,0 +1,104 @@
+module Example.Dialog exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import FeatherIcons
+import Widget
+import Widget.Style exposing (ButtonStyle, DialogStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | dialog : DialogStyle msg
+        , primaryButton : ButtonStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { dialog = Material.alertDialog Material.defaultPalette
+    , primaryButton = Material.containedButton Material.defaultPalette
+    }
+
+type Model
+    = IsOpen Bool
+
+
+type Msg
+    = OpenDialog Bool
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( IsOpen True
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg _ =
+    case msg of
+        OpenDialog bool ->
+            ( IsOpen bool
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (IsOpen isOpen) =
+    Widget.button style.primaryButton
+        { text = "show Dialog"
+        , icon =
+            FeatherIcons.eye
+                |> FeatherIcons.withSize 16
+                |> FeatherIcons.toHtml []
+                |> Element.html
+                |> Element.el []
+        , onPress =
+            OpenDialog True
+                |> msgMapper
+                |> Just
+        }
+        |> Element.el
+            ([ Element.height <| Element.minimum 200 <| Element.fill
+             , Element.width <| Element.minimum 400 <| Element.fill
+             ]
+                ++ (if isOpen then
+                        { text = "This is a dialog window"
+                        , title = Just "Dialog"
+                        , accept =
+                            Just
+                                { text = "Ok"
+                                , onPress =
+                                    Just <|
+                                        msgMapper <|
+                                            OpenDialog False
+                                }
+                        , dismiss =
+                            Just
+                                { text = "Dismiss"
+                                , onPress =
+                                    Just <|
+                                        msgMapper <|
+                                            OpenDialog False
+                                }
+                        }
+                            |> Widget.dialog style.dialog
+
+                    else
+                        []
+                   )
+            )
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/ExpansionPanel.elm b/example/src/Example/ExpansionPanel.elm
new file mode 100644
index 0000000..566a44b
--- /dev/null
+++ b/example/src/Example/ExpansionPanel.elm
@@ -0,0 +1,65 @@
+module Example.ExpansionPanel exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Widget
+import Widget.Style exposing (ExpansionPanelStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | expansionPanel : ExpansionPanelStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { expansionPanel = Material.expansionPanel Material.defaultPalette
+    }
+
+type Model
+    = IsExpanded Bool
+
+
+type Msg
+    = ToggleCollapsable Bool
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( IsExpanded False
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg _ =
+    case msg of
+        ToggleCollapsable bool ->
+            ( IsExpanded bool
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (IsExpanded isExpanded) =
+    { onToggle = ToggleCollapsable >> msgMapper
+    , isExpanded = isExpanded
+    , icon = Element.none
+    , text = "Title"
+    , content = Element.text <| "Hello World"
+    }
+        |> Widget.expansionPanel style.expansionPanel
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/List.elm b/example/src/Example/List.elm
new file mode 100644
index 0000000..cdb7b7e
--- /dev/null
+++ b/example/src/Example/List.elm
@@ -0,0 +1,61 @@
+module Example.List exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Widget
+import Widget.Style exposing (ColumnStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | cardColumn : ColumnStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { cardColumn = Material.cardColumn Material.defaultPalette
+    }
+
+type alias Model =
+    ()
+
+
+type alias Msg =
+    Never
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( ()
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update _ () =
+    ( ()
+    , Cmd.none
+    )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions () =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view _ style () =
+    [ Element.text <| "A"
+    , Element.text <| "B"
+    , Element.text <| "C"
+    ]
+        |> Widget.column style.cardColumn
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/Modal.elm b/example/src/Example/Modal.elm
new file mode 100644
index 0000000..f09b0b2
--- /dev/null
+++ b/example/src/Example/Modal.elm
@@ -0,0 +1,103 @@
+module Example.Modal exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import FeatherIcons
+import Widget
+import Widget.Style exposing (ButtonStyle, ColumnStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | cardColumn : ColumnStyle msg
+        , primaryButton : ButtonStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { cardColumn = Material.cardColumn Material.defaultPalette
+    , primaryButton = Material.containedButton Material.defaultPalette
+    }
+
+type Model
+    = IsEnabled Bool
+
+
+type Msg
+    = ToggleModal Bool
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( IsEnabled True
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg _ =
+    case msg of
+        ToggleModal bool ->
+            ( IsEnabled bool
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (IsEnabled isEnabled) =
+    Widget.button style.primaryButton
+        { text = "show Modal"
+        , icon =
+            FeatherIcons.eye
+                |> FeatherIcons.withSize 16
+                |> FeatherIcons.toHtml []
+                |> Element.html
+                |> Element.el []
+        , onPress =
+            ToggleModal True
+                |> msgMapper
+                |> Just
+        }
+        |> Element.el
+            ([ Element.height <| Element.minimum 200 <| Element.fill
+             , Element.width <| Element.minimum 400 <| Element.fill
+             ]
+                ++ (if isEnabled then
+                        Widget.modal
+                            { onDismiss =
+                                ToggleModal False
+                                    |> msgMapper
+                                    |> Just
+                            , content =
+                                "Click on the area around this box to close it."
+                                    |> Element.text
+                                    |> List.singleton
+                                    |> Element.paragraph []
+                                    |> List.singleton
+                                    |> Widget.column style.cardColumn
+                                    |> Element.el
+                                        [ Element.height <| Element.px 100
+                                        , Element.width <| Element.px 250
+                                        , Element.centerX
+                                        , Element.centerY
+                                        ]
+                            }
+
+                    else
+                        []
+                   )
+            )
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/MultiSelect.elm b/example/src/Example/MultiSelect.elm
new file mode 100644
index 0000000..acc77e1
--- /dev/null
+++ b/example/src/Example/MultiSelect.elm
@@ -0,0 +1,84 @@
+module Example.MultiSelect exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Set exposing (Set)
+import Widget
+import Widget.Style exposing (ButtonStyle, RowStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | buttonRow : RowStyle msg
+        , selectButton : ButtonStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { buttonRow = Material.buttonRow
+    , selectButton = Material.toggleButton Material.defaultPalette
+    }
+
+type Model
+    = Selected (Set Int)
+
+
+type Msg
+    = ChangedSelected Int
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( Selected <| Set.empty
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg (Selected selected) =
+    case msg of
+        ChangedSelected int ->
+            ( selected
+                |> (if selected |> Set.member int then
+                        Set.remove int
+
+                    else
+                        Set.insert int
+                   )
+                |> Selected
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (Selected selected) =
+    { selected = selected
+    , options =
+        [ 1, 2, 42 ]
+            |> List.map
+                (\int ->
+                    { text = String.fromInt int
+                    , icon = Element.none
+                    }
+                )
+    , onSelect = ChangedSelected >> msgMapper >> Just
+    }
+        |> Widget.multiSelect
+        |> Widget.buttonRow
+            { list = style.buttonRow
+            , button = style.selectButton
+            }
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/Select.elm b/example/src/Example/Select.elm
new file mode 100644
index 0000000..6a9a091
--- /dev/null
+++ b/example/src/Example/Select.elm
@@ -0,0 +1,76 @@
+module Example.Select exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Widget
+import Widget.Style exposing (ButtonStyle, RowStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | buttonRow : RowStyle msg
+        , selectButton : ButtonStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { buttonRow = Material.buttonRow
+    , selectButton = Material.toggleButton Material.defaultPalette
+    }
+
+type Model
+    = Selected (Maybe Int)
+
+
+type Msg
+    = ChangedSelected Int
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( Selected Nothing
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg _ =
+    case msg of
+        ChangedSelected int ->
+            ( Selected <| Just int
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (Selected selected) =
+    { selected = selected
+    , options =
+        [ 1, 2, 42 ]
+            |> List.map
+                (\int ->
+                    { text = String.fromInt int
+                    , icon = Element.none
+                    }
+                )
+    , onSelect = ChangedSelected >> msgMapper >> Just
+    }
+        |> Widget.select
+        |> Widget.buttonRow
+            { list = style.buttonRow
+            , button = style.selectButton
+            }
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/SortTable.elm b/example/src/Example/SortTable.elm
new file mode 100644
index 0000000..a3eb7b0
--- /dev/null
+++ b/example/src/Example/SortTable.elm
@@ -0,0 +1,114 @@
+module Example.SortTable exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Widget
+import Widget.Style exposing (SortTableStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | sortTable : SortTableStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { sortTable = 
+        { containerTable = []
+        , headerButton = Material.textButton Material.defaultPalette
+        , ascIcon = 
+            Material.expansionPanel Material.defaultPalette
+                |> .collapseIcon
+        , descIcon =
+            Material.expansionPanel Material.defaultPalette
+                |> .expandIcon
+        , defaultIcon = Element.none
+        }
+    }
+
+
+type alias Model =
+    { title : String
+    , asc : Bool
+    }
+
+
+type Msg
+    = ChangedSorting String
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( { title = "Name", asc = True }
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        ChangedSorting string ->
+            ( { title = string
+              , asc =
+                    if model.title == string then
+                        not model.asc
+
+                    else
+                        True
+              }
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style model =
+    Widget.sortTable style.sortTable
+        { content =
+            [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
+            , { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
+            , { id = 3, name = "Alfred", rating = 4.22, hash = Just "6fs1" }
+            , { id = 4, name = "Thomas", rating = 3, hash = Just "k52f" }
+            ]
+        , columns =
+            [ Widget.intColumn
+                { title = "Id"
+                , value = .id
+                , toString = \int -> "#" ++ String.fromInt int
+                , width = Element.fill
+                }
+            , Widget.stringColumn
+                { title = "Name"
+                , value = .name
+                , toString = identity
+                , width = Element.fill
+                }
+            , Widget.floatColumn
+                { title = "Rating"
+                , value = .rating
+                , toString = String.fromFloat
+                , width = Element.fill
+                }
+            , Widget.unsortableColumn
+                { title = "Hash"
+                , toString = .hash >> Maybe.withDefault "None"
+                , width = Element.fill
+                }
+            ]
+        , asc = model.asc
+        , sortBy = model.title
+        , onChange = ChangedSorting >> msgMapper
+        }
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/Tab.elm b/example/src/Example/Tab.elm
new file mode 100644
index 0000000..f07ca4a
--- /dev/null
+++ b/example/src/Example/Tab.elm
@@ -0,0 +1,88 @@
+module Example.Tab exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Widget
+import Widget.Style exposing (TabStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | tab : TabStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { tab = Material.tab Material.defaultPalette
+    }
+
+type Model
+    = Selected (Maybe Int)
+
+
+type Msg
+    = ChangedTab Int
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( Selected Nothing
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg _ =
+    case msg of
+        ChangedTab int ->
+            ( Selected <| Just int
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style (Selected selected) =
+    Widget.tab style.tab
+        { tabs =
+            { selected = selected
+            , options =
+                [ 1, 2, 3 ]
+                    |> List.map
+                        (\int ->
+                            { text = "Tab " ++ (int |> String.fromInt)
+                            , icon = Element.none
+                            }
+                        )
+            , onSelect = ChangedTab >> msgMapper >> Just
+            }
+        , content =
+            \s ->
+                (case s of
+                    Just 0 ->
+                        "This is Tab 1"
+
+                    Just 1 ->
+                        "This is the second tab"
+
+                    Just 2 ->
+                        "The thrid and last tab"
+
+                    _ ->
+                        "Please select a tab"
+                )
+                    |> Element.text
+        }
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Example/TextInput.elm b/example/src/Example/TextInput.elm
new file mode 100644
index 0000000..786fed9
--- /dev/null
+++ b/example/src/Example/TextInput.elm
@@ -0,0 +1,120 @@
+module Example.TextInput exposing (Model, Msg, init, subscriptions, update, view)
+
+import Element exposing (Element)
+import Set exposing (Set)
+import Widget
+import Widget.Style exposing (ColumnStyle, TextInputStyle)
+import Widget.Style.Material as Material
+import Browser
+
+type alias Style style msg =
+    { style
+        | textInput : TextInputStyle msg
+        , column : ColumnStyle msg
+    }
+
+materialStyle : Style {} msg
+materialStyle =
+    { textInput = Material.textInput Material.defaultPalette
+    , column = Material.column
+    }
+
+
+type alias Model =
+    { chipTextInput : Set String
+    , textInput : String
+    }
+
+
+type Msg
+    = ToggleTextInputChip String
+    | SetTextInput String
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( { chipTextInput = Set.empty
+      , textInput = ""
+      }
+    , Cmd.none
+    )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        ToggleTextInputChip string ->
+            ( { model
+                | chipTextInput =
+                    model.chipTextInput
+                        |> (if model.chipTextInput |> Set.member string then
+                                Set.remove string
+
+                            else
+                                Set.insert string
+                           )
+              }
+            , Cmd.none
+            )
+
+        SetTextInput string ->
+            ( { model | textInput = string }, Cmd.none )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.none
+
+
+view : (Msg -> msg) -> Style style msg -> Model -> Element msg
+view msgMapper style model =
+    [ { chips =
+            model.chipTextInput
+                |> Set.toList
+                |> List.map
+                    (\string ->
+                        { icon = Element.none
+                        , text = string
+                        , onPress =
+                            string
+                                |> ToggleTextInputChip
+                                |> msgMapper
+                                |> Just
+                        }
+                    )
+      , text = model.textInput
+      , placeholder = Nothing
+      , label = "Chips"
+      , onChange = SetTextInput >> msgMapper
+      }
+        |> Widget.textInput style.textInput
+    , model.chipTextInput
+        |> Set.diff
+            ([ "A", "B", "C" ]
+                |> Set.fromList
+            )
+        |> Set.toList
+        |> List.map
+            (\string ->
+                Widget.button style.textInput.chipButton
+                    { onPress =
+                        string
+                            |> ToggleTextInputChip
+                            |> msgMapper
+                            |> Just
+                    , text = string
+                    , icon = Element.none
+                    }
+            )
+        |> Element.wrappedRow [ Element.spacing 10 ]
+    ]
+        |> Widget.column style.column
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = always init
+        , view = view identity materialStyle >> Element.layout []
+        , update = update
+        , subscriptions = subscriptions
+        }
\ No newline at end of file
diff --git a/example/src/Icons.elm b/example/src/Icons.elm
index dd3410a..de4dd0d 100644
--- a/example/src/Icons.elm
+++ b/example/src/Icons.elm
@@ -1,78 +1,207 @@
 module Icons exposing
     ( book
+    , chevronDown
+    , chevronLeft
+    , chevronRight
+    , chevronUp
+    , circle
     , github
     , menu
     , moreVertical
-    , circle
-    , triangle
+    , penTool
+    , repeat
+    , search
+    , slash
     , square
+    , triangle
     )
 
 import Html exposing (Html)
 import Svg exposing (Svg, svg)
-import Svg.Attributes exposing (..)
+import Svg.Attributes as Attributes
 
 
 svgFeatherIcon : String -> List (Svg msg) -> Html msg
 svgFeatherIcon className =
     svg
-        [ class <| "feather feather-" ++ className
-        , fill "none"
-        , height "16"
-        , stroke "currentColor"
-        , strokeLinecap "round"
-        , strokeLinejoin "round"
-        , strokeWidth "2"
-        , viewBox "0 0 24 24"
-        , width "16"
+        [ Attributes.class <| "feather feather-" ++ className
+        , Attributes.fill "none"
+        , Attributes.height "16"
+        , Attributes.stroke "currentColor"
+        , Attributes.strokeLinecap "round"
+        , Attributes.strokeLinejoin "round"
+        , Attributes.strokeWidth "2"
+        , Attributes.viewBox "0 0 24 24"
+        , Attributes.width "16"
+        ]
+
+
+chevronDown : Html msg
+chevronDown =
+    svgFeatherIcon "chevron-down"
+        [ Svg.polyline [ Attributes.points "6 9 12 15 18 9" ] []
+        ]
+
+
+chevronRight : Html msg
+chevronRight =
+    svgFeatherIcon "chevron-right"
+        [ Svg.polyline [ Attributes.points "9 18 15 12 9 6" ] []
+        ]
+
+
+chevronLeft : Html msg
+chevronLeft =
+    svgFeatherIcon "chevron-left"
+        [ Svg.polyline [ Attributes.points "15 18 9 12 15 6" ] []
+        ]
+
+
+chevronUp : Html msg
+chevronUp =
+    svgFeatherIcon "chevron-up"
+        [ Svg.polyline [ Attributes.points "18 15 12 9 6 15" ] []
+        ]
+
+
+repeat : Html msg
+repeat =
+    svgFeatherIcon "repeat"
+        [ Svg.polyline [ Attributes.points "17 1 21 5 17 9" ] []
+        , Svg.path [ Attributes.d "M3 11V9a4 4 0 0 1 4-4h14" ] []
+        , Svg.polyline [ Attributes.points "7 23 3 19 7 15" ] []
+        , Svg.path [ Attributes.d "M21 13v2a4 4 0 0 1-4 4H3" ] []
+        ]
+
+
+penTool : Html msg
+penTool =
+    svgFeatherIcon "pen-tool"
+        [ Svg.path [ Attributes.d "M12 19l7-7 3 3-7 7-3-3z" ] []
+        , Svg.path [ Attributes.d "M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z" ] []
+        , Svg.path [ Attributes.d "M2 2l7.586 7.586" ] []
+        , Svg.circle
+            [ Attributes.cx "11"
+            , Attributes.cy "11"
+            , Attributes.r "2"
+            ]
+            []
         ]
 
 
 book : Html msg
 book =
     svgFeatherIcon "book"
-        [ Svg.path [ d "M4 19.5A2.5 2.5 0 0 1 6.5 17H20" ] []
-        , Svg.path [ d "M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" ] []
+        [ Svg.path [ Attributes.d "M4 19.5A2.5 2.5 0 0 1 6.5 17H20" ] []
+        , Svg.path [ Attributes.d "M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" ] []
         ]
 
 
 github : Html msg
 github =
     svgFeatherIcon "github"
-        [ Svg.path [ d "M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" ] []
+        [ Svg.path [ Attributes.d "M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22" ] []
         ]
 
 
 menu : Html msg
 menu =
     svgFeatherIcon "menu"
-        [ Svg.line [ x1 "3", y1 "12", x2 "21", y2 "12" ] []
-        , Svg.line [ x1 "3", y1 "6", x2 "21", y2 "6" ] []
-        , Svg.line [ x1 "3", y1 "18", x2 "21", y2 "18" ] []
+        [ Svg.line
+            [ Attributes.x1 "3"
+            , Attributes.y1 "12"
+            , Attributes.x2 "21"
+            , Attributes.y2 "12"
+            ]
+            []
+        , Svg.line
+            [ Attributes.x1 "3"
+            , Attributes.y1 "6"
+            , Attributes.x2 "21"
+            , Attributes.y2 "6"
+            ]
+            []
+        , Svg.line
+            [ Attributes.x1 "3"
+            , Attributes.y1 "18"
+            , Attributes.x2 "21"
+            , Attributes.y2 "18"
+            ]
+            []
         ]
 
+
 moreVertical : Html msg
 moreVertical =
     svgFeatherIcon "more-vertical"
-        [ Svg.circle [ cx "12", cy "12", r "1" ] []
-        , Svg.circle [ cx "12", cy "5", r "1" ] []
-        , Svg.circle [ cx "12", cy "19", r "1" ] []
+        [ Svg.circle [ Attributes.cx "12", Attributes.cy "12", Attributes.r "1" ] []
+        , Svg.circle [ Attributes.cx "12", Attributes.cy "5", Attributes.r "1" ] []
+        , Svg.circle [ Attributes.cx "12", Attributes.cy "19", Attributes.r "1" ] []
         ]
 
+
 circle : Html msg
 circle =
     svgFeatherIcon "circle"
-        [ Svg.circle [ cx "12", cy "12", r "10" ] []
+        [ Svg.circle [ Attributes.cx "12", Attributes.cy "12", Attributes.r "10" ] []
         ]
 
+
+slash : Html msg
+slash =
+    svgFeatherIcon "slash"
+        [ Svg.circle
+            [ Attributes.cx "12"
+            , Attributes.cy "12"
+            , Attributes.r "10"
+            ]
+            []
+        , Svg.line
+            [ Attributes.x1 "4.93"
+            , Attributes.y1 "4.93"
+            , Attributes.x2 "19.07"
+            , Attributes.y2 "19.07"
+            ]
+            []
+        ]
+
+
 triangle : Html msg
 triangle =
     svgFeatherIcon "triangle"
-        [ Svg.path [ d "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" ] []
+        [ Svg.path [ Attributes.d "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" ] []
         ]
 
+
 square : Html msg
 square =
     svgFeatherIcon "square"
-        [ Svg.rect [ Svg.Attributes.x "3", y "3", width "18", height "18", rx "2", ry "2" ] []
-        ]
\ No newline at end of file
+        [ Svg.rect
+            [ Attributes.x "3"
+            , Attributes.y "3"
+            , Attributes.width "18"
+            , Attributes.height "18"
+            , Attributes.rx "2"
+            , Attributes.ry "2"
+            ]
+            []
+        ]
+
+
+search : Html msg
+search =
+    svgFeatherIcon "search"
+        [ Svg.circle
+            [ Attributes.cx "11"
+            , Attributes.cy "11"
+            , Attributes.r "8"
+            ]
+            []
+        , Svg.line
+            [ Attributes.x1 "21"
+            , Attributes.y1 "21"
+            , Attributes.x2 "16.65"
+            , Attributes.y2 "16.65"
+            ]
+            []
+        ]
diff --git a/example/src/Main.elm b/example/src/Main.elm
new file mode 100644
index 0000000..6db0904
--- /dev/null
+++ b/example/src/Main.elm
@@ -0,0 +1,494 @@
+module Main exposing (main)
+
+import Array
+import Browser
+import Browser.Dom as Dom exposing (Viewport)
+import Browser.Events as Events
+import Browser.Navigation as Navigation
+import Data.Example as Example exposing (Example)
+import Data.Section as Section exposing (Section(..))
+import Data.Style exposing (Style)
+import Data.Theme as Theme exposing (Theme(..))
+import Element exposing (Element,DeviceClass(..))
+import Framework
+import Framework.Grid as Grid
+import Framework.Heading as Heading
+import Html exposing (Html)
+import Html.Attributes as Attributes
+import Icons
+import Reusable
+import Set.Any as AnySet exposing (AnySet)
+import Stateless
+import Task
+import Time
+import Widget
+import Widget.Layout as Layout exposing (Layout, Part)
+import Widget.ScrollingNav as ScrollingNav
+import FeatherIcons
+
+type alias LoadedModel =
+    { stateless : Stateless.Model
+    , scrollingNav : ScrollingNav.ScrollingNav Example
+    , layout : Layout LoadedMsg
+    , displayDialog : Bool
+    , window :
+        { height : Int
+        , width : Int
+        }
+    , search :
+        { raw : String
+        , current : String
+        , remaining : Int
+        }
+    , theme : Theme
+    , expanded : AnySet String Example
+    }
+
+
+type Model
+    = Loading
+    | Loaded LoadedModel
+
+
+type LoadedMsg
+    = StatelessSpecific Stateless.Msg
+    | UpdateScrollingNav (ScrollingNav.ScrollingNav Example -> ScrollingNav.ScrollingNav Example)
+    | TimePassed Int
+    | AddSnackbar ( String, Bool )
+    | ToggleDialog Bool
+    | ChangedSidebar (Maybe Part)
+    | Resized { width : Int, height : Int }
+    | Load String
+    | JumpTo Example
+    | ChangedSearch String
+    | SetTheme Theme
+    | Idle
+    | ToggledExample Example
+
+
+type Msg
+    = LoadedSpecific LoadedMsg
+    | GotViewport Viewport
+
+
+initialModel : Viewport -> ( LoadedModel, Cmd LoadedMsg )
+initialModel { viewport } =
+    let
+        ( scrollingNav, cmd ) =
+            ScrollingNav.init
+                { toString = Example.toString
+                , fromString = Example.fromString
+                , arrangement = Example.asList
+                , toMsg =
+                    \result ->
+                        case result of
+                            Ok fun ->
+                                UpdateScrollingNav fun
+
+                            Err _ ->
+                                Idle
+                }
+
+        ( stateless, statelessCmd ) =
+            Stateless.init
+    in
+    ( { stateless = stateless
+      , scrollingNav = scrollingNav
+      , layout = Layout.init
+      , displayDialog = False
+      , window =
+            { width = viewport.width |> round
+            , height = viewport.height |> round
+            }
+      , search =
+            { raw = ""
+            , current = ""
+            , remaining = 0
+            }
+      , theme = Material
+      , expanded = AnySet.empty Example.toString
+      }
+    , [ cmd
+      , statelessCmd |> Cmd.map StatelessSpecific
+      ]
+        |> Cmd.batch
+    )
+
+
+init : () -> ( Model, Cmd Msg )
+init () =
+    ( Loading
+    , Task.perform GotViewport Dom.getViewport
+    )
+
+
+updateLoaded : LoadedMsg -> LoadedModel -> ( LoadedModel, Cmd LoadedMsg )
+updateLoaded msg model =
+    case msg of
+        StatelessSpecific m ->
+            model.stateless
+                |> Stateless.update m
+                |> Tuple.mapBoth
+                    (\stateless ->
+                        { model
+                            | stateless = stateless
+                        }
+                    )
+                    (Cmd.map StatelessSpecific)
+
+        UpdateScrollingNav fun ->
+            ( { model | scrollingNav = model.scrollingNav |> fun }
+            , Cmd.none
+            )
+
+        TimePassed int ->
+            let
+                search =
+                    model.search
+            in
+            ( { model
+                | layout = model.layout |> Layout.timePassed int
+                , search =
+                    if search.remaining > 0 then
+                        if search.remaining <= int then
+                            { search
+                                | current = search.raw
+                                , remaining = 0
+                            }
+
+                        else
+                            { search
+                                | remaining = search.remaining - int
+                            }
+
+                    else
+                        model.search
+              }
+            , ScrollingNav.getPos
+                |> Task.perform UpdateScrollingNav
+            )
+
+        AddSnackbar ( string, bool ) ->
+            ( { model
+                | layout =
+                    model.layout
+                        |> Layout.queueMessage
+                            { text = string
+                            , button =
+                                if bool then
+                                    Just
+                                        { text = "Add"
+                                        , onPress =
+                                            Just <|
+                                                AddSnackbar ( "This is another message", False )
+                                        }
+
+                                else
+                                    Nothing
+                            }
+              }
+            , Cmd.none
+            )
+
+        ToggleDialog bool ->
+            ( { model | displayDialog = bool }
+            , Cmd.none
+            )
+
+        Resized window ->
+            ( { model | window = window }
+            , Cmd.none
+            )
+
+        ChangedSidebar sidebar ->
+            ( { model | layout = model.layout |> Layout.activate sidebar }
+            , Cmd.none
+            )
+
+        Load string ->
+            ( model, Navigation.load string )
+
+        JumpTo section ->
+            ( model
+            , model.scrollingNav
+                |> ScrollingNav.jumpTo
+                    { section = section
+                    , onChange = always Idle
+                    }
+            )
+
+        ChangedSearch string ->
+            let
+                search =
+                    model.search
+            in
+            ( { model
+                | search =
+                    { search
+                        | raw = string
+                        , remaining = 300
+                    }
+              }
+            , Cmd.none
+            )
+
+        SetTheme theme ->
+            ( { model | theme = theme }
+            , Cmd.none
+            )
+
+        ToggledExample example ->
+            ( { model
+                | expanded = model.expanded |> AnySet.toggle example
+              }
+            , Cmd.none
+            )
+
+        Idle ->
+            ( model, Cmd.none )
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case ( model, msg ) of
+        ( Loading, GotViewport viewport ) ->
+            initialModel viewport
+                |> Tuple.mapBoth Loaded (Cmd.map LoadedSpecific)
+
+        ( Loaded state, LoadedSpecific m ) ->
+            updateLoaded m state
+                |> Tuple.mapBoth Loaded (Cmd.map LoadedSpecific)
+
+        _ ->
+            ( model, Cmd.none )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+    Sub.batch
+        [ Time.every 50 (always (TimePassed 50))
+        , Events.onResize (\h w -> Resized { height = h, width = w })
+        ]
+        |> Sub.map LoadedSpecific
+
+
+view : Model -> Html Msg
+view model =
+    case model of
+        Loading ->
+            Element.none |> Framework.responsiveLayout []
+
+        Loaded m ->
+            let
+                style : Style msg
+                style =
+                    Theme.toStyle m.theme
+            in
+            Html.map LoadedSpecific <|
+                Layout.view style.layout
+                    { dialog =
+                        if m.displayDialog then
+                            { text = "This is a dialog window"
+                            , title = Just "Dialog"
+                            , accept =
+                                Just
+                                    { text = "Ok"
+                                    , onPress = Just <| ToggleDialog False
+                                    }
+                            , dismiss =
+                                Just
+                                    { text = "Dismiss"
+                                    , onPress = Just <| ToggleDialog False
+                                    }
+                            }
+                                |> Widget.dialog style.dialog
+                                |> Just
+
+                        else
+                            Nothing
+                    , layout = m.layout
+                    , window = m.window
+                    , menu =
+                        m.scrollingNav
+                            |> ScrollingNav.toSelect
+                                (\int ->
+                                    m.scrollingNav.arrangement
+                                        |> Array.fromList
+                                        |> Array.get int
+                                        |> Maybe.map JumpTo
+                                )
+                    , actions =
+                        [ { onPress = Just <| Load "https://package.elm-lang.org/packages/Orasund/elm-ui-widgets/latest/"
+                          , text = "Docs"
+                          , icon = Icons.book |> Element.html |> Element.el []
+                          }
+                        , { onPress = Just <| Load "https://github.com/Orasund/elm-ui-widgets"
+                          , text = "Github"
+                          , icon = Icons.github |> Element.html |> Element.el []
+                          }
+                        , { onPress =
+                                if m.theme /= Material then
+                                    Just <| SetTheme <| Material
+
+                                else
+                                    Nothing
+                          , text = "Material Theme"
+                          , icon = Icons.penTool |> Element.html |> Element.el []
+                          }
+                        , { onPress =
+                                if m.theme /= DarkMaterial then
+                                    Just <| SetTheme <| DarkMaterial
+
+                                else
+                                    Nothing
+                          , text = "Dark Material Theme"
+                          , icon = Icons.penTool |> Element.html |> Element.el []
+                          }
+                        , { onPress =
+                                if m.theme /= ElmUiFramework then
+                                    Just <| SetTheme <| ElmUiFramework
+
+                                else
+                                    Nothing
+                          , text = "Elm-Ui-Framework Theme"
+                          , icon = Icons.penTool |> Element.html |> Element.el []
+                          }
+                        , { onPress =
+                                if m.theme /= Template then
+                                    Just <| SetTheme <| Template
+
+                                else
+                                    Nothing
+                          , text = "Template Theme"
+                          , icon = Icons.penTool |> Element.html |> Element.el []
+                          }
+                        ]
+                    , onChangedSidebar = ChangedSidebar
+                    , title =
+                        "Elm-Ui-Widgets"
+                            |> Element.text
+                            |> Element.el Heading.h1
+                    , search =
+                        Just
+                            { text = m.search.raw
+                            , onChange = ChangedSearch
+                            , label = "Search"
+                            }
+                    }
+                <|
+                    viewLoaded m
+
+
+viewLoaded : LoadedModel -> Element LoadedMsg
+viewLoaded m =
+    let
+        style : Style msg
+        style =
+            Theme.toStyle m.theme
+    in
+    [ Element.el [ Element.height <| Element.px <| 42 ] <| Element.none
+    , [ StatelessViews, ReusableViews ]
+        |> List.map
+            (\section ->
+                (case section of
+                    ReusableViews ->
+                        Reusable.view
+                            { theme = m.theme
+                            , addSnackbar = AddSnackbar
+                            }
+
+                    StatelessViews ->
+                        Stateless.view
+                            { theme = m.theme
+                            , msgMapper = StatelessSpecific
+                            , model = m.stateless
+                            }
+                )
+                    |> (\{ title, description, items } ->
+                            [ title
+                                |> Element.text
+                                |> Element.el Heading.h2
+                            , if m.search.current == "" then
+                                description
+                                    |> Element.text
+                                    |> List.singleton
+                                    |> Element.paragraph []
+
+                              else
+                                Element.none
+                            , items
+                                |> (if m.search.current /= "" then
+                                        List.filter
+                                            (\( a, _, _ ) ->
+                                                a
+                                                    |> String.toLower
+                                                    |> String.contains (m.search.current |> String.toLower)
+                                            )
+
+                                    else
+                                        identity
+                                   )
+                                |> List.map
+                                    (\( name, elem, more ) ->
+                                        [ [ Element.text name
+                                                |> Element.el
+                                                    (Heading.h3
+                                                        ++ [ Element.height <| Element.shrink
+                                                           , name
+                                                                |> Attributes.id
+                                                                |> Element.htmlAttribute
+                                                           ]
+                                                    )
+                                          , elem
+                                          ]
+                                            |> Element.column Grid.simple
+                                        , 
+                                            Widget.expansionPanel style.expansionPanel
+    
+                                                { onToggle = 
+                                                    always
+                                                    (name
+                                                    |> Example.fromString
+                                                    |> Maybe.map ToggledExample
+                                                    |> Maybe.withDefault Idle
+                                                    )
+                                                , icon = Element.none
+                                                , text =
+                                                    "States"
+                                                , content = more
+                                                , isExpanded =
+                                                    name
+                                                    |> Example.fromString
+                                                    |> Maybe.map
+                                                    (\example ->
+                                                    m.expanded 
+                                                    |> AnySet.member example 
+                                                    )|> Maybe.withDefault False
+                                                    
+
+                                                }
+                                        ]
+                                            |> Widget.column style.cardColumn
+                                    )
+                                |> Element.wrappedRow
+                                    (Grid.simple
+                                        ++ [ Element.height <| Element.shrink
+                                           ]
+                                    )
+                            ]
+                                |> Element.column (Grid.section ++ [ Element.centerX ])
+                       )
+            )
+        |> Element.column (Framework.container ++ style.layout.container)
+    ]
+        |> Element.column Grid.compact
+
+
+main : Program () Model Msg
+main =
+    Browser.element
+        { init = init
+        , view = view
+        , update = update
+        , subscriptions = subscriptions
+        }
diff --git a/example/src/Reusable.elm b/example/src/Reusable.elm
index 0b4a15f..9587b86 100644
--- a/example/src/Reusable.elm
+++ b/example/src/Reusable.elm
@@ -1,163 +1,80 @@
-module Reusable exposing (Model, Msg, init, update, view)
+module Reusable exposing (view)
 
-import Browser
-import Element exposing (Color, Element)
-import Element.Background as Background
-import Element.Font as Font
-import Element.Input as Input
-import Framework
-import Framework.Button as Button
-import Framework.Card as Card
-import Framework.Color as Color
+import Data.Style exposing (Style)
+import Data.Theme as Theme exposing (Theme)
+import Element exposing (Element)
 import Framework.Grid as Grid
-import Framework.Group as Group
-import Framework.Heading as Heading
-import Framework.Input as Input
-import Framework.Tag as Tag
-import Heroicons.Solid as Heroicons
-import Html exposing (Html)
-import Html.Attributes as Attributes
-import Set exposing (Set)
-import Time
 import Widget
-import Widget.FilterSelect as FilterSelect
-import Widget.ScrollingNav as ScrollingNav
-import Widget.Snackbar as Snackbar
-import Widget.SortTable as SortTable
-import Widget.ValidatedInput as ValidatedInput
 
 
-type alias Model =
-    SortTable.Model
+snackbar : Style msg -> (( String, Bool ) -> msg) -> ( String, Element msg, Element msg )
+snackbar style addSnackbar =
+    ( "Snackbar"
+    , [ Widget.button style.button
+            { onPress =
+                Just <|
+                    addSnackbar <|
+                        ( "This is a notification. It will disappear after 10 seconds."
+                        , False
+                        )
+            , text = "Add Notification"
+            , icon = Element.none
+            }
+      , Widget.button style.button
+            { onPress =
+                Just <|
+                    addSnackbar <|
+                        ( "You can add another notification if you want."
+                        , True
+                        )
+            , text = "Add Notification with Action"
+            , icon = Element.none
+            }
+      ]
+        |> Element.column Grid.simple
+    , Element.none
+    )
 
 
-type Msg
-    = SortBy { title : String, asc : Bool }
+scrollingNavCard : Style msg -> ( String, Element msg, Element msg )
+scrollingNavCard _ =
+    ( "Scrolling Nav"
+    , Element.text "Resize the screen and open the side-menu. Then start scrolling to see the scrolling navigation in action."
+        |> List.singleton
+        |> Element.paragraph []
+    , Element.none
+    )
 
 
-type alias Item =
-    { name : String
-    , amount : Int
-    , price : Float
-    }
-
-
-update : Msg -> Model -> Model
-update msg model =
-    case msg of
-        SortBy m ->
-            m
-
-
-init : Model
-init =
-    SortTable.sortBy { title = "Name", asc = True }
-
-
-snackbar : (String -> msg) -> Element msg
-snackbar addSnackbar =
-    [ Element.el Heading.h3 <| Element.text "Snackbar"
-    , Input.button Button.simple
-        { onPress = Just <| addSnackbar "This is a notification. It will disappear after 10 seconds."
-        , label =
-            "Add Notification"
-                |> Element.text
-                |> List.singleton
-                |> Element.paragraph []
-        }
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-sortTable : SortTable.Model -> Element Msg
-sortTable model =
-    [ Element.el Heading.h3 <| Element.text "Sort Table"
-    , SortTable.view
-        { content =
-            [ { id = 1, name = "Antonio", rating = 2.456 }
-            , { id = 2, name = "Ana", rating = 1.34 }
-            , { id = 3, name = "Alfred", rating = 4.22 }
-            , { id = 4, name = "Thomas", rating = 3 }
-            ]
-        , columns =
-            [ SortTable.intColumn
-                { title = "Id"
-                , value = .id
-                , toString = \int -> "#" ++ String.fromInt int
-                }
-            , SortTable.stringColumn
-                { title = "Name"
-                , value = .name
-                , toString = identity
-                }
-            , SortTable.floatColumn
-                { title = "rating"
-                , value = .rating
-                , toString = String.fromFloat
-                }
-            ]
-        , model = model
-        }
-        |> (\{ data, columns } ->
-                { data = data
-                , columns =
-                    columns
-                        |> List.map
-                            (\config ->
-                                { header =
-                                    Input.button [ Font.bold ]
-                                        { onPress =
-                                            { title = config.header
-                                            , asc =
-                                                if config.header == model.title then
-                                                    not model.asc
-
-                                                else
-                                                    True
-                                            }
-                                                |> SortBy
-                                                |> Just
-                                        , label =
-                                            if config.header == model.title then
-                                                [ config.header |> Element.text
-                                                , Element.html <|
-                                                    if model.asc then
-                                                        Heroicons.cheveronUp [ Attributes.width 16 ]
-
-                                                    else
-                                                        Heroicons.cheveronDown [ Attributes.width 16 ]
-                                                ]
-                                                    |> Element.row (Grid.simple ++ [ Font.bold ])
-
-                                            else
-                                                config.header |> Element.text
-                                        }
-                                , view = config.view >> Element.text
-                                , width = Element.fill
-                                }
-                            )
-                }
-           )
-        |> Element.table Grid.simple
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
+layout : Style msg -> ( String, Element msg, Element msg )
+layout _ =
+    ( "Layout"
+    , Element.text "The layout combines the menu bar, both side bar, the dialog window and the snackbar. Try using all of them and also try resizing the window to see how they interact with each other."
+        |> List.singleton
+        |> Element.paragraph []
+    , Element.none
+    )
 
 
 view :
-    { addSnackbar : String -> msg
-    , msgMapper : Msg -> msg
-    , model : Model
+    { theme : Theme
+    , addSnackbar : ( String, Bool ) -> msg
     }
-    -> Element msg
-view { addSnackbar, msgMapper, model } =
-    Element.column (Grid.section ++ [ Element.centerX ])
-        [ Element.el Heading.h2 <| Element.text "Reusable Views"
-        , "Reusable views have an internal state but no update function. You will need to do some wiring, but nothing complicated."
-            |> Element.text
-            |> List.singleton
-            |> Element.paragraph []
-        , Element.wrappedRow (Grid.simple ++ [Element.height <| Element.shrink]) <|
-            [ snackbar addSnackbar
-            , sortTable model |> Element.map msgMapper
-            ]
+    ->
+        { title : String
+        , description : String
+        , items : List ( String, Element msg, Element msg )
+        }
+view { theme, addSnackbar } =
+    let
+        style =
+            Theme.toStyle theme
+    in
+    { title = "Reusable Views"
+    , description = "Reusable views have an internal state but no update function. You will need to do some wiring, but nothing complicated."
+    , items =
+        [ snackbar style addSnackbar
+        , scrollingNavCard style
+        , layout style
         ]
+    }
diff --git a/example/src/Stateless.elm b/example/src/Stateless.elm
index b3334ad..65d4b30 100644
--- a/example/src/Stateless.elm
+++ b/example/src/Stateless.elm
@@ -1,326 +1,73 @@
 module Stateless exposing (Model, Msg, init, update, view)
 
-import Array exposing (Array)
+import Data.Example as Example
+import Data.Theme as Theme exposing (Theme)
 import Element exposing (Element)
-import Element.Background as Background
-import Element.Border as Border
-import Element.Input as Input
-import Framework.Button as Button
-import Framework.Card as Card
-import Framework.Color as Color
-import Framework.Grid as Grid
-import Framework.Group as Group
-import Framework.Heading as Heading
-import Framework.Input as Input
-import Framework.Tag as Tag
-import Heroicons.Solid as Heroicons
-import Html exposing (Html)
-import Html.Attributes as Attributes
-import Set exposing (Set)
-import Widget
-import Layout exposing (Direction(..))
+import Widget.Layout exposing (Part(..))
 
 
 type alias Model =
-    { selected : Maybe Int
-    , multiSelected : Set Int
-    , isCollapsed : Bool
-    , carousel : Int
-    , tab : Int
+    { carousel : Int
+    , example : Example.Model
     }
 
 
 type Msg
-    = ChangedSelected Int
-    | ChangedMultiSelected Int
-    | ToggleCollapsable Bool
-    | ChangedTab Int
-    | SetCarousel Int
+    = ExampleSpecific Example.Msg
+    | Idle
 
 
-init : Model
+init : ( Model, Cmd Msg )
 init =
-    { selected = Nothing
-    , multiSelected = Set.empty
-    , isCollapsed = False
-    , carousel = 0
-    , tab = 1
-    }
+    let
+        ( example, cmd ) =
+            Example.init
+    in
+    ( { carousel = 0
+      , example = example
+      }
+    , cmd |> Cmd.map ExampleSpecific
+    )
 
 
 update : Msg -> Model -> ( Model, Cmd Msg )
 update msg model =
     case msg of
-        ChangedSelected int ->
-            ( { model
-                | selected = Just int
-              }
-            , Cmd.none
+        ExampleSpecific exampleMsg ->
+            let
+                ( exampleModel, exampleCmd ) =
+                    Example.update exampleMsg model.example
+            in
+            ( { model | example = exampleModel }
+            , exampleCmd |> Cmd.map ExampleSpecific
             )
 
-        ChangedMultiSelected int ->
-            ( { model
-                | multiSelected =
-                    model.multiSelected
-                        |> (if model.multiSelected |> Set.member int then
-                                Set.remove int
-
-                            else
-                                Set.insert int
-                           )
-              }
-            , Cmd.none
-            )
-
-        ToggleCollapsable bool ->
-            ( { model
-                | isCollapsed = bool
-              }
-            , Cmd.none
-            )
-
-        SetCarousel int ->
-            ( if (int < 0) || (int > 3) then
-                model
-
-              else
-                { model
-                    | carousel = int
-                }
-            , Cmd.none
-            )
-
-        ChangedTab int ->
-            ( { model | tab = int }, Cmd.none )
+        Idle ->
+            ( model, Cmd.none )
 
 
-select : Model -> Element Msg
-select model =
-    [ Element.el Heading.h3 <| Element.text "Select"
-    , Widget.select
-        { selected = model.selected
-        , options = [ 1, 2, 42 ]
-        , label = String.fromInt >> Element.text
-        , onChange = ChangedSelected
-        , attributes =
-            \selected ->
-                Button.simple
-                    ++ [ Border.width 0
-                       , Border.rounded 0
-                       ]
-                    ++ (if selected then
-                            Color.primary
-
-                        else
-                            []
-                       )
+view :
+    { theme : Theme
+    , msgMapper : Msg -> msg
+    , model : Model
+    }
+    ->
+        { title : String
+        , description : String
+        , items : List ( String, Element msg, Element msg )
         }
-        |> List.indexedMap
-            (\i ->
-                Element.el
-                    (Button.simple
-                        ++ [ Element.padding <| 0 ]
-                        ++ (if i == 0 then
-                                Group.left
-
-                            else if i == 2 then
-                                Group.right
-
-                            else
-                                Group.center
-                           )
-                    )
-            )
-        |> Element.row Grid.compact
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-multiSelect : Model -> Element Msg
-multiSelect model =
-    [ Element.el Heading.h3 <| Element.text "Multi Select"
-    , Widget.multiSelect
-        { selected = model.multiSelected
-        , options = [ 1, 2, 42 ]
-        , label = String.fromInt >> Element.text
-        , onChange = ChangedMultiSelected
-        , attributes =
-            \selected ->
-                Button.simple
-                    ++ [ Border.width 0
-                       , Border.rounded 0
-                       ]
-                    ++ (if selected then
-                            Color.primary
-
-                        else
-                            []
-                       )
-        }
-        |> List.indexedMap
-            (\i ->
-                Element.el
-                    (Button.simple
-                        ++ [ Element.padding <| 0 ]
-                        ++ (if i == 0 then
-                                Group.left
-
-                            else if i == 2 then
-                                Group.right
-
-                            else
-                                Group.center
-                           )
-                    )
-            )
-        |> Element.row Grid.compact
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-collapsable : Model -> Element Msg
-collapsable model =
-    [ Element.el Heading.h3 <| Element.text "Collapsable"
-    , Widget.collapsable
-        { onToggle = ToggleCollapsable
-        , isCollapsed = model.isCollapsed
-        , label =
-            Element.row Grid.compact
-                [ Element.html <|
-                    if model.isCollapsed then
-                        Heroicons.cheveronRight [ Attributes.width 20 ]
-
-                    else
-                        Heroicons.cheveronDown [ Attributes.width 20 ]
-                , Element.el Heading.h4 <| Element.text <| "Title"
-                ]
-        , content = Element.text <| "Hello World"
-        }
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-tab : Model -> Element Msg
-tab model =
-    [ Element.el Heading.h3 <| Element.text "Tab"
-    , Widget.tab Grid.simple
-        { selected = model.tab
-        , options = [ 1, 2, 3 ]
-        , onChange = ChangedTab
-        , label = \int -> "Tab " ++ String.fromInt int |> Element.text
-        , content =
-            \selected ->
-                (case selected of
-                    1 ->
-                        "This is Tab 1"
-
-                    2 ->
-                        "This is the second tab"
-
-                    3 ->
-                        "The thrid and last tab"
-
-                    _ ->
-                        "Please select a tab"
-                )
-                    |> Element.text
-                    |> Element.el (Card.small ++ Group.bottom)
-        , attributes =
-            \selected ->
-                Button.simple
-                    ++ Group.top
-                    ++ (if selected then
-                            Color.primary
-
-                        else
-                            []
-                       )
-        }
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-scrim :
-    { showDialog : msg
-    , changedSheet : Maybe Direction -> msg
-    } -> Model -> Element msg
-scrim {showDialog,changedSheet} model =
-    [ Element.el Heading.h3 <| Element.text "Scrim"
-    , Input.button Button.simple
-        { onPress = Just showDialog
-        , label = Element.text <| "Show dialog"
-        }
-    , Input.button Button.simple
-        { onPress = Just <| changedSheet <| Just Left
-        , label = Element.text <| "show left sheet"
-        }
-    ,  Input.button Button.simple
-        { onPress = Just <| changedSheet <| Just Right
-        , label = Element.text <| "show right sheet"
-        }
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-carousel : Model -> Element Msg
-carousel model =
-    [ Element.el Heading.h3 <| Element.text "Carousel"
-    , Widget.carousel
-        { content = ( Color.cyan, [ Color.yellow, Color.green, Color.red ] |> Array.fromList )
-        , current = model.carousel
-        , label =
-            \c ->
-                [ Input.button [ Element.centerY ]
-                    { onPress = Just <| SetCarousel <| model.carousel - 1
-                    , label =
-                        Heroicons.cheveronLeft [ Attributes.width 20 ]
-                            |> Element.html
-                    }
-                , Element.el
-                    (Card.simple
-                        ++ [ Background.color <| c
-                           , Element.height <| Element.px <| 100
-                           , Element.width <| Element.px <| 100
-                           ]
-                    )
-                  <|
-                    Element.none
-                , Input.button [ Element.centerY ]
-                    { onPress = Just <| SetCarousel <| model.carousel + 1
-                    , label =
-                        Heroicons.cheveronRight [ Attributes.width 20 ]
-                            |> Element.html
-                    }
-                ]
-                    |> Element.row (Grid.simple ++ [ Element.centerX, Element.width <| Element.shrink ])
-        }
-    ]
-        |> Element.column (Grid.simple ++ Card.large ++ [Element.height <| Element.fill])
-
-
-view : 
-    { msgMapper : Msg -> msg
-    , showDialog : msg
-    , changedSheet : Maybe Direction -> msg
-    } -> Model -> Element msg
-view { msgMapper, showDialog, changedSheet } model =
-    Element.column (Grid.section )
-        [ Element.el Heading.h2 <| Element.text "Stateless Views"
-        , "Stateless views are simple functions that view some content. No wiring required."
-            |> Element.text
-            |> List.singleton
-            |> Element.paragraph []
-        , Element.wrappedRow
-            (Grid.simple ++ [Element.height <| Element.shrink])
-          <|
-            [ select model |> Element.map msgMapper
-            , multiSelect model |> Element.map msgMapper
-            , collapsable model |> Element.map msgMapper
-            , scrim
-                { showDialog = showDialog
-                , changedSheet = changedSheet
-                } model
-            , carousel model |> Element.map msgMapper
-            , tab model |> Element.map msgMapper
-            ]
-        ]
+view { theme, msgMapper, model } =
+    let
+        style =
+            Theme.toStyle theme
+    in
+    { title = "Stateless Views"
+    , description = "Stateless views are simple functions that view some content. No wiring required."
+    , items =
+        Example.toCardList
+            { idle = Idle |> msgMapper
+            , msgMapper = ExampleSpecific >> msgMapper
+            , style = style
+            , model = model.example
+            }
+    }
diff --git a/example/src/View/Test.elm b/example/src/View/Test.elm
new file mode 100644
index 0000000..8055f07
--- /dev/null
+++ b/example/src/View/Test.elm
@@ -0,0 +1,513 @@
+module View.Test exposing (button, dialog, expansionPanel, list, modal, multiSelect, select, sortTable, tab, textInput)
+
+import Data.Style exposing (Style)
+import Element exposing (Element)
+import Icons
+import Set
+import Widget
+import Widget.Layout exposing (Part(..))
+
+
+button : msg -> Style msg -> List ( String, Element msg )
+button idle style =
+    [ ( "Button"
+      , Widget.button style.button
+            { text = "Button"
+            , icon = Icons.triangle |> Element.html |> Element.el []
+            , onPress = Just idle
+            }
+      )
+    , ( "Text button"
+      , Widget.textButton style.button
+            { text = "Button"
+            , onPress = Just idle
+            }
+      )
+    , ( "Icon button"
+      , Widget.iconButton style.button
+            { text = "Button"
+            , icon = Icons.triangle |> Element.html |> Element.el []
+            , onPress = Just idle
+            }
+      )
+    , ( "Disabled button"
+      , Widget.button style.button
+            { text = "Button"
+            , icon = Icons.triangle |> Element.html |> Element.el []
+            , onPress = Nothing
+            }
+      )
+    , ( "Inactive Select button"
+      , Widget.selectButton style.button
+            ( False
+            , { text = "Button"
+              , icon = Icons.triangle |> Element.html |> Element.el []
+              , onPress = Just idle
+              }
+            )
+      )
+    , ( "Active Select button"
+      , Widget.selectButton style.button
+            ( True
+            , { text = "Button"
+              , icon = Icons.triangle |> Element.html |> Element.el []
+              , onPress = Just idle
+              }
+            )
+      )
+    ]
+
+
+select : msg -> Style msg -> List ( String, Element msg )
+select idle style =
+    [ ( "First selected"
+      , { selected = Just 0
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.select
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Nothing selected"
+      , { selected = Nothing
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.select
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Invalid selection"
+      , { selected = Just -1
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.select
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Disabled selection"
+      , { selected = Just 0
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always Nothing
+        }
+            |> Widget.select
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Empty Options"
+      , { selected = Nothing
+        , options =
+            []
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.select
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    ]
+
+
+multiSelect : msg -> Style msg -> List ( String, Element msg )
+multiSelect idle style =
+    [ ( "Some selected"
+      , { selected = Set.fromList [ 0, 1 ]
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.multiSelect
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Nothing selected"
+      , { selected = Set.empty
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.multiSelect
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Invalid selection"
+      , { selected = Set.singleton -1
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.multiSelect
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Disabled selection"
+      , { selected = Set.singleton 0
+        , options =
+            [ 1, 2, 42 ]
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always Nothing
+        }
+            |> Widget.multiSelect
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    , ( "Empty Options"
+      , { selected = Set.empty
+        , options =
+            []
+                |> List.map
+                    (\int ->
+                        { text = String.fromInt int
+                        , icon = Element.none
+                        }
+                    )
+        , onSelect = always idle >> Just
+        }
+            |> Widget.multiSelect
+            |> Widget.buttonRow
+                { list = style.buttonRow
+                , button = style.selectButton
+                }
+      )
+    ]
+
+
+expansionPanel : msg -> Style msg -> List ( String, Element msg )
+expansionPanel idle style =
+    [ ( "Collapsed"
+      , { onToggle = always idle
+        , isExpanded = False
+        , icon = Icons.triangle |> Element.html |> Element.el []
+        , text = "Button"
+        , content = Element.text <| "Hidden Message"
+        }
+            |> Widget.expansionPanel style.expansionPanel
+      )
+    , ( "Expanded"
+      , { onToggle = always idle
+        , isExpanded = True
+        , icon = Icons.triangle |> Element.html |> Element.el []
+        , text = "Button"
+        , content = Element.text <| "Hidden Message"
+        }
+            |> Widget.expansionPanel style.expansionPanel
+      )
+    ]
+
+
+tab : msg -> Style msg -> List ( String, Element msg )
+tab idle style =
+    [ ( "Nothing selected"
+      , Widget.tab style.tab
+            { tabs =
+                { selected = Nothing
+                , options =
+                    [ 1, 2, 3 ]
+                        |> List.map
+                            (\int ->
+                                { text = int |> String.fromInt
+                                , icon = Element.none
+                                }
+                            )
+                , onSelect = always idle >> Just
+                }
+            , content =
+                \selected ->
+                    (case selected of
+                        Nothing ->
+                            "Please select a tab"
+
+                        _ ->
+                            ""
+                    )
+                        |> Element.text
+            }
+      )
+    , ( "Tab selected"
+      , Widget.tab style.tab
+            { tabs =
+                { selected = Just 0
+                , options =
+                    [ 1, 2, 3 ]
+                        |> List.map
+                            (\int ->
+                                { text = int |> String.fromInt
+                                , icon = Element.none
+                                }
+                            )
+                , onSelect = always idle >> Just
+                }
+            , content =
+                \selected ->
+                    (case selected of
+                        Just 0 ->
+                            "First Tab selected"
+
+                        _ ->
+                            "Please select a tab"
+                    )
+                        |> Element.text
+            }
+      )
+    ]
+
+
+sortTable : msg -> Style msg -> List ( String, Element msg )
+sortTable idle style =
+    [ ( "Int column"
+      , Widget.sortTable style.sortTable
+            { content =
+                [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
+                , { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
+                ]
+            , columns =
+                [ Widget.intColumn
+                    { title = "Id"
+                    , value = .id
+                    , toString = \int -> "#" ++ String.fromInt int
+                    , width = Element.fill
+                    }
+                , Widget.stringColumn
+                    { title = "Name"
+                    , value = .name
+                    , toString = identity
+                    , width = Element.fill
+                    }
+                ]
+            , asc = True
+            , sortBy = "Id"
+            , onChange = always idle
+            }
+      )
+    , ( "Name column"
+      , Widget.sortTable style.sortTable
+            { content =
+                [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
+                , { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
+                ]
+            , columns =
+                [ Widget.stringColumn
+                    { title = "Name"
+                    , value = .name
+                    , toString = identity
+                    , width = Element.fill
+                    }
+                , Widget.floatColumn
+                    { title = "Rating"
+                    , value = .rating
+                    , toString = String.fromFloat
+                    , width = Element.fill
+                    }
+                ]
+            , asc = True
+            , sortBy = "Name"
+            , onChange = always idle
+            }
+      )
+    , ( "Float column"
+      , Widget.sortTable style.sortTable
+            { content =
+                [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
+                , { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
+                ]
+            , columns =
+                [ Widget.floatColumn
+                    { title = "Rating"
+                    , value = .rating
+                    , toString = String.fromFloat
+                    , width = Element.fill
+                    }
+                , Widget.unsortableColumn
+                    { title = "Hash"
+                    , toString = .hash >> Maybe.withDefault "None"
+                    , width = Element.fill
+                    }
+                ]
+            , asc = False
+            , sortBy = "Rating"
+            , onChange = always idle
+            }
+      )
+    , ( "Unsortable column"
+      , Widget.sortTable style.sortTable
+            { content =
+                [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
+                , { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
+                ]
+            , columns =
+                [ Widget.floatColumn
+                    { title = "Rating"
+                    , value = .rating
+                    , toString = String.fromFloat
+                    , width = Element.fill
+                    }
+                , Widget.unsortableColumn
+                    { title = "Hash"
+                    , toString = .hash >> Maybe.withDefault "None"
+                    , width = Element.fill
+                    }
+                ]
+            , asc = True
+            , sortBy = "Hash"
+            , onChange = always idle
+            }
+      )
+    , ( "Empty Table"
+      , Widget.sortTable style.sortTable
+            { content =
+                [ { id = 1, name = "Antonio", rating = 2.456, hash = Nothing }
+                , { id = 2, name = "Ana", rating = 1.34, hash = Just "45jf" }
+                ]
+            , columns = []
+            , asc = True
+            , sortBy = ""
+            , onChange = always idle
+            }
+      )
+    ]
+
+
+modal : msg -> Style msg -> List ( String, Element msg )
+modal _ _ =
+    []
+
+
+dialog : msg -> Style msg -> List ( String, Element msg )
+dialog _ _ =
+    []
+
+
+textInput : msg -> Style msg -> List ( String, Element msg )
+textInput idle style =
+    [ ( "Nothing Selected"
+      , { chips = []
+        , text = ""
+        , placeholder = Nothing
+        , label = "Label"
+        , onChange = always idle
+        }
+            |> Widget.textInput style.textInput
+      )
+    , ( "Some chips"
+      , { chips =
+            [ { icon = Icons.triangle |> Element.html |> Element.el []
+              , text = "A"
+              , onPress = Just idle
+              }
+            , { icon = Icons.circle |> Element.html |> Element.el []
+              , text = "B"
+              , onPress = Just idle
+              }
+            ]
+        , text = ""
+        , placeholder = Nothing
+        , label = "Label"
+        , onChange = always idle
+        }
+            |> Widget.textInput style.textInput
+      )
+    ]
+
+
+list : msg -> Style msg -> List ( String, Element msg )
+list _ style =
+    [ ( "Row"
+      , [ Element.text "A"
+        , Element.text "B"
+        , Element.text "C"
+        ]
+            |> Widget.row style.row
+      )
+    , ( "Column"
+      , [ Element.text "A"
+        , Element.text "B"
+        , Element.text "C"
+        ]
+            |> Widget.column style.cardColumn
+      )
+    , ( "Singleton List"
+      , [ Element.text "A"
+        ]
+            |> Widget.column style.cardColumn
+      )
+    , ( "Empty List"
+      , []
+            |> Widget.column style.cardColumn
+      )
+    ]
diff --git a/src/Core/Style.elm b/src/Core/Style.elm
deleted file mode 100644
index e2d07a6..0000000
--- a/src/Core/Style.elm
+++ /dev/null
@@ -1,100 +0,0 @@
-module Core.Style exposing (Style,menuTabButtonSelected,menuTabButton, menuButton, menuButtonSelected, menuIconButton, sheetButton, sheetButtonSelected)
-
-import Element exposing (Attribute, Element)
-import Element.Input as Input
-import Html exposing (Html)
-
-
-type alias Style msg =
-    { snackbar : List (Attribute msg)
-    , layout : List (Attribute msg) -> Element msg -> Html msg
-    , header : List (Attribute msg)
-    , sheet : List (Attribute msg)
-    , menuButton : List (Attribute msg)
-    , menuButtonSelected : List (Attribute msg)
-    , sheetButton : List (Attribute msg)
-    , sheetButtonSelected : List (Attribute msg)
-    , tabButton : List (Attribute msg)
-    , tabButtonSelected : List (Attribute msg)
-    , menuIcon : Element Never
-    , moreVerticalIcon : Element Never
-    , spacing : Int
-    }
-
-
-menuButtonSelected : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-menuButtonSelected config { label, icon, onPress } =
-    Input.button (config.menuButton ++ config.menuButtonSelected)
-        { onPress = onPress
-        , label =
-            Element.row [ Element.spacing 8 ]
-                [ icon |> Element.map never
-                , Element.text label
-                ]
-        }
-
-
-menuButton : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-menuButton config { label, icon, onPress } =
-    Input.button config.menuButton
-        { onPress = onPress
-        , label =
-            Element.row [ Element.spacing 8 ]
-                [ icon |> Element.map never
-                , Element.text label
-                ]
-        }
-
-
-menuIconButton : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-menuIconButton config { label, icon, onPress } =
-    Input.button config.menuButton
-        { onPress = onPress
-        , label = icon |> Element.map never
-        }
-
-
-sheetButton : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-sheetButton config { label, icon, onPress } =
-    Input.button config.sheetButton
-        { onPress = onPress
-        , label =
-            Element.row [ Element.spacing 8 ]
-                [ icon |> Element.map never
-                , Element.text label
-                ]
-        }
-
-
-sheetButtonSelected : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-sheetButtonSelected config { label, icon, onPress } =
-    Input.button (config.sheetButton ++ config.sheetButtonSelected)
-        { onPress = onPress
-        , label =
-            Element.row [ Element.spacing 8 ]
-                [ icon |> Element.map never
-                , Element.text label
-                ]
-        }
-
-menuTabButton : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-menuTabButton config { label, icon, onPress } =
-    Input.button (config.menuButton ++ config.tabButton)
-        { onPress = onPress
-        , label =
-            Element.row [ Element.spacing 8 ]
-                [ icon |> Element.map never
-                , Element.text label
-                ]
-        }
-
-menuTabButtonSelected : Style msg -> { label : String, icon : Element Never, onPress : Maybe msg } -> Element msg
-menuTabButtonSelected config { label, icon, onPress } =
-    Input.button (config.menuButton ++ config.tabButton ++ config.tabButtonSelected)
-        { onPress = onPress
-        , label =
-            Element.row [ Element.spacing 8 ]
-                [ icon |> Element.map never
-                , Element.text label
-                ]
-        }
\ No newline at end of file
diff --git a/src/Core/Utillity.elm b/src/Core/Utillity.elm
deleted file mode 100644
index 2aee893..0000000
--- a/src/Core/Utillity.elm
+++ /dev/null
@@ -1,30 +0,0 @@
-module Core.Utillity exposing (responsiveLayout)
-
-import Element exposing (Attribute, Element)
-import Html exposing (Html)
-import Html.Attributes as Attributes
-
-
-{-| taken from Orasund/elm-ui-framework
--}
-layout : List (Attribute msg) -> Element msg -> Html msg
-layout attributes =
-    Element.layoutWith
-        { options = layoutOptions
-        }
-        (layoutAttributes ++ attributes)
-
-
-{-| taken from Orasund/elm-ui-framework
--}
-responsiveLayout : List (Attribute msg) -> Element msg -> Html msg
-responsiveLayout attributes view =
-    Html.div []
-        [ Html.node "meta"
-            [ Attributes.attribute "name" "viewport"
-            , Attributes.attribute "content" "width=device-width, initial-scale=1.0"
-            ]
-            []
-        , layout attributes <|
-            view
-        ]
diff --git a/src/Internal/Button.elm b/src/Internal/Button.elm
new file mode 100644
index 0000000..981b19b
--- /dev/null
+++ b/src/Internal/Button.elm
@@ -0,0 +1,76 @@
+module Internal.Button exposing
+    ( Button
+    , TextButton
+    , button
+    , iconButton
+    , textButton
+    )
+
+import Element exposing (Element)
+import Element.Input as Input
+import Element.Region as Region
+import Widget.Style exposing (ButtonStyle)
+
+
+type alias Button msg =
+    { text : String
+    , onPress : Maybe msg
+    , icon : Element Never
+    }
+
+
+type alias TextButton msg =
+    { text : String
+    , onPress : Maybe msg
+    }
+
+
+iconButton : ButtonStyle msg -> Button msg -> Element msg
+iconButton style { onPress, text, icon } =
+    Input.button
+        (style.container
+            ++ (if onPress == Nothing then
+                    style.ifDisabled
+
+                else
+                    style.otherwise
+               )
+            ++ [ Region.description text ]
+        )
+        { onPress = onPress
+        , label =
+            icon |> Element.map never |> Element.el style.labelRow
+        }
+
+
+textButton : ButtonStyle msg -> TextButton msg -> Element msg
+textButton style { onPress, text } =
+    button style
+        { onPress = onPress
+        , text = text
+        , icon = Element.none
+        }
+
+
+button :
+    ButtonStyle msg
+    -> Button msg
+    -> Element msg
+button style { onPress, text, icon } =
+    Input.button
+        (style.container
+            ++ (if onPress == Nothing then
+                    style.ifDisabled
+
+                else
+                    style.otherwise
+               )
+        )
+        { onPress = onPress
+        , label =
+            Element.row style.labelRow
+                [ icon |> Element.map never
+                , Element.text text |> Element.el style.text
+                ]
+        }
+        
diff --git a/src/Internal/Dialog.elm b/src/Internal/Dialog.elm
new file mode 100644
index 0000000..8470820
--- /dev/null
+++ b/src/Internal/Dialog.elm
@@ -0,0 +1,93 @@
+module Internal.Dialog exposing (Dialog, dialog, modal)
+
+import Element exposing (Attribute, Element)
+import Element.Background as Background
+import Element.Events as Events
+import Internal.Button as Button exposing (TextButton)
+import Widget.Style exposing (DialogStyle)
+
+
+type alias Dialog msg =
+    { title : Maybe String
+    , text : String
+    , accept : Maybe (TextButton msg)
+    , dismiss : Maybe (TextButton msg)
+    }
+
+
+modal : { onDismiss : Maybe msg, content : Element msg } -> List (Attribute msg)
+modal { onDismiss, content } =
+    [ Element.none
+        |> Element.el
+            ([ Element.width <| Element.fill
+             , Element.height <| Element.fill
+             , Background.color <| Element.rgba255 0 0 0 0.5
+             ]
+                ++ (onDismiss
+                        |> Maybe.map (Events.onClick >> List.singleton)
+                        |> Maybe.withDefault []
+                   )
+            )
+        |> Element.inFront
+    , content |> Element.inFront
+    , Element.clip
+    ]
+
+
+dialog :
+    DialogStyle msg
+    -> Dialog msg
+    -> List (Attribute msg)
+dialog style { title, text, accept, dismiss } =
+    { onDismiss =
+        case ( accept, dismiss ) of
+            ( Nothing, Nothing ) ->
+                Nothing
+
+            ( Nothing, Just { onPress } ) ->
+                onPress
+
+            ( Just _, _ ) ->
+                Nothing
+    , content =
+        Element.column
+            ([ Element.centerX
+             , Element.centerY
+             ]
+                ++ style.containerColumn
+            )
+            [ title
+                |> Maybe.map
+                    (Element.text
+                        >> Element.el style.title
+                    )
+                |> Maybe.withDefault Element.none
+            , text
+                |> Element.text
+                |> List.singleton
+                |> Element.paragraph style.text
+            , Element.row
+                ([ Element.alignRight
+                 , Element.width <| Element.shrink
+                 ]
+                    ++ style.buttonRow
+                )
+                (case ( accept, dismiss ) of
+                    ( Just acceptButton, Nothing ) ->
+                        acceptButton
+                            |> Button.textButton style.acceptButton
+                            |> List.singleton
+
+                    ( Just acceptButton, Just dismissButton ) ->
+                        [ dismissButton
+                            |> Button.textButton style.dismissButton
+                        , acceptButton
+                            |> Button.textButton style.acceptButton
+                        ]
+
+                    _ ->
+                        []
+                )
+            ]
+    }
+        |> modal
diff --git a/src/Internal/ExpansionPanel.elm b/src/Internal/ExpansionPanel.elm
new file mode 100644
index 0000000..d8f7a1b
--- /dev/null
+++ b/src/Internal/ExpansionPanel.elm
@@ -0,0 +1,46 @@
+module Internal.ExpansionPanel exposing (ExpansionPanel, expansionPanel)
+
+{-| Part of Material Design Lists
+-}
+
+import Element exposing (Element)
+import Element.Events as Events
+import Widget.Style exposing (ExpansionPanelStyle)
+
+
+type alias ExpansionPanel msg =
+    { onToggle : Bool -> msg
+    , icon : Element Never
+    , text : String
+    , content : Element msg
+    , isExpanded : Bool
+    }
+
+
+expansionPanel :
+    ExpansionPanelStyle msg
+    -> ExpansionPanel msg
+    -> Element msg
+expansionPanel style model =
+    Element.column style.containerColumn <|
+        [ Element.row
+            ((Events.onClick <| model.onToggle <| not model.isExpanded)
+                :: style.panelRow
+            )
+            [ Element.row style.labelRow
+                [ model.icon |> Element.map never
+                , model.text |> Element.text
+                ]
+            , Element.map never <|
+                if model.isExpanded then
+                    style.collapseIcon
+
+                else
+                    style.expandIcon
+            ]
+        , if model.isExpanded then
+            Element.el style.content <| model.content
+
+          else
+            Element.none
+        ]
diff --git a/src/Internal/List.elm b/src/Internal/List.elm
new file mode 100644
index 0000000..74ade97
--- /dev/null
+++ b/src/Internal/List.elm
@@ -0,0 +1,114 @@
+module Internal.List exposing (buttonColumn, buttonRow, column, row)
+
+import Element exposing (Attribute, Element)
+import Internal.Button exposing (Button)
+import Internal.Select as Select
+import Widget.Style exposing (ButtonStyle, ColumnStyle, RowStyle)
+
+
+internal :
+    { list
+        | element : List (Attribute msg)
+        , ifFirst : List (Attribute msg)
+        , ifLast : List (Attribute msg)
+        , otherwise : List (Attribute msg)
+    }
+    -> List (Element msg)
+    -> List (Element msg)
+internal style list =
+    list
+        |> List.indexedMap
+            (\i ->
+                Element.el <|
+                    style.element
+                        ++ (if List.length list == 1 then
+                                []
+
+                            else if i == 0 then
+                                style.ifFirst
+
+                            else if i == (List.length list - 1) then
+                                style.ifLast
+
+                            else
+                                style.otherwise
+                           )
+            )
+
+
+row : RowStyle msg -> List (Element msg) -> Element msg
+row style =
+    internal style >> Element.row style.containerRow
+
+
+column : ColumnStyle msg -> List (Element msg) -> Element msg
+column style =
+    internal style >> Element.column style.containerColumn
+
+
+internalButton :
+    { list :
+        { list
+            | element : List (Attribute msg)
+            , ifFirst : List (Attribute msg)
+            , ifLast : List (Attribute msg)
+            , otherwise : List (Attribute msg)
+        }
+    , button : ButtonStyle msg
+    }
+    -> List ( Bool, Button msg )
+    -> List (Element msg)
+internalButton style list =
+    list
+        |> List.indexedMap
+            (\i ->
+                Select.selectButton
+                    { container =
+                        style.button.container
+                            ++ style.list.element
+                            ++ (if List.length list == 1 then
+                                    []
+
+                                else if i == 0 then
+                                    style.list.ifFirst
+
+                                else if i == (List.length list - 1) then
+                                    style.list.ifLast
+
+                                else
+                                    style.list.otherwise
+                               )
+                    , labelRow =
+                        style.button.labelRow
+                    , text =
+                        style.button.text
+                    , ifDisabled =
+                        style.button.ifDisabled
+                    , ifActive =
+                        style.button.ifActive
+                    , otherwise =
+                        style.button.otherwise
+                    }
+                    --Workaround for https://github.com/mdgriffith/elm-ui/issues/47
+                    >> Element.el []
+            )
+
+
+buttonRow :
+    { list : RowStyle msg
+    , button : ButtonStyle msg
+    }
+    -> List ( Bool, Button msg )
+    -> Element msg
+buttonRow style =
+    internalButton style >> Element.row style.list.containerRow
+
+
+buttonColumn :
+    { list : ColumnStyle msg
+    , button : ButtonStyle msg
+    }
+    -> List ( Bool, Button msg )
+    -> Element msg
+buttonColumn style =
+    internalButton style >> Element.column style.list.containerColumn
diff --git a/src/Internal/Select.elm b/src/Internal/Select.elm
new file mode 100644
index 0000000..e0e4375
--- /dev/null
+++ b/src/Internal/Select.elm
@@ -0,0 +1,87 @@
+module Internal.Select exposing (MultiSelect, Select, multiSelect, select, selectButton)
+
+import Element exposing (Element)
+import Element.Input as Input
+import Internal.Button exposing (Button)
+import Set exposing (Set)
+import Widget.Style exposing (ButtonStyle)
+
+
+type alias Select msg =
+    { selected : Maybe Int
+    , options :
+        List
+            { text : String
+            , icon : Element Never
+            }
+    , onSelect : Int -> Maybe msg
+    }
+
+
+type alias MultiSelect msg =
+    { selected : Set Int
+    , options :
+        List
+            { text : String
+            , icon : Element Never
+            }
+    , onSelect : Int -> Maybe msg
+    }
+
+
+selectButton :
+    ButtonStyle msg
+    -> ( Bool, Button msg )
+    -> Element msg
+selectButton style ( selected, b ) =
+    Input.button
+        (style.container
+            ++ (if b.onPress == Nothing then
+                    style.ifDisabled
+
+                else if selected then
+                    style.ifActive
+
+                else
+                    style.otherwise
+               )
+        )
+        { onPress = b.onPress
+        , label =
+            Element.row style.labelRow
+                [ b.icon |> Element.map never
+                , Element.text b.text |> Element.el style.text
+                ]
+        }
+
+
+select :
+    Select msg
+    -> List ( Bool, Button msg )
+select { selected, options, onSelect } =
+    options
+        |> List.indexedMap
+            (\i a ->
+                ( selected == Just i
+                , { onPress = i |> onSelect
+                  , text = a.text
+                  , icon = a.icon
+                  }
+                )
+            )
+
+
+multiSelect :
+    MultiSelect msg
+    -> List ( Bool, Button msg )
+multiSelect { selected, options, onSelect } =
+    options
+        |> List.indexedMap
+            (\i a ->
+                ( selected |> Set.member i
+                , { onPress = i |> onSelect
+                  , text = a.text
+                  , icon = a.icon
+                  }
+                )
+            )
diff --git a/src/Internal/SortTable.elm b/src/Internal/SortTable.elm
new file mode 100644
index 0000000..e2e41c1
--- /dev/null
+++ b/src/Internal/SortTable.elm
@@ -0,0 +1,181 @@
+module Internal.SortTable exposing
+    ( Column
+    , ColumnType
+    , SortTable
+    , floatColumn
+    , intColumn
+    , sortTable
+    , stringColumn
+    , unsortableColumn
+    )
+
+import Element exposing (Element, Length)
+import Internal.Button as Button
+import Widget.Style exposing (SortTableStyle)
+
+
+{-| A Sortable list allows you to sort coulmn.
+-}
+type ColumnType a
+    = StringColumn { value : a -> String, toString : String -> String }
+    | IntColumn { value : a -> Int, toString : Int -> String }
+    | FloatColumn { value : a -> Float, toString : Float -> String }
+    | UnsortableColumn (a -> String)
+
+
+{-| The Model contains the sorting column name and if ascending or descending.
+-}
+type alias SortTable a msg =
+    { content : List a
+    , columns : List (Column a)
+    , sortBy : String
+    , asc : Bool
+    , onChange : String -> msg
+    }
+
+
+type Column a
+    = Column
+        { title : String
+        , content : ColumnType a
+        , width : Length
+        }
+
+
+unsortableColumn : { title : String, toString : a -> String, width : Length } -> Column a
+unsortableColumn { title, toString, width } =
+    Column
+        { title = title
+        , content = UnsortableColumn toString
+        , width = width
+        }
+
+
+{-| A Column containing a Int
+-}
+intColumn : { title : String, value : a -> Int, toString : Int -> String, width : Length } -> Column a
+intColumn { title, value, toString, width } =
+    Column
+        { title = title
+        , content = IntColumn { value = value, toString = toString }
+        , width = width
+        }
+
+
+{-| A Column containing a Float
+-}
+floatColumn : { title : String, value : a -> Float, toString : Float -> String, width : Length } -> Column a
+floatColumn { title, value, toString, width } =
+    Column
+        { title = title
+        , content = FloatColumn { value = value, toString = toString }
+        , width = width
+        }
+
+
+{-| A Column containing a String
+-}
+stringColumn : { title : String, value : a -> String, toString : String -> String, width : Length } -> Column a
+stringColumn { title, value, toString, width } =
+    Column
+        { title = title
+        , content = StringColumn { value = value, toString = toString }
+        , width = width
+        }
+
+
+{-| The View
+-}
+sortTable :
+    SortTableStyle msg
+    -> SortTable a msg
+    -> Element msg
+sortTable style model =
+    let
+        findTitle : List (Column a) -> Maybe (ColumnType a)
+        findTitle list =
+            case list of
+                [] ->
+                    Nothing
+
+                (Column head) :: tail ->
+                    if head.title == model.sortBy then
+                        Just head.content
+
+                    else
+                        findTitle tail
+    in
+    Element.table style.containerTable
+        { data =
+            model.content
+                |> (model.columns
+                        |> findTitle
+                        |> Maybe.andThen
+                            (\c ->
+                                case c of
+                                    StringColumn { value } ->
+                                        Just <| List.sortBy value
+
+                                    IntColumn { value } ->
+                                        Just <| List.sortBy value
+
+                                    FloatColumn { value } ->
+                                        Just <| List.sortBy value
+
+                                    UnsortableColumn _ ->
+                                        Nothing
+                            )
+                        |> Maybe.withDefault identity
+                   )
+                |> (if model.asc then
+                        identity
+
+                    else
+                        List.reverse
+                   )
+        , columns =
+            model.columns
+                |> List.map
+                    (\(Column column) ->
+                        { header =
+                            Button.button style.headerButton
+                                { text = column.title
+                                , icon =
+                                    if column.title == model.sortBy then
+                                        if model.asc then
+                                            style.ascIcon
+
+                                        else
+                                            style.descIcon
+
+                                    else
+                                        style.defaultIcon
+                                , onPress =
+                                    case column.content of
+                                        UnsortableColumn _ ->
+                                            Nothing
+
+                                        _ ->
+                                            Just <| model.onChange <| column.title
+                                }
+                        , width = column.width
+                        , view =
+                            (case column.content of
+                                IntColumn { value, toString } ->
+                                    value >> toString
+
+                                FloatColumn { value, toString } ->
+                                    value >> toString
+
+                                StringColumn { value, toString } ->
+                                    value >> toString
+
+                                UnsortableColumn toString ->
+                                    toString
+                            )
+                                >> Element.text
+                                >> List.singleton
+                                >> Element.paragraph []
+                        }
+                    )
+        }
diff --git a/src/Internal/Tab.elm b/src/Internal/Tab.elm
new file mode 100644
index 0000000..131b560
--- /dev/null
+++ b/src/Internal/Tab.elm
@@ -0,0 +1,24 @@
+module Internal.Tab exposing (Tab, tab)
+
+import Element exposing (Element)
+import Internal.Select as Select exposing (Select)
+import Widget.Style exposing (TabStyle)
+
+
+type alias Tab msg =
+    { tabs : Select msg
+    , content : Maybe Int -> Element msg
+    }
+
+
+tab : TabStyle msg -> Tab msg -> Element msg
+tab style { tabs, content } =
+    [ tabs
+        |> Select.select
+        |> List.map (Select.selectButton style.button)
+        |> Element.row style.optionRow
+    , tabs.selected
+        |> content
+        |> Element.el style.content
+    ]
+        |> Element.column style.containerColumn
diff --git a/src/Internal/TextInput.elm b/src/Internal/TextInput.elm
new file mode 100644
index 0000000..c4725f5
--- /dev/null
+++ b/src/Internal/TextInput.elm
@@ -0,0 +1,38 @@
+module Internal.TextInput exposing (TextInput, textInput)
+
+import Element exposing (Element)
+import Element.Input as Input exposing (Placeholder)
+import Internal.Button as Button exposing (Button)
+import Widget.Style exposing (TextInputStyle)
+
+
+type alias TextInput msg =
+    { chips : List (Button msg)
+    , text : String
+    , placeholder : Maybe (Placeholder msg)
+    , label : String
+    , onChange : String -> msg
+    }
+
+
+textInput : TextInputStyle msg -> TextInput msg -> Element msg
+textInput style { chips, placeholder, label, text, onChange } =
+    Element.row style.containerRow
+        [ if chips |> List.isEmpty then
+            Element.none
+
+          else
+            chips
+                |> List.map
+                    (Button.button style.chipButton
+                        --Workaround for https://github.com/mdgriffith/elm-ui/issues/47
+                        >> Element.el []
+                    )
+                |> Element.row style.chipsRow
+        , Input.text style.input
+            { onChange = onChange
+            , text = text
+            , placeholder = placeholder
+            , label = Input.labelHidden label
+            }
+        ]
diff --git a/src/Layout.elm b/src/Layout.elm
deleted file mode 100644
index 66b5b17..0000000
--- a/src/Layout.elm
+++ /dev/null
@@ -1,256 +0,0 @@
-module Layout exposing (Direction(..), Layout, init, queueMessage, setSidebar, timePassed, view)
-
-import Browser.Dom exposing (Viewport)
-import Core.Style as Style exposing (Style)
-import Element exposing (Attribute, DeviceClass(..), Element)
-import Element.Background as Background
-import Element.Events as Events
-import Element.Input as Input
-import Html exposing (Html)
-import Html.Attributes as Attributes
-import Widget
-import Widget.Snackbar as Snackbar
-
-
-type Direction
-    = Left
-    | Right
-
-
-type alias Layout =
-    { snackbar : Snackbar.Model String
-    , sheet : Maybe Direction
-    }
-
-
-init : Layout
-init =
-    { snackbar = Snackbar.init
-    , sheet = Nothing
-    }
-
-
-queueMessage : String -> Layout -> Layout
-queueMessage message layout =
-    { layout
-        | snackbar = layout.snackbar |> Snackbar.insert message
-    }
-
-
-setSidebar : Maybe Direction -> Layout -> Layout
-setSidebar direction layout =
-    { layout
-        | sheet = direction
-    }
-
-
-timePassed : Int -> Layout -> Layout
-timePassed sec layout =
-    case layout.sheet of
-        Nothing ->
-            { layout
-                | snackbar = layout.snackbar |> Snackbar.timePassed sec
-            }
-
-        _ ->
-            layout
-
-
-view :
-    List (Attribute msg)
-    ->
-        { deviceClass : DeviceClass
-        , dialog : Maybe { onDismiss : Maybe msg, content : Element msg }
-        , content : Element msg
-        , layout : Layout
-        , title : Element msg
-        , menu :
-            { selected : Int
-            , items : List { label : String, icon : Element Never, onPress : Maybe msg }
-            }
-        , actions : List { label : String, icon : Element Never, onPress : Maybe msg }
-        , onChangedSidebar : Maybe Direction -> msg
-        , style : Style msg
-        }
-    -> Html msg
-view attributes { title, onChangedSidebar, menu, actions, deviceClass, dialog, content, style, layout } =
-    let
-        ( primaryActions, moreActions ) =
-            ( if (actions |> List.length) > 4 then
-                actions |> List.take 2
-
-              else if (actions |> List.length) == 4 then
-                actions |> List.take 1
-
-              else if (actions |> List.length) == 3 then
-                []
-
-              else
-                actions |> List.take 2
-            , if (actions |> List.length) > 4 then
-                actions |> List.drop 2
-
-              else if (actions |> List.length) == 4 then
-                actions |> List.drop 1
-
-              else if (actions |> List.length) == 3 then
-                actions
-
-              else
-                actions |> List.drop 2
-            )
-
-        nav =
-            [ (if
-                (deviceClass == Phone)
-                    || (deviceClass == Tablet)
-                    || ((menu.items |> List.length) > 5)
-               then
-                [ Input.button style.menuButton
-                    { onPress = Just <| onChangedSidebar <| Just Left
-                    , label = style.menuIcon |> Element.map never
-                    }
-                , title
-                ]
-
-               else
-                [ title
-                , menu.items
-                    |> List.indexedMap
-                        (\i ->
-                            if i == menu.selected then
-                                Style.menuTabButtonSelected style
-
-                            else
-                                Style.menuTabButton style
-                        )
-                    |> Element.row
-                        [ Element.width <| Element.shrink
-                        ]
-                ]
-              )
-                |> Element.row
-                    [ Element.width <| Element.shrink
-                    , Element.spacing 8
-                    ]
-            , [ primaryActions
-                    |> List.map
-                        (if deviceClass == Phone then
-                            Style.menuIconButton style
-
-                         else
-                            Style.menuButton style
-                        )
-              , if moreActions |> List.isEmpty then
-                    []
-
-                else
-                    [ Style.menuButton style
-                        { onPress = Just <| onChangedSidebar <| Just Right
-                        , icon = style.moreVerticalIcon
-                        , label = ""
-                        }
-                    ]
-              ]
-                |> List.concat
-                |> Element.row
-                    [ Element.width <| Element.shrink
-                    , Element.alignRight
-                    ]
-            ]
-                |> Element.row
-                    (style.header
-                        ++ [ Element.padding 0
-                           , Element.centerX
-                           , Element.spaceEvenly
-                           , Element.alignTop
-                           , Element.width <| Element.fill
-                           ]
-                    )
-
-        snackbar =
-            layout.snackbar
-                |> Snackbar.current
-                |> Maybe.map
-                    (Element.text
-                        >> List.singleton
-                        >> Element.paragraph style.snackbar
-                        >> Element.el
-                            [ Element.padding 8
-                            , Element.alignBottom
-                            , Element.alignRight
-                            ]
-                    )
-                |> Maybe.withDefault Element.none
-        sheet =
-            case layout.sheet of
-                Just Left ->
-                    menu.items
-                        |> List.indexedMap
-                            (\i ->
-                                if i == menu.selected then
-                                    Style.sheetButtonSelected style
-
-                                else
-                                    Style.sheetButton style
-                            )
-                        |> Element.column [ Element.width <| Element.fill ]
-                        |> Element.el
-                            (style.sheet
-                                ++ [ Element.height <| Element.fill
-                                   , Element.alignLeft
-                                   ]
-                            )
-
-                Just Right ->
-                    moreActions
-                        |> List.map (Style.sheetButton style)
-                        |> Element.column [ Element.width <| Element.fill ]
-                        |> Element.el
-                            (style.sheet
-                                ++ [ Element.height <| Element.fill
-                                   , Element.alignRight
-                                   ]
-                            )
-
-                Nothing ->
-                    Element.none
-    in
-    content
-        |> style.layout
-            (List.concat
-                [ attributes
-                , [ Element.inFront nav
-                  , Element.inFront snackbar
-                  ]
-                , if (layout.sheet /= Nothing) || (dialog /= Nothing) then
-                    Widget.scrim
-                        { onDismiss =
-                            Just <|
-                                case dialog of
-                                    Just { onDismiss } ->
-                                        onDismiss
-                                            |> Maybe.withDefault
-                                                (Nothing
-                                                    |> onChangedSidebar
-                                                )
-
-                                    Nothing ->
-                                        Nothing
-                                            |> onChangedSidebar
-                        , content = Element.none
-                        }
-
-                  else
-                    []
-                , [ Element.inFront sheet
-                  , Element.inFront <|
-                        case dialog of
-                            Just element ->
-                                element.content
-
-                            Nothing ->
-                                Element.none
-                  ]
-                ]
-            )
diff --git a/src/Widget.elm b/src/Widget.elm
index 65e0abd..374c0e6 100644
--- a/src/Widget.elm
+++ b/src/Widget.elm
@@ -1,249 +1,508 @@
 module Widget exposing
-    ( select, multiSelect, collapsable, carousel, scrim, tab
-    , dialog
+    ( Button, TextButton, iconButton, textButton, button
+    , Select, MultiSelect, selectButton, select, multiSelect
+    , Dialog, modal, dialog
+    , ExpansionPanel, expansionPanel
+    , row, column, buttonRow, buttonColumn
+    , SortTable,Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
+    , TextInput, textInput
+    , Tab, tab
     )
 
-{-| This module contains functions for displaying data.
+{-| This module contains different stateless view functions. No wiring required.
 
-@docs select, multiSelect, collapsable, carousel, scrim, tab
+These widgets should be used by defining the styling seperately:
+
+```
+Widget.button Material.primaryButton
+    { text = "disable me"
+    , icon =
+        FeatherIcons.slash
+            |> FeatherIcons.withSize 16
+            |> FeatherIcons.toHtml []
+            |> Element.html
+            |> Element.el []
+    , onPress =
+        if isButtonEnabled then
+            ChangedButtonStatus False
+                |> Just
+
+        else
+            Nothing
+    }
+```
+
+Every widgets comes with a type. You can think of the widgets as building blocks.
+You can create you own widgets by sticking widgets types together.
+
+# Buttons
+
+![Button](https://orasund.github.io/elm-ui-widgets/assets/button.png)
+
+@docs Button, TextButton, iconButton, textButton, button
 
 
-# DEPRECATED
+# Select
 
-@docs dialog
+![Select](https://orasund.github.io/elm-ui-widgets/assets/select.png)
+
+@docs Select, selectButton, select
+
+![multiSelect](https://orasund.github.io/elm-ui-widgets/assets/multiSelect.png)
+
+@docs MultiSelect, multiSelect
+
+
+# Dialog
+
+![dialog](https://orasund.github.io/elm-ui-widgets/assets/dialog.png)
+
+@docs Dialog, modal, dialog
+
+
+# Expansion Panel
+
+![expansionPanel](https://orasund.github.io/elm-ui-widgets/assets/expansionPanel.png)
+
+@docs ExpansionPanel, expansionPanel
+
+
+# List
+
+![list](https://orasund.github.io/elm-ui-widgets/assets/list.png)
+
+@docs row, column, buttonRow, buttonColumn
+
+
+# Sort Table
+
+![sortTable](https://orasund.github.io/elm-ui-widgets/assets/sortTable.png)
+
+@docs SortTable,Column, sortTable, floatColumn, intColumn, stringColumn, unsortableColumn
+
+
+# Text Input
+
+![textInput](https://orasund.github.io/elm-ui-widgets/assets/textInput.png)
+
+@docs TextInput, textInput
+
+
+# Tab
+
+![tab](https://orasund.github.io/elm-ui-widgets/assets/textInput.png)
+
+@docs Tab, tab
 
 -}
 
-import Array exposing (Array)
-import Element exposing (Attribute, Element)
-import Element.Background as Background
-import Element.Events as Events
-import Element.Input as Input
+import Element exposing (Attribute, Element, Length)
+import Element.Input exposing (Placeholder)
+import Internal.Button as Button
+import Internal.Dialog as Dialog
+import Internal.ExpansionPanel as ExpansionPanel
+import Internal.List as List
+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,TextInputStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, RowStyle, SortTableStyle, TabStyle)
+
+
+
+{----------------------------------------------------------
+- BUTTON
+----------------------------------------------------------}
+
+
+{-| Button widget type
+-}
+type alias Button msg =
+    { text : String
+    , icon : Element Never
+    , onPress : Maybe msg
+    }
+
+
+{-| Button widget type with no icon
+-}
+type alias TextButton msg =
+    { text : String
+    , onPress : Maybe msg
+    }
+
+
+{-| A button containing only an icon, the text is used for screenreaders.
+-}
+iconButton :
+    ButtonStyle msg
+    ->
+        { text : String
+        , icon : Element Never
+        , onPress : Maybe msg
+        }
+    -> Element msg
+iconButton =
+    Button.iconButton
+
+
+{-| A button with just text and not icon.
+-}
+textButton :
+    ButtonStyle msg
+    ->
+        { textButton
+            | text : String
+            , onPress : Maybe msg
+        }
+    -> Element msg
+textButton style { text, onPress } =
+    Button.textButton style
+        { text = text
+        , onPress = onPress
+        }
+
+
+{-| A button containing a text and an icon.
+-}
+button :
+    ButtonStyle msg
+    ->
+        { text : String
+        , icon : Element Never
+        , onPress : Maybe msg
+        }
+    -> Element msg
+button =
+    Button.button
+
+
+
+{----------------------------------------------------------
+- SELECT
+----------------------------------------------------------}
+
+
+{-| Select widget type
+
+Technical Remark:
+
+* A more suitable name would be "Choice"
+
+-}
+type alias Select msg =
+    { selected : Maybe Int
+    , options :
+        List
+            { text : String
+            , icon : Element Never
+            }
+    , onSelect : Int -> Maybe msg
+    }
+
+
+{-| Multi Select widget type
+
+Technical Remark:
+
+* A more suitable name would be "Options"
+
+-}
+type alias MultiSelect msg =
+    { selected : Set Int
+    , options :
+        List
+            { text : String
+            , icon : Element Never
+            }
+    , onSelect : Int -> Maybe msg
+    }
+
+
+{-| A simple button that can be selected.
+-}
+selectButton :
+    ButtonStyle msg
+    -> ( Bool, Button msg )
+    -> Element msg
+selectButton =
+    Select.selectButton
 
 
 {-| Selects one out of multiple options. This can be used for radio buttons or Menus.
 -}
 select :
-    { selected : Maybe a
-    , options : List a
-    , label : a -> Element msg
-    , onChange : a -> msg
-    , attributes : Bool -> List (Attribute msg)
-    }
-    -> List (Element msg)
-select { selected, options, label, onChange, attributes } =
-    options
-        |> List.map
-            (\a ->
-                Input.button (attributes (selected == Just a))
-                    { onPress = a |> onChange |> Just
-                    , label = label a
-                    }
-            )
+    Select msg
+    -> List ( Bool, Button msg )
+select =
+    Select.select
 
 
 {-| Selects multible options. This can be used for checkboxes.
 -}
 multiSelect :
-    { selected : Set comparable
-    , options : List comparable
-    , label : comparable -> Element msg
-    , onChange : comparable -> msg
-    , attributes : Bool -> List (Attribute msg)
+    MultiSelect msg
+    -> List ( Bool, Button msg )
+multiSelect =
+    Select.multiSelect
+
+
+
+{----------------------------------------------------------
+- DIALOG
+----------------------------------------------------------}
+
+
+{-| Dialog widget type
+-}
+type alias Dialog msg =
+    { title : Maybe String
+    , body : Element msg
+    , accept : Maybe (TextButton msg)
+    , dismiss : Maybe (TextButton msg)
     }
-    -> List (Element msg)
-multiSelect { selected, options, label, onChange, attributes } =
-    options
-        |> List.map
-            (\a ->
-                Input.button (attributes (selected |> Set.member a))
-                    { onPress = a |> onChange |> Just
-                    , label =
-                        label a
-                    }
-            )
 
 
-{-| Some collapsable content.
+{-| A modal.
 
-        Widget.collapsable
-            {onToggle = ToggleCollapsable
-            ,isCollapsed = model.isCollapsed
-            ,label = Element.row Grid.compact
-                [ Element.html <|
-                    if model.isCollapsed then
-                        Heroicons.cheveronRight  [ Attributes.width 20]
-                    else
-                        Heroicons.cheveronDown [ Attributes.width 20]
-                , Element.el Heading.h4 <|Element.text <| "Title"
-                ]
-            ,content = Element.text <| "Hello World"
-            }
+Technical Remark:
+
+* To stop the screen from scrolling, set the height of the layout to the height of the screen.
 
 -}
-collapsable :
-    { onToggle : Bool -> msg
-    , isCollapsed : Bool
-    , label : Element msg
-    , content : Element msg
-    }
-    -> Element msg
-collapsable { onToggle, isCollapsed, label, content } =
-    Element.column [] <|
-        [ Input.button []
-            { onPress = Just <| onToggle <| not isCollapsed
-            , label = label
-            }
-        ]
-            ++ (if isCollapsed then
-                    []
+modal : { onDismiss : Maybe msg, content : Element msg } -> List (Attribute msg)
+modal =
+    Dialog.modal
 
-                else
-                    [ content ]
-               )
+
+{-| A Dialog Window.
+-}
+dialog :
+    DialogStyle msg
+    ->
+        { title : Maybe String
+        , text : String
+        , accept : Maybe (TextButton msg)
+        , dismiss : Maybe (TextButton msg)
+        }
+    -> List (Attribute msg)
+dialog =
+    Dialog.dialog
+
+
+
+{----------------------------------------------------------
+- EXPANSION PANEL
+----------------------------------------------------------}
+
+{-| Expansion Panel widget type
+-}
+type alias ExpansionPanel msg =
+    { onToggle : Bool -> msg
+    , icon : Element Never
+    , text : String
+    , expandIcon : Element Never
+    , collapseIcon : Element Never
+    , content : Element msg
+    , isExpanded : Bool
+    }
+
+{-| An expansion Panel
+-}
+expansionPanel :
+    ExpansionPanelStyle msg
+    ->
+        { onToggle : Bool -> msg
+        , icon : Element Never
+        , text : String
+        , content : Element msg
+        , isExpanded : Bool
+        }
+    -> Element msg
+expansionPanel =
+    ExpansionPanel.expansionPanel
+
+
+
+{----------------------------------------------------------
+- TEXT INPUT
+----------------------------------------------------------}
+
+{-| Text Input widget type
+-}
+type alias TextInput msg =
+    { chips : List (Button msg)
+    , text : String
+    , placeholder : Maybe (Placeholder msg)
+    , label : String
+    , onChange : String -> msg
+    }
+
+{-| A text Input that allows to include chips. -}
+textInput :
+    TextInputStyle msg
+    ->
+        { chips : List (Button msg)
+        , text : String
+        , placeholder : Maybe (Placeholder msg)
+        , label : String
+        , onChange : String -> msg
+        }
+    -> Element msg
+textInput =
+    TextInput.textInput
+
+
+
+{----------------------------------------------------------
+- LIST
+----------------------------------------------------------}
+
+{-| Replacement of `Element.row`
+-}
+row : RowStyle msg -> List (Element msg) -> Element msg
+row =
+    List.row
+
+{-| Replacement of `Element.column`
+-}
+column : ColumnStyle msg -> List (Element msg) -> Element msg
+column =
+    List.column
+
+{-| A row of buttons
+-}
+buttonRow :
+    { list : RowStyle msg
+    , button : ButtonStyle msg
+    }
+    -> List ( Bool, Button msg )
+    -> Element msg
+buttonRow =
+    List.buttonRow
+
+{-| A column of buttons
+-}
+buttonColumn :
+    { list : ColumnStyle msg
+    , button : ButtonStyle msg
+    }
+    -> List ( Bool, Button msg )
+    -> Element msg
+buttonColumn =
+    List.buttonColumn
+
+
+
+{----------------------------------------------------------
+- SORT TABLE
+----------------------------------------------------------}
+
+
+{-| Column for the Sort Table widget type
+-}
+type alias Column a =
+    SortTable.Column a
+
+{-|  Sort Table widget type
+-}
+type alias SortTable a msg=
+    { content : List a
+    , columns : List (Column a)
+    , sortBy : String
+    , asc : Bool
+    , onChange : String -> msg
+    }
+
+{-| An unsortable Column, when trying to sort by this column, nothing will change.
+-}
+unsortableColumn :
+    { title : String
+    , toString : a -> String
+    , width : Length
+    }
+    -> Column a
+unsortableColumn =
+    SortTable.unsortableColumn
+
+
+{-| A Column containing a Int
+-}
+intColumn :
+    { title : String
+    , value : a -> Int
+    , toString : Int -> String
+    , width : Length
+    }
+    -> Column a
+intColumn =
+    SortTable.intColumn
+
+
+{-| A Column containing a Float
+-}
+floatColumn :
+    { title : String
+    , value : a -> Float
+    , toString : Float -> String
+    , width : Length
+    }
+    -> Column a
+floatColumn =
+    SortTable.floatColumn
+
+
+{-| A Column containing a String
+-}
+stringColumn :
+    { title : String
+    , value : a -> String
+    , toString : String -> String
+    , width : Length
+    }
+    -> Column a
+stringColumn =
+    SortTable.stringColumn
+
+
+{-| The View
+-}
+sortTable :
+    SortTableStyle msg
+    ->
+        { content : List a
+        , columns : List (Column a)
+        , sortBy : String
+        , asc : Bool
+        , onChange : String -> msg
+        }
+    -> Element msg
+sortTable =
+    SortTable.sortTable
+
+
+
+{----------------------------------------------------------
+- TAB
+----------------------------------------------------------}
+
+{-| Tab widget type
+-}
+type alias Tab msg =
+    { tabs : Select msg
+    , content : Maybe Int -> Element msg
+    }
 
 
 {-| Displayes a list of contents in a tab
 -}
 tab :
-    List (Attribute msg)
+    TabStyle msg
     ->
-        { selected : a
-        , options : List a
-        , onChange : a -> msg
-        , label : a -> Element msg
-        , content : a -> Element msg
-        , attributes : Bool -> List (Attribute msg)
+        { tabs : Select msg
+        , content : Maybe Int -> Element msg
         }
     -> Element msg
-tab atts { selected, options, onChange, label, content, attributes } =
-    [ select
-        { selected = Just selected
-        , options = options
-        , label = label
-        , onChange = onChange
-        , attributes = attributes
-        }
-        |> Element.row atts
-    , content selected
-    ]
-        |> Element.column []
-
-
-{-| DEPRECATED. Use scrim instead.
--}
-dialog :
-    { onDismiss : Maybe msg
-    , content : Element msg
-    }
-    -> Element msg
-dialog { onDismiss, content } =
-    content
-        |> Element.el
-            [ Element.centerX
-            , Element.centerY
-            ]
-        |> Element.el
-            ([ Element.width <| Element.fill
-             , Element.height <| Element.fill
-             , Background.color <| Element.rgba255 0 0 0 0.5
-             ]
-                ++ (onDismiss
-                        |> Maybe.map (Events.onClick >> List.singleton)
-                        |> Maybe.withDefault []
-                   )
-            )
-
-
-{-| A scrim to block the interaction with the site. Usefull for modals and side panels
-
-If the scrim is clicked a message may be send. Also one can place an element infront.
-
-        Framework.Layout
-            [ Wiget.scrim
-                { onDismiss = Just <| ToggleDialog False
-                , content =
-                    [ "This is a dialog window"
-                        |> Element.text
-                    , Input.button []
-                        {onPress = Just <| ToggleDialog False
-                        , label = Element.text "Ok"
-                        }
-                    ]
-                    |> Element.column
-                        [ Element.centerX
-                        , Element.centerY
-                        ]
-                }
-            ]
-
--}
-scrim : { onDismiss : Maybe msg, content : Element msg } -> List (Attribute msg)
-scrim { onDismiss, content } =
-    Element.el
-        ([ Element.width <| Element.fill
-         , Element.height <| Element.fill
-         , Background.color <| Element.rgba255 0 0 0 0.5
-         ]
-            ++ (onDismiss
-                    |> Maybe.map (Events.onClick >> List.singleton)
-                    |> Maybe.withDefault []
-               )
-        )
-        content
-        |> Element.inFront
-        |> List.singleton
-
-
-{-| A Carousel circles through a non empty list of contents.
-
-        Widget.carousel
-            {content = ("Blue",["Yellow", "Green" , "Red" ]|> Array.fromList)
-            ,current = model.carousel
-            , label = \c ->
-                [ Input.button [Element.centerY]
-                    { onPress = Just <|
-                         SetCarousel <|
-                            (\x -> if x < 0 then 0 else x) <|
-                                model.carousel - 1
-                    , label = "<" |> Element.text
-                    }
-                , c |> Element.text
-                , Input.button [Element.centerY]
-                    { onPress = Just <|
-                        SetCarousel <|
-                            (\x -> if x > 3 then 3 else x) <|
-                            model.carousel + 1
-                    , label = ">" |> Element.text
-                    }
-                ]
-                |> Element.row [Element.centerX, Element.width<| Element.shrink]
-            }
-
--}
-carousel :
-    { content : ( a, Array a )
-    , current : Int
-    , label : a -> Element msg
-    }
-    -> Element msg
-carousel { content, current, label } =
-    let
-        ( head, tail ) =
-            content
-    in
-    (if current <= 0 then
-        head
-
-     else if current > Array.length tail then
-        tail
-            |> Array.get (Array.length tail - 1)
-            |> Maybe.withDefault head
-
-     else
-        tail
-            |> Array.get (current - 1)
-            |> Maybe.withDefault head
-    )
-        |> label
+tab =
+    Tab.tab
diff --git a/src/Widget/FilterSelect.elm b/src/Widget/FilterSelect.elm
deleted file mode 100644
index 8d6bbf9..0000000
--- a/src/Widget/FilterSelect.elm
+++ /dev/null
@@ -1,93 +0,0 @@
-module Widget.FilterSelect exposing (Model, Msg(..), init, update, viewInput, viewOptions)
-
-{-|
-
-@docs Model, Msg, init, update, viewInput, viewOptions
-
--}
-
-import Element exposing (Attribute, Element)
-import Element.Input as Input exposing (Placeholder)
-import Set exposing (Set)
-
-
-{-| The Model containing the raw value, the selected value and all the possible options.
--}
-type alias Model =
-    { raw : String
-    , selected : Maybe String
-    , options : Set String
-    }
-
-
-{-| The Msg is exposed by design. You can unselect by sending `Selected Nothing`.
--}
-type Msg
-    = ChangedRaw String
-    | Selected (Maybe String)
-
-
-{-| The initial state contains the set of possible options.
--}
-init : Set String -> Model
-init options =
-    { raw = ""
-    , selected = Nothing
-    , options = options
-    }
-
-
-{-| Updates the Model
--}
-update : Msg -> Model -> Model
-update msg model =
-    case msg of
-        ChangedRaw string ->
-            { model
-                | raw = string
-            }
-
-        Selected maybe ->
-            { model
-                | selected = maybe
-            }
-                |> (case maybe of
-                        Just string ->
-                            \m -> { m | raw = string }
-
-                        Nothing ->
-                            identity
-                   )
-
-
-{-| A wrapper around Input.text.
--}
-viewInput :
-    List (Attribute msg)
-    -> Model
-    ->
-        { msgMapper : Msg -> msg
-        , placeholder : Maybe (Placeholder msg)
-        , label : String
-        }
-    -> Element msg
-viewInput attributes model { msgMapper, placeholder, label } =
-    Input.text attributes
-        { onChange = ChangedRaw >> msgMapper
-        , text = model.raw
-        , placeholder = placeholder
-        , label = Input.labelHidden label
-        }
-
-
-{-| Returns a List of all options that matches the filter.
--}
-viewOptions : Model -> List String
-viewOptions { raw, options } =
-    if raw == "" then
-        []
-
-    else
-        options
-            |> Set.filter (String.toUpper >> String.contains (raw |> String.toUpper))
-            |> Set.toList
diff --git a/src/Widget/Layout.elm b/src/Widget/Layout.elm
new file mode 100644
index 0000000..2675447
--- /dev/null
+++ b/src/Widget/Layout.elm
@@ -0,0 +1,349 @@
+module Widget.Layout exposing (Layout, Part(..), activate, init, queueMessage, timePassed, view)
+
+{-| Combines multiple concepts from the [material design specification](https://material.io/components/), namely:
+
+* Top App Bar
+* Navigation Draw
+* Side Panel
+* Dialog
+* Snackbar
+
+It is responsive and changes view to apply to the [material design guidelines](https://material.io/components/app-bars-top).
+
+# Basics
+
+@docs Layout, Part, init, timePassed, view
+
+# Actions
+
+@docs activate, queueMessage
+
+
+-}
+
+import Array
+import Element exposing (Attribute, DeviceClass(..), Element)
+import Element.Input as Input
+import Html exposing (Html)
+import Widget exposing (Button, Select)
+import Widget.Snackbar as Snackbar exposing (Message)
+import Widget.Style exposing (LayoutStyle)
+
+{-| The currently visible part: either the left sheet, right sheet or the search bar
+-}
+type Part
+    = LeftSheet
+    | RightSheet
+    | Search
+
+{-| The model of the layout containing the snackbar and the currently active side sheet (or search bar)
+-}
+type alias Layout msg =
+    { snackbar : Snackbar.Snackbar (Message msg)
+    , active : Maybe Part
+    }
+
+{-| The initial state of the layout
+-}
+init : Layout msg
+init =
+    { snackbar = Snackbar.init
+    , active = Nothing
+    }
+
+{-| Queues a message and displayes it as a snackbar once no other snackbar is visible.
+-}
+queueMessage : Message msg -> Layout msg -> Layout msg
+queueMessage message layout =
+    { layout
+        | snackbar = layout.snackbar |> Snackbar.insert message
+    }
+
+{-| Open either a side sheet or the search bar.
+-}
+activate : Maybe Part -> Layout msg -> Layout msg
+activate part layout =
+    { layout
+        | active = part
+    }
+
+{-| Update the model, put this function into your subscription.
+The first argument is the seconds that have passed sice the function was called last.
+-}
+timePassed : Int -> Layout msg -> Layout msg
+timePassed sec layout =
+    case layout.active of
+        Just LeftSheet ->
+            layout
+
+        Just RightSheet ->
+            layout
+
+        _ ->
+            { layout
+                | snackbar = layout.snackbar |> Snackbar.timePassed sec
+            }
+
+{-| View the layout. Replacement of `Element.layout`.
+-}
+view :
+    LayoutStyle msg
+    ->
+        { window : { height : Int, width : Int }
+        , dialog : Maybe (List (Attribute msg))
+        , layout : Layout msg
+        , title : Element msg
+        , menu : Select msg
+        , search :
+            Maybe
+                { onChange : String -> msg
+                , text : String
+                , label : String
+                }
+        , actions : List (Button msg)
+        , onChangedSidebar : Maybe Part -> msg
+        }
+    -> Element msg
+    -> Html msg
+view style { search, title, onChangedSidebar, menu, actions, window, dialog, layout } content =
+    let
+        deviceClass : DeviceClass
+        deviceClass =
+            window
+                |> Element.classifyDevice
+                |> .class
+
+        ( primaryActions, moreActions ) =
+            ( if (actions |> List.length) > 4 then
+                actions |> List.take 2
+
+              else if (actions |> List.length) == 4 then
+                actions |> List.take 1
+
+              else if (actions |> List.length) == 3 then
+                []
+
+              else
+                actions |> List.take 2
+            , if (actions |> List.length) > 4 then
+                actions |> List.drop 2
+
+              else if (actions |> List.length) == 4 then
+                actions |> List.drop 1
+
+              else if (actions |> List.length) == 3 then
+                actions
+
+              else
+                actions |> List.drop 2
+            )
+
+        nav =
+            [ (if
+                (deviceClass == Phone)
+                    || (deviceClass == Tablet)
+                    || ((menu.options |> List.length) > 5)
+               then
+                [ Widget.iconButton style.menuButton
+                    { onPress = Just <| onChangedSidebar <| Just LeftSheet
+                    , icon = style.menuIcon |> Element.map never
+                    , text = "Menu"
+                    }
+                , menu.selected
+                    |> Maybe.andThen
+                        (\option ->
+                            menu.options
+                                |> Array.fromList
+                                |> Array.get option
+                        )
+                    |> Maybe.map (.text >> Element.text)
+                    |> Maybe.withDefault title
+                    |> Element.el style.title
+                ]
+
+               else
+                [ title |> Element.el style.title
+                , menu
+                    |> Widget.select
+                    |> List.map (Widget.selectButton style.menuTabButton)
+                    |> Element.row
+                        [ Element.width <| Element.shrink
+                        ]
+                ]
+              )
+                |> 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 } ->
+                            Input.text style.search
+                                { onChange = onChange
+                                , text = text
+                                , placeholder =
+                                    Just <|
+                                        Input.placeholder [] <|
+                                            Element.text label
+                                , label = Input.labelHidden label
+                                }
+                        )
+                    |> Maybe.withDefault Element.none
+            , [ search
+                    |> Maybe.map
+                        (\{ label } ->
+                            if deviceClass == Tablet then
+                                [ Widget.button style.menuButton
+                                    { onPress = Just <| onChangedSidebar <| Just Search
+                                    , icon = style.searchIcon
+                                    , text = label
+                                    }
+                                ]
+
+                            else if deviceClass == Phone then
+                                [ Widget.iconButton style.menuButton
+                                    { onPress = Just <| onChangedSidebar <| Just Search
+                                    , icon = style.searchIcon
+                                    , text = label
+                                    }
+                                ]
+
+                            else
+                                []
+                        )
+                    |> Maybe.withDefault []
+              , primaryActions
+                    |> List.map
+                        (if deviceClass == Phone then
+                            Widget.iconButton style.menuButton
+
+                         else
+                            Widget.button style.menuButton
+                        )
+              , if moreActions |> List.isEmpty then
+                    []
+
+                else
+                    [ Widget.iconButton style.menuButton
+                        { onPress = Just <| onChangedSidebar <| Just RightSheet
+                        , icon = style.moreVerticalIcon
+                        , text = "More"
+                        }
+                    ]
+              ]
+                |> List.concat
+                |> Element.row
+                    [ Element.width <| Element.shrink
+                    , Element.alignRight
+                    ]
+            ]
+                |> Element.row
+                    (style.header
+                        ++ [ Element.padding 0
+                           , Element.centerX
+                           , Element.spacing style.spacing
+                           , Element.alignTop
+                           , Element.width <| Element.fill
+                           ]
+                    )
+
+        snackbar =
+            layout.snackbar
+                |> Snackbar.view style.snackbar identity
+                |> Maybe.map
+                    (Element.el
+                        [ Element.padding style.spacing
+                        , Element.alignBottom
+                        , Element.alignRight
+                        ]
+                    )
+                |> Maybe.withDefault Element.none
+
+        sheet =
+            case layout.active of
+                Just LeftSheet ->
+                    [ [ title
+                      ]
+                    , menu
+                        |> Widget.select
+                        |> List.map
+                            (Widget.selectButton style.sheetButton)
+                    ]
+                        |> List.concat
+                        |> Element.column [ Element.width <| Element.fill ]
+                        |> Element.el
+                            (style.sheet
+                                ++ [ Element.height <| Element.fill
+                                   , Element.alignLeft
+                                   ]
+                            )
+
+                Just RightSheet ->
+                    moreActions
+                        |> List.map (Widget.button style.sheetButton)
+                        |> Element.column [ Element.width <| Element.fill ]
+                        |> Element.el
+                            (style.sheet
+                                ++ [ Element.height <| Element.fill
+                                   , Element.alignRight
+                                   ]
+                            )
+
+                Just Search ->
+                    case search of
+                        Just { onChange, text, label } ->
+                            Input.text
+                                (style.searchFill
+                                    ++ [ Element.width <| Element.fill
+                                       ]
+                                )
+                                { onChange = onChange
+                                , text = text
+                                , placeholder =
+                                    Just <|
+                                        Input.placeholder [] <|
+                                            Element.text label
+                                , label = Input.labelHidden label
+                                }
+                                |> Element.el
+                                    [ Element.alignTop
+                                    , Element.width <| Element.fill
+                                    ]
+
+                        Nothing ->
+                            Element.none
+
+                Nothing ->
+                    Element.none
+    in
+    content
+        |> style.layout
+            (List.concat
+                [ style.container
+                , [ Element.inFront nav
+                  , Element.inFront snackbar
+                  ]
+                , if (layout.active /= Nothing) || (dialog /= Nothing) then
+                    --(Element.height <| Element.px <| window.height)
+                    --    ::
+                    case dialog of
+                        Just dialogConfig ->
+                            dialogConfig
+
+                        Nothing ->
+                            Widget.modal
+                                { onDismiss =
+                                    Nothing
+                                        |> onChangedSidebar
+                                        |> Just
+                                , content = sheet
+                                }
+
+                  else
+                    []
+                ]
+            )
diff --git a/src/Widget/ScrollingNav.elm b/src/Widget/ScrollingNav.elm
index 8a55cf5..83675c0 100644
--- a/src/Widget/ScrollingNav.elm
+++ b/src/Widget/ScrollingNav.elm
@@ -1,7 +1,6 @@
 module Widget.ScrollingNav exposing
-    ( Model, Msg, init, update, subscriptions, view, viewSections, current
-    , jumpTo, syncPositions
-    , jumpToWithOffset
+    ( ScrollingNav, init, view, current, toSelect
+    , jumpTo, jumpToWithOffset, syncPositions, getPos, setPos
     )
 
 {-| The Scrolling Nav is a navigation bar thats updates while you scroll through
@@ -10,51 +9,45 @@ the page. Clicking on a navigation button will scroll directly to that section.
 
 # Basics
 
-@docs Model, Msg, init, update, subscriptions, view, viewSections, current
+@docs ScrollingNav, init, view, current, toSelect
 
 
 # Operations
 
-@docs jumpTo, syncPositions
+@docs jumpTo, jumpToWithOffset, syncPositions, getPos, setPos
 
 -}
 
 import Browser.Dom as Dom
-import Element exposing (Attribute, Element)
-import Framework.Grid as Grid
+import Element exposing (Element)
 import Html.Attributes as Attributes
 import IntDict exposing (IntDict)
-import Task
-import Time
+import Task exposing (Task)
+import Widget exposing (Select)
 
 
 {-| -}
-type alias Model section =
-    { labels : section -> String
+type alias ScrollingNav section =
+    { toString : section -> String
+    , fromString : String -> Maybe section
     , positions : IntDict String
     , arrangement : List section
     , scrollPos : Int
     }
 
 
-{-| -}
-type Msg section
-    = GotHeaderPos section (Result Dom.Error Int)
-    | ChangedViewport (Result Dom.Error ())
-    | SyncPosition Int
-    | JumpTo section
-    | TimePassed
-
-
 {-| The intial state include the labels and the arrangement of the sections
 -}
 init :
-    { labels : section -> String
+    { toString : section -> String
+    , fromString : String -> Maybe section
     , arrangement : List section
+    , toMsg : Result Dom.Error (ScrollingNav section -> ScrollingNav section) -> msg
     }
-    -> ( Model section, Cmd (Msg section) )
-init { labels, arrangement } =
-    { labels = labels
+    -> ( ScrollingNav section, Cmd msg )
+init { toString, fromString, arrangement, toMsg } =
+    { toString = toString
+    , fromString = fromString
     , positions = IntDict.empty
     , arrangement = arrangement
     , scrollPos = 0
@@ -62,101 +55,102 @@ init { labels, arrangement } =
         |> (\a ->
                 ( a
                 , syncPositions a
+                    |> Task.attempt toMsg
                 )
            )
 
 
-{-| -}
-update : Msg section -> Model section -> ( Model section, Cmd (Msg section) )
-update msg model =
-    case msg of
-        GotHeaderPos label result ->
-            ( case result of
-                Ok pos ->
-                    { model
-                        | positions =
-                            model.positions
-                                |> IntDict.insert pos
-                                    (label |> model.labels)
-                    }
-
-                Err _ ->
-                    model
-            , Cmd.none
-            )
-
-        ChangedViewport _ ->
-            ( model, Cmd.none )
-
-        SyncPosition pos ->
-            ( { model
-                | scrollPos = pos
-              }
-            , Cmd.none
-            )
-
-        TimePassed ->
-            ( model
-            , Dom.getViewport
-                |> Task.map (.viewport >> .y >> round)
-                |> Task.perform SyncPosition
-            )
-
-        JumpTo elem ->
-            ( model
-            , model
-                |> jumpTo elem
-            )
-
-
-{-| -}
-subscriptions : Sub (Msg msg)
-subscriptions =
-    Time.every 100 (always TimePassed)
-
-
-{-| scrolls the screen to the respective section
+{-| Syncs the position of of the viewport
 -}
-jumpTo : section -> Model section -> Cmd (Msg msg)
-jumpTo section { labels } =
-    Dom.getElement (section |> labels)
+getPos : Task x (ScrollingNav selection -> ScrollingNav selection)
+getPos =
+    Dom.getViewport
+        |> Task.map
+            (\int model ->
+                { model
+                    | scrollPos = int.viewport.y |> round
+                }
+            )
+
+
+{-| sets the position of the viewport to show a specific section
+-}
+setPos : Int -> ScrollingNav section -> ScrollingNav section
+setPos pos model =
+    { model | scrollPos = pos }
+
+
+{-| Scrolls the screen to the respective section
+-}
+jumpTo :
+    { section : section
+    , onChange : Result Dom.Error () -> msg
+    }
+    -> ScrollingNav section
+    -> Cmd msg
+jumpTo { section, onChange } { toString } =
+    Dom.getElement (section |> toString)
         |> Task.andThen
             (\{ element } ->
-                Dom.setViewport 0 (element.y)
+                Dom.setViewport 0 element.y
             )
-        |> Task.attempt ChangedViewport
+        |> Task.attempt onChange
 
-{-| scrolls the screen to the respective section with some offset
+
+{-| Scrolls the screen to the respective section with some offset
 -}
-jumpToWithOffset : Float -> section -> Model section -> Cmd (Msg msg)
-jumpToWithOffset offset section { labels } =
-    Dom.getElement (section |> labels)
+jumpToWithOffset :
+    { offset : Float
+    , section : section
+    , onChange : Result Dom.Error () -> msg
+    }
+    -> ScrollingNav section
+    -> Cmd msg
+jumpToWithOffset { offset, section, onChange } { toString } =
+    Dom.getElement (section |> toString)
         |> Task.andThen
             (\{ element } ->
                 Dom.setViewport 0 (element.y - offset)
             )
-        |> Task.attempt ChangedViewport
+        |> Task.attempt onChange
 
-{-| -}
-syncPositions : Model section -> Cmd (Msg section)
-syncPositions { labels, arrangement } =
+
+{-| Updates the positions of all sections.
+This functions should be called regularly if the height of elements on your page can change during time.
+-}
+syncPositions : ScrollingNav section -> Task Dom.Error (ScrollingNav section -> ScrollingNav section)
+syncPositions { toString, arrangement } =
     arrangement
         |> List.map
             (\label ->
-                Dom.getElement (labels label)
+                Dom.getElement (toString label)
                     |> Task.map
-                        (.element
-                            >> .y
-                            >> round
+                        (\x ->
+                            ( x.element.y |> round
+                            , label
+                            )
                         )
-                    |> Task.attempt
-                        (GotHeaderPos label)
             )
-        |> Cmd.batch
+        |> Task.sequence
+        |> Task.map
+            (\list m ->
+                list
+                    |> List.foldl
+                        (\( pos, label ) model ->
+                            { model
+                                | positions =
+                                    model.positions
+                                        |> IntDict.insert pos
+                                            (label |> model.toString)
+                            }
+                        )
+                        m
+            )
 
 
-{-| -}
-current : (String -> Maybe section) -> Model section -> Maybe section
+{-| Returns the current section
+-}
+current : (String -> Maybe section) -> ScrollingNav section -> Maybe section
 current fromString { positions, scrollPos } =
     positions
         |> IntDict.before (scrollPos + 1)
@@ -166,42 +160,72 @@ current fromString { positions, scrollPos } =
         |> Maybe.andThen fromString
 
 
-{-| -}
-viewSections :
-    { label : String -> Element msg
-    , fromString : String -> Maybe section
-    , msgMapper : Msg section -> msg
-    , attributes : Bool -> List (Attribute msg)
-    }
-    -> Model section
-    ->
-        { selected : Maybe section
-        , options : List section
-        , label : section -> Element msg
-        , onChange : section -> msg
-        , attributes : Bool -> List (Attribute msg)
-        }
-viewSections { label, fromString, msgMapper, attributes } ({ arrangement, scrollPos, labels, positions } as model) =
-    { selected = model |> current fromString
-    , options = arrangement
-    , label = \elem -> label (elem |> labels)
-    , onChange = JumpTo >> msgMapper
-    , attributes = attributes
+{-| Returns a select widget containing all section, with the current section selected.
+-}
+toSelect : (Int -> Maybe msg) -> ScrollingNav section -> Select msg
+toSelect onSelect ({ arrangement, toString, fromString } as model) =
+    { selected =
+        arrangement
+            |> List.indexedMap (\i s -> ( i, s ))
+            |> List.filterMap
+                (\( i, s ) ->
+                    if Just s == current fromString model then
+                        Just i
+
+                    else
+                        Nothing
+                )
+            |> List.head
+    , options =
+        arrangement
+            |> List.map
+                (\s ->
+                    { text = toString s
+                    , icon = Element.none
+                    }
+                )
+    , onSelect = onSelect
     }
 
 
-{-| -}
+{-| Opinionated way of viewing the section.
+
+This might be useful at first, but you should consider writing your own view function.
+
+```
 view :
     (section -> Element msg)
     -> Model section
-    -> Element msg
-view asElement { labels, arrangement } =
+    -> List (Element msg)
+view asElement { toString, arrangement } =
     arrangement
         |> List.map
             (\header ->
                 Element.el
                     [ header
-                        |> labels
+                        |> toString
+                        |> Attributes.id
+                        |> Element.htmlAttribute
+                    , Element.width <| Element.fill
+                    ]
+                <|
+                    asElement <|
+                        header
+            )
+```
+
+-}
+view :
+    (section -> Element msg)
+    -> ScrollingNav section
+    -> List (Element msg)
+view asElement { toString, arrangement } =
+    arrangement
+        |> List.map
+            (\header ->
+                Element.el
+                    [ header
+                        |> toString
                         |> Attributes.id
                         |> Element.htmlAttribute
                     , Element.width <| Element.fill
@@ -210,4 +234,3 @@ view asElement { labels, arrangement } =
                     asElement <|
                         header
             )
-        |> Element.column Grid.simple
diff --git a/src/Widget/Snackbar.elm b/src/Widget/Snackbar.elm
index aa2eadc..e84c77d 100644
--- a/src/Widget/Snackbar.elm
+++ b/src/Widget/Snackbar.elm
@@ -1,14 +1,16 @@
 module Widget.Snackbar exposing
-    ( Model, init, current, timePassed
+    ( Snackbar, Message, init, current, timePassed, view
     , insert, insertFor, dismiss
     )
 
-{-| A [snackbar](https://material.io/components/snackbars/) shows notification, one at a time.
+{-| ![Snackbar](https://orasund.github.io/elm-ui-widgets/assets/snackbar.png)
+
+A [snackbar](https://material.io/components/snackbars/) shows notification, one at a time.
 
 
 # Basics
 
-@docs Model, init, current, timePassed
+@docs Snackbar, Message, init, current, timePassed, view
 
 
 # Operations
@@ -17,12 +19,22 @@ module Widget.Snackbar exposing
 
 -}
 
+import Element exposing (Element)
 import Queue exposing (Queue)
+import Widget exposing (TextButton)
+import Widget.Style exposing (SnackbarStyle)
+
+{-| A message with maybe some action button
+-}
+type alias Message msg =
+    { text : String
+    , button : Maybe (TextButton msg)
+    }
 
 
 {-| A snackbar has a queue of Notifications, each with the amount of ms the message should be displayed
 -}
-type alias Model a =
+type alias Snackbar a =
     { queue : Queue ( a, Int )
     , current : Maybe ( a, Int )
     }
@@ -30,7 +42,7 @@ type alias Model a =
 
 {-| Inital state
 -}
-init : Model a
+init : Snackbar a
 init =
     { queue = Queue.empty
     , current = Nothing
@@ -39,14 +51,14 @@ init =
 
 {-| Insert a message that will last for 10 seconds.
 -}
-insert : a -> Model a -> Model a
+insert : a -> Snackbar a -> Snackbar a
 insert =
     insertFor 10000
 
 
 {-| Insert a message for a specific amount of milli seconds.
 -}
-insertFor : Int -> a -> Model a -> Model a
+insertFor : Int -> a -> Snackbar a -> Snackbar a
 insertFor removeIn a model =
     case model.current of
         Nothing ->
@@ -58,7 +70,7 @@ insertFor removeIn a model =
 
 {-| Dismiss the current message.
 -}
-dismiss : Model a -> Model a
+dismiss : Snackbar a -> Snackbar a
 dismiss model =
     { model | current = Nothing }
 
@@ -66,7 +78,7 @@ dismiss model =
 {-| Updates the model. This functions should be called regularly.
 The first argument is the milli seconds that passed since the last time the function was called.
 -}
-timePassed : Int -> Model a -> Model a
+timePassed : Int -> Snackbar a -> Snackbar a
 timePassed ms model =
     case model.current of
         Nothing ->
@@ -89,6 +101,33 @@ timePassed ms model =
 
 {-| Returns the current element.
 -}
-current : Model a -> Maybe a
+current : Snackbar a -> Maybe a
 current model =
     model.current |> Maybe.map Tuple.first
+
+
+{-| Views the current Message. (only one at a time)
+-}
+view :
+    SnackbarStyle msg
+    -> (a -> Message msg)
+    -> Snackbar a
+    -> Maybe (Element msg)
+view style toMessage model =
+    model
+        |> current
+        |> Maybe.map
+            (toMessage
+                >> (\{ text, button } ->
+                        [ text
+                            |> Element.text
+                            |> List.singleton
+                            |> Element.paragraph style.text
+                        , button
+                            |> Maybe.map
+                                (Widget.textButton style.button)
+                            |> Maybe.withDefault Element.none
+                        ]
+                            |> Element.row style.containerRow
+                   )
+            )
diff --git a/src/Widget/SortTable.elm b/src/Widget/SortTable.elm
deleted file mode 100644
index 1b2e41e..0000000
--- a/src/Widget/SortTable.elm
+++ /dev/null
@@ -1,215 +0,0 @@
-module Widget.SortTable exposing
-    ( Model, init, view, sortBy
-    , intColumn, floatColumn, stringColumn
-    )
-
-{-| A Sortable list allows you to sort coulmn.
-
-        SortTable.view
-            { content =
-                [ {id = 1, name = "Antonio", rating = 2.456}
-                , {id = 2, name = "Ana", rating = 1.34}
-                , {id = 3, name = "Alfred", rating = 4.22}
-                , {id = 4, name = "Thomas", rating = 3 }
-                ]
-            , columns =
-                [ SortTable.intColumn
-                    { title = "Id"
-                    , value = .id
-                    , toString = \int -> "#" ++ String.fromInt int
-                    }
-                , SortTable.stringColumn
-                    { title = "Name"
-                    , value = .name
-                    , toString = identity
-                    }
-                , SortTable.floatColumn
-                    { title = "rating"
-                    , value = .rating
-                    , toString = String.fromFloat
-                    }
-                ]
-            , model = model
-            }
-            |> (\{data,columns} ->
-                {data = data
-                ,columns = columns
-                    |> List.map (\config->
-                            { header =
-                                Input.button [Font.bold]
-                                    { onPress =
-                                        { title = config.header
-                                        , asc =
-                                            if config.header == model.title then
-                                                not model.asc
-                                            else
-                                                True
-                                        }
-                                            |> SortBy
-                                            |> Just
-                                    , label =
-                                        if config.header == model.title then
-                                            [ config.header |> Element.text
-                                            , Element.text <|
-                                                if model.asc then
-                                                    "/\"
-                                                else
-                                                    "\/"
-                                            ]
-                                                |> Element.row [Font.bold]
-                                        else
-                                            config.header  |> Element.text
-                                    }
-                            , view = config.view >> Element.text
-                            , width = Element.fill
-                            }
-                        )
-                })
-            |> Element.table []
-
-
-# Basics
-
-@docs Model, init, view, sortBy
-
-
-# Columns
-
-@docs intColumn, floatColumn, stringColumn
-
--}
-
-
-type ColumnType a
-    = StringColumn { value : a -> String, toString : String -> String }
-    | IntColumn { value : a -> Int, toString : Int -> String }
-    | FloatColumn { value : a -> Float, toString : Float -> String }
-
-
-{-| The Model contains the sorting column name and if ascending or descending.
--}
-type alias Model =
-    { title : String
-    , asc : Bool
-    }
-
-
-type alias Column a =
-    { title : String
-    , content : ColumnType a
-    }
-
-
-{-| The initial State setting the sorting column name to the empty string.
--}
-init : Model
-init =
-    { title = "", asc = True }
-
-
-{-| A Column containing a Int
--}
-intColumn : { title : String, value : a -> Int, toString : Int -> String } -> Column a
-intColumn { title, value, toString } =
-    { title = title
-    , content = IntColumn { value = value, toString = toString }
-    }
-
-
-{-| A Column containing a Float
--}
-floatColumn : { title : String, value : a -> Float, toString : Float -> String } -> Column a
-floatColumn { title, value, toString } =
-    { title = title
-    , content = FloatColumn { value = value, toString = toString }
-    }
-
-
-{-| A Column containing a String
--}
-stringColumn : { title : String, value : a -> String, toString : String -> String } -> Column a
-stringColumn { title, value, toString } =
-    { title = title
-    , content = StringColumn { value = value, toString = toString }
-    }
-
-
-{-| Change the sorting criteras.
-
-        sortBy =
-            identity
-
--}
-sortBy : { title : String, asc : Bool } -> Model
-sortBy =
-    identity
-
-
-{-| The View
--}
-view :
-    { content : List a
-    , columns : List (Column a)
-    , model : Model
-    }
-    ->
-        { data : List a
-        , columns : List { header : String, view : a -> String }
-        }
-view { content, columns, model } =
-    let
-        findTitle : List (Column a) -> Maybe (ColumnType a)
-        findTitle list =
-            case list of
-                [] ->
-                    Nothing
-
-                head :: tail ->
-                    if head.title == model.title then
-                        Just head.content
-
-                    else
-                        findTitle tail
-    in
-    { data =
-        content
-            |> (columns
-                    |> findTitle
-                    |> Maybe.map
-                        (\c ->
-                            case c of
-                                StringColumn { value } ->
-                                    List.sortBy value
-
-                                IntColumn { value } ->
-                                    List.sortBy value
-
-                                FloatColumn { value } ->
-                                    List.sortBy value
-                        )
-                    |> Maybe.withDefault identity
-               )
-            |> (if model.asc then
-                    identity
-
-                else
-                    List.reverse
-               )
-    , columns =
-        columns
-            |> List.map
-                (\column ->
-                    { header = column.title
-                    , view =
-                        case column.content of
-                            IntColumn { value, toString } ->
-                                value >> toString
-
-                            FloatColumn { value, toString } ->
-                                value >> toString
-
-                            StringColumn { value, toString } ->
-                                value >> toString
-                    }
-                )
-    }
diff --git a/src/Widget/Style.elm b/src/Widget/Style.elm
new file mode 100644
index 0000000..0ce5cf2
--- /dev/null
+++ b/src/Widget/Style.elm
@@ -0,0 +1,134 @@
+module Widget.Style exposing (ButtonStyle,ColumnStyle, DialogStyle, ExpansionPanelStyle, LayoutStyle, RowStyle, SnackbarStyle, SortTableStyle, TabStyle, TextInputStyle)
+
+{-| This module contains style types for every widget.
+
+@docs ButtonStyle, ColumnStyle, DialogStyle, ExpansionPanelStyle, LayoutStyle, RowStyle, SnackbarStyle, SortTableStyle, TabStyle, TextInputStyle
+
+-}
+
+import Element exposing (Attribute, Element)
+import Html exposing (Html)
+
+
+{-| -}
+type alias ButtonStyle msg =
+    { container : List (Attribute msg)
+    , labelRow : List (Attribute msg)
+    , text : List (Attribute msg)
+    , ifDisabled : List (Attribute msg)
+    , ifActive : List (Attribute msg)
+    , otherwise : List (Attribute msg)
+    }
+
+
+{-| -}
+type alias DialogStyle msg =
+    { containerColumn : List (Attribute msg)
+    , title : List (Attribute msg)
+    , buttonRow : List (Attribute msg)
+    , acceptButton : ButtonStyle msg
+    , dismissButton : ButtonStyle msg
+    , text : List (Attribute msg)
+    }
+
+
+{-| Technical Remark:
+
+  - If icons are defined in Svg, they might not display correctly.
+    To avoid that, make sure to wrap them in `Element.html >> Element.el []`
+
+-}
+type alias ExpansionPanelStyle msg =
+    { containerColumn : List (Attribute msg)
+    , panelRow : List (Attribute msg)
+    , labelRow : List (Attribute msg)
+    , content : List (Attribute msg)
+    , expandIcon : Element Never
+    , collapseIcon : Element Never
+    }
+
+
+{-| -}
+type alias SnackbarStyle msg =
+    { containerRow : List (Attribute msg)
+    , text : List (Attribute msg)
+    , button : ButtonStyle msg
+    }
+
+
+{-| -}
+type alias TextInputStyle msg =
+    { chipButton : ButtonStyle msg
+    , containerRow : List (Attribute msg)
+    , chipsRow : List (Attribute msg)
+    , input : List (Attribute msg)
+    }
+
+
+{-| -}
+type alias TabStyle msg =
+    { button : ButtonStyle msg
+    , optionRow : List (Attribute msg)
+    , containerColumn : List (Attribute msg)
+    , content : List (Attribute msg)
+    }
+
+
+{-| -}
+type alias RowStyle msg =
+    { containerRow : List (Attribute msg)
+    , element : List (Attribute msg)
+    , ifFirst : List (Attribute msg)
+    , ifLast : List (Attribute msg)
+    , otherwise : List (Attribute msg)
+    }
+
+
+{-| -}
+type alias ColumnStyle msg =
+    { containerColumn : List (Attribute msg)
+    , element : List (Attribute msg)
+    , ifFirst : List (Attribute msg)
+    , ifLast : List (Attribute msg)
+    , otherwise : List (Attribute msg)
+    }
+
+
+{-| Technical Remark:
+
+  - If icons are defined in Svg, they might not display correctly.
+    To avoid that, make sure to wrap them in `Element.html >> Element.el []`
+
+-}
+type alias SortTableStyle msg =
+    { containerTable : List (Attribute msg)
+    , headerButton : ButtonStyle msg
+    , ascIcon : Element Never
+    , descIcon : Element Never
+    , defaultIcon : Element Never
+    }
+
+
+{-| Technical Remark:
+
+  - If icons are defined in Svg, they might not display correctly.
+    To avoid that, make sure to wrap them in `Element.html >> Element.el []`
+
+-}
+type alias LayoutStyle msg =
+    { container : List (Attribute msg)
+    , snackbar : SnackbarStyle msg
+    , layout : List (Attribute msg) -> Element msg -> Html msg
+    , header : List (Attribute msg)
+    , sheet : List (Attribute msg)
+    , sheetButton : ButtonStyle msg
+    , menuButton : ButtonStyle msg
+    , menuTabButton : ButtonStyle msg
+    , menuIcon : Element Never
+    , moreVerticalIcon : Element Never
+    , spacing : Int
+    , title : List (Attribute msg)
+    , searchIcon : Element Never
+    , search : List (Attribute msg)
+    , searchFill : List (Attribute msg)
+    }
diff --git a/src/Widget/Style/Material.elm b/src/Widget/Style/Material.elm
new file mode 100644
index 0000000..12dcc46
--- /dev/null
+++ b/src/Widget/Style/Material.elm
@@ -0,0 +1,1569 @@
+module Widget.Style.Material exposing
+    ( Palette, defaultPalette, darkPalette
+    , containedButton, outlinedButton, textButton
+    , iconButton, toggleButton, buttonRow
+    , chip, textInput
+    , alertDialog
+    , expansionPanel
+    , row, column
+    , cardColumn
+    , layout, snackbar, tab, tabButton
+    )
+
+{-| ![Example using the Material Design style](https://orasund.github.io/elm-ui-widgets/assets/material-style.png)
+
+This module implements a Material design theme for all widgets.
+
+The stylings are following [the official Material Design guidelines](https://material.io/components) as close as possible.
+Please use these widgets in combination with the official guidelines.
+
+The typograpahy is taken from [the material design guidelines](https://material.io/design/typography/the-type-system.html#type-scale).
+Its recommended to use a font size of 16px width and the [Roboto Font](https://fonts.google.com/specimen/Roboto?query=Ro).
+
+The style are not opaque, so you can change every styling to your needs.
+
+If you have any suggestions or improvements, be sure to leave a PR or a Issue over at the github repos.
+
+You can use the theme by copying the following code:
+
+```
+type alias Style msg =
+    { dialog : DialogStyle msg
+    , expansionPanel : ExpansionPanelStyle msg
+    , button : ButtonStyle msg
+    , primaryButton : ButtonStyle msg
+    , tab : TabStyle msg
+    , textInput : TextInputStyle msg
+    , chipButton : ButtonStyle msg
+    , row : RowStyle msg
+    , buttonRow : RowStyle msg
+    , column : ColumnStyle msg
+    , cardColumn : ColumnStyle msg
+    , sortTable : SortTableStyle msg
+    , selectButton : ButtonStyle msg
+    , layout : LayoutStyle msg
+    }
+
+sortTable : Palette -> SortTableStyle msg
+sortTable palette =
+    { containerTable = []
+    , headerButton = Material.textButton palette
+    , ascIcon = Icons.chevronUp |> Element.html |> Element.el []
+    , descIcon = Icons.chevronDown |> Element.html |> Element.el []
+    , defaultIcon = Element.none
+    }
+
+
+style : Palette -> Style msg
+style palette =
+    { sortTable = sortTable palette
+    , row = Material.row
+    , buttonRow = Material.buttonRow
+    , cardColumn = Material.cardColumn palette
+    , column = Material.column
+    , button = Material.outlinedButton palette
+    , primaryButton = Material.containedButton palette
+    , selectButton = Material.toggleButton palette
+    , tab = Material.tab palette
+    , textInput = Material.textInput palette
+    , chipButton = Material.chip palette
+    , expansionPanel = Material.expansionPanel palette
+    , dialog = Material.alertDialog palette
+    , layout = Material.layout palette
+    }
+```
+
+# Palette
+
+@docs Palette, defaultPalette, darkPalette
+
+
+# Button
+
+Different styles for buttons have different meanings.
+
+  - Use `textButton` as your default button
+  - Use `containedButton` for any important action
+  - Use `outlinedButton` if you have more then one important action.
+    Use `containedButton` for **the most** important action of the group.
+
+@docs containedButton, outlinedButton, textButton
+
+@docs iconButton, toggleButton, buttonRow
+
+# Card
+
+In the material design specification the card is not really specified at all.
+Im practice the List seams more useful then a own card widget.
+Thus for now we only provide a card containing a list.
+
+@docs cardColumn
+
+# Chip
+
+@docs chip, textInput
+
+# Dialog
+
+@docs alertDialog
+
+
+# Expansion Panel
+
+@docs expansionPanel
+
+
+# List
+
+The [List widget](https://material.io/components/lists) is a very complex widget that sadly only particially made it into this package.
+
+@docs row, column
+
+# Snackbar
+
+@docs snackbar
+
+# Tab
+
+@docs tab, tabButton
+
+# Layout
+
+@docs layout
+-}
+
+import Color exposing (Color)
+import Color.Accessibility as Accessibility
+import Color.Convert as Convert
+import Element exposing (Attribute, Element)
+import Element.Background as Background
+import Element.Border as Border
+import Element.Font as Font
+import Html.Attributes as Attributes
+import Svg exposing (Svg)
+import Svg.Attributes
+import Widget.Style
+    exposing
+        ( ButtonStyle
+        , ColumnStyle
+        , DialogStyle
+        , ExpansionPanelStyle
+        , LayoutStyle
+        , RowStyle
+        , SnackbarStyle
+        , TabStyle
+        , TextInputStyle
+        )
+
+
+
+{-------------------------------------------------------------------------------
+-- T Y P O G R A P H Y
+-------------------------------------------------------------------------------}
+
+
+buttonFont : List (Attribute msg)
+buttonFont =
+    [ Element.htmlAttribute <| Attributes.style "text-transform" "uppercase"
+    , Font.size 14
+    , Font.semiBold --medium
+    , Font.letterSpacing 1.25
+    ]
+
+
+h6 : List (Attribute msg)
+h6 =
+    [ Font.size 20
+    , Font.semiBold --medium
+    , Font.letterSpacing 0.15
+    ]
+
+
+
+{-------------------------------------------------------------------------------
+-- C O L O R
+-------------------------------------------------------------------------------}
+
+
+{-| The material design comes with customizable color palettes.
+
+Check out [the official documentation about the color system](https://material.io/design/color/the-color-system.html#color-theme-creation) to see how these colors are used.
+
+For the `-on` colors you can use white, for transitions into white, or black,for transitions into black. Other colors are also possible, but i've not seen any website acutally using a different color.
+
+-}
+type alias Palette =
+    { primary : Color --Color.rgb255 0x62 0x00 0xEE
+    , secondary : Color --Color.rgb255 0x03 0xda 0xc6
+    , background : Color --Color.rgb255 0xFF 0xFF 0xFF
+    , surface : Color --Color.rgb255 0xFF 0xFF 0xFF
+    , error : Color --Color.rgb255 0xB0 0x00 0x20
+    , on :
+        { primary : Color --Color.rgb255 0xFF 0xFF 0xFF
+        , secondary : Color --Color.rgb255 0x00 0x00 0x00
+        , background : Color --Color.rgb255 0x00 0x00 0x00
+        , surface : Color --Color.rgb255 0x00 0x00 0x00
+        , error : Color --Color.rgb255 0xFF 0xFF 0xFF
+        }
+    }
+
+
+{-| The default color theme.
+
+![The default theme](https://lh3.googleusercontent.com/k6WO1fd7T40A9JvSVfHqs0CPLFyTEDCecsVGxEDhOaTP0wUTPYOVVkxt60hKxBprgNoMqs8OyKqtlaQ4tDBtQJs-fTcZrpZEjxhUVQ=w1064-v0)
+
+_Image take from [material.io](https://material.io/design/color/the-color-system.html#color-theme-creation)_
+
+-}
+defaultPalette : Palette
+defaultPalette =
+    { primary = Color.rgb255 0x62 0x00 0xEE
+    , secondary = Color.rgb255 0x03 0xDA 0xC6
+    , background = Color.rgb255 0xFF 0xFF 0xFF
+    , surface = Color.rgb255 0xFF 0xFF 0xFF
+    , error = Color.rgb255 0xB0 0x00 0x20
+    , on =
+        { primary = Color.rgb255 0xFF 0xFF 0xFF
+        , secondary = Color.rgb255 0x00 0x00 0x00
+        , background = Color.rgb255 0x00 0x00 0x00
+        , surface = Color.rgb255 0x00 0x00 0x00
+        , error = Color.rgb255 0xFF 0xFF 0xFF
+        }
+    }
+
+
+{-| The offical dark theme of google.
+
+![The dark theme](https://lh3.googleusercontent.com/tv7J2o4ZiSmLYwyBslBs_PLzKyzI8QUV5qdvHGfoAQn9r7pY4Hj5SmW27m3zUWeDtRSE8Cb5_5PQmkbavDfw7XbIL8EodIKZhilRdg=w1064-v0)
+
+_Image take from [material.io](https://material.io/design/color/dark-theme.html#ui-application)_
+
+-}
+darkPalette : Palette
+darkPalette =
+    { primary = Color.rgb255 0xBB 0x86 0xFC
+    , secondary = Color.rgb255 0x03 0xDA 0xC6
+    , background = Color.rgb255 0x12 0x12 0x12
+    , surface = Color.rgb255 0x12 0x12 0x12
+    , error = Color.rgb255 0xCF 0x66 0x79
+    , on =
+        { primary = Color.rgb255 0x00 0x00 0x00
+        , secondary = Color.rgb255 0x00 0x00 0x00
+        , background = Color.rgb255 0xFF 0xFF 0xFF
+        , surface = Color.rgb255 0xFF 0xFF 0xFF
+        , error = Color.rgb255 0x00 0x00 0x00
+        }
+    }
+
+
+buttonHoverOpacity : Float
+buttonHoverOpacity =
+    0.08
+
+
+buttonFocusOpacity : Float
+buttonFocusOpacity =
+    0.24
+
+
+buttonPressedOpacity : Float
+buttonPressedOpacity =
+    0.32
+
+
+buttonDisabledOpacity : Float
+buttonDisabledOpacity =
+    0.38
+
+
+buttonSelectedOpacity : Float
+buttonSelectedOpacity =
+    0.16
+
+
+accessibleTextColor : Color -> Color
+accessibleTextColor color =
+    let
+        l : Float
+        l =
+            1
+                + (color |> Color.toRgba |> .alpha)
+                * (Accessibility.luminance color - 1)
+    in
+    if (1.05 / (l + 0.05)) < 7 then
+        Color.rgb255 0 0 0
+
+    else
+        Color.rgb255 255 255 255
+
+
+accessibleWithTextColor : Color -> Color -> Color
+accessibleWithTextColor c color =
+    let
+        l1 : Float
+        l1 =
+            1
+                + (c |> Color.toRgba |> .alpha)
+                * (Accessibility.luminance c - 1)
+
+        l2 : Float
+        l2 =
+            1
+                + (color |> Color.toRgba |> .alpha)
+                * (Accessibility.luminance color - 1)
+
+        newConstrast : Float
+        newConstrast =
+            7
+
+        lighterLuminance : Float
+        lighterLuminance =
+            newConstrast * (l2 + 0.05) - 0.05
+
+        darkerLuminance : Float
+        darkerLuminance =
+            (l2 + 0.05) - 0.05 / newConstrast
+    in
+    c
+        |> (if l1 > l2 then
+                if ((l1 + 0.05) / (l2 + 0.05)) < 7 then
+                    Convert.colorToLab
+                        >> (\col ->
+                                { col | l = 100 * lighterLuminance }
+                           )
+                        >> Convert.labToColor
+
+                else
+                    identity
+
+            else if ((l2 + 0.05) / (l1 + 0.05)) < 7 then
+                Convert.colorToLab
+                    >> (\col ->
+                            { col | l = 100 * darkerLuminance }
+                       )
+                    >> Convert.labToColor
+
+            else
+                identity
+           )
+
+
+toCIELCH : Color -> { l : Float, c : Float, h : Float }
+toCIELCH =
+    Convert.colorToLab
+        >> (\{ l, a, b } ->
+                { l = l
+                , c = sqrt (a * a + b * b)
+                , h = atan2 b a
+                }
+           )
+
+
+fromCIELCH : { l : Float, c : Float, h : Float } -> Color
+fromCIELCH =
+    (\{ l, c, h } ->
+        { l = l
+        , a = c * cos h
+        , b = c * sin h
+        }
+    )
+        >> Convert.labToColor
+
+
+{-| using noahzgordon/elm-color-extra for colors
+-}
+withShade : Color -> Float -> Color -> Color
+withShade c2 amount c1 =
+    let
+        alpha =
+            c1
+                |> Color.toRgba
+                |> .alpha
+
+        fun a b =
+            { l = (a.l * (1 - amount) + b.l * amount) / 1
+            , c = (a.c * (1 - amount) + b.c * amount) / 1
+            , h = (a.h * (1 - amount) + b.h * amount) / 1
+            }
+    in
+    fun (toCIELCH c1) (toCIELCH c2)
+        |> fromCIELCH
+        |> Color.toRgba
+        |> (\color -> { color | alpha = alpha })
+        |> Color.fromRgba
+
+
+scaleOpacity : Float -> Color -> Color
+scaleOpacity opacity =
+    Color.toRgba
+        >> (\color -> { color | alpha = color.alpha * opacity })
+        >> Color.fromRgba
+
+
+gray : Color
+gray =
+    Color.rgb255 0x77 0x77 0x77
+
+
+dark : Color
+dark =
+    Color.rgb255 50 50 50
+
+
+fromColor : Color -> Element.Color
+fromColor =
+    Color.toRgba >> Element.fromRgb
+
+
+shadow :
+    Float
+    ->
+        { offset : ( Float, Float )
+        , size : Float
+        , blur : Float
+        , color : Element.Color
+        }
+shadow float =
+    { color = Element.rgba255 0x00 0x00 0x00 0.2
+    , offset = ( 0, float )
+    , size = 0
+    , blur = float
+    }
+
+
+textAndBackground : Color -> List (Element.Attr decorative msg)
+textAndBackground color =
+    [ color
+        |> fromColor
+        |> Background.color
+    , color
+        |> accessibleTextColor
+        |> fromColor
+        |> Font.color
+    ]
+
+
+
+{-------------------------------------------------------------------------------
+-- B U T T O N
+-------------------------------------------------------------------------------}
+
+
+baseButton : Palette -> ButtonStyle msg
+baseButton _ =
+    { container =
+        buttonFont
+            ++ [ Element.height <| Element.px 36
+               , Element.paddingXY 8 8
+               , Border.rounded <| 4
+               ]
+    , labelRow =
+        [ Element.spacing <| 8
+        , Element.width <| Element.minimum 32 <| Element.shrink
+        , Element.centerY
+        ]
+    , text = [ Element.centerX ]
+    , ifDisabled =
+        [ Element.htmlAttribute <| Attributes.style "cursor" "not-allowed"
+        ]
+    , ifActive = []
+    , otherwise = []
+    }
+
+
+{-| A contained button representing the most important action of a group.
+
+![Contained Button](https://material.io/develop/images/content/79e62add1830d33fc90edb22212bce53.svg)
+
+_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_
+
+-}
+containedButton : Palette -> ButtonStyle msg
+containedButton palette =
+    { container =
+        (baseButton palette |> .container)
+            ++ [ Border.shadow <| shadow 2
+               , Element.mouseDown <|
+                    (palette.primary
+                        |> withShade palette.on.primary buttonPressedOpacity
+                        |> textAndBackground
+                    )
+                        ++ [ Border.shadow <| shadow 12 ]
+               , Element.focused <|
+                    (palette.primary
+                        |> withShade palette.on.primary buttonFocusOpacity
+                        |> textAndBackground
+                    )
+                        ++ [ Border.shadow <| shadow 6 ]
+               , Element.mouseOver <|
+                    (palette.primary
+                        |> withShade palette.on.primary buttonHoverOpacity
+                        |> textAndBackground
+                    )
+                        ++ [ Border.shadow <| shadow 6 ]
+               ]
+    , labelRow =
+        (baseButton palette |> .labelRow)
+            ++ [ Element.paddingXY 8 0
+               ]
+    , text = baseButton palette |> .text
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> scaleOpacity buttonDisabledOpacity
+                    |> fromColor
+                    |> Background.color
+               , Font.color <| fromColor <| gray
+               , Border.shadow <| shadow 0
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        palette.primary
+            |> withShade palette.on.primary buttonHoverOpacity
+            |> textAndBackground
+    , otherwise =
+        palette.primary
+            |> textAndBackground
+    }
+
+
+{-| A outlined button representing an important action within a group.
+
+![Contained Button](https://material.io/develop/images/content/2b50635d38c5fdec260f09be9aeafb10.svg)
+
+_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_
+
+-}
+outlinedButton : Palette -> ButtonStyle msg
+outlinedButton palette =
+    { container =
+        (baseButton palette |> .container)
+            ++ [ Border.width <| 1
+               , Border.color <| fromColor <| gray
+               , Font.color <| fromColor <| palette.primary
+               , Element.mouseDown
+                    [ palette.primary
+                        |> scaleOpacity buttonPressedOpacity
+                        |> fromColor
+                        |> Background.color
+                    , gray
+                        |> withShade palette.primary buttonPressedOpacity
+                        |> fromColor
+                        |> Border.color
+                    ]
+               , Element.focused
+                    [ palette.primary
+                        |> scaleOpacity buttonFocusOpacity
+                        |> fromColor
+                        |> Background.color
+                    , gray
+                        |> withShade palette.primary buttonFocusOpacity
+                        |> fromColor
+                        |> Border.color
+                    ]
+               , Element.mouseOver
+                    [ palette.primary
+                        |> scaleOpacity buttonHoverOpacity
+                        |> fromColor
+                        |> Background.color
+                    , gray
+                        |> withShade palette.primary buttonHoverOpacity
+                        |> fromColor
+                        |> Border.color
+                    ]
+               ]
+    , labelRow =
+        (baseButton palette |> .labelRow)
+            ++ [ Element.paddingXY 8 0
+               ]
+    , text = baseButton palette |> .text
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        [ palette.primary
+            |> scaleOpacity buttonHoverOpacity
+            |> fromColor
+            |> Background.color
+        , gray
+            |> withShade palette.primary buttonHoverOpacity
+            |> fromColor
+            |> Border.color
+        ]
+    , otherwise =
+        []
+    }
+
+
+{-| A text button representing a simple action within a group.
+
+![Text Button](https://material.io/develop/images/content/d3079632c6f54d86f9b7093d541c2ee9.svg)
+
+_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_
+
+-}
+textButton : Palette -> ButtonStyle msg
+textButton palette =
+    { container =
+        (baseButton palette |> .container)
+            ++ [ Font.color <| fromColor <| palette.primary
+               , Element.mouseDown
+                    [ palette.primary
+                        |> scaleOpacity buttonPressedOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.focused
+                    [ palette.primary
+                        |> scaleOpacity buttonFocusOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.mouseOver
+                    [ palette.primary
+                        |> scaleOpacity buttonHoverOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               ]
+    , labelRow = baseButton palette |> .labelRow
+    , text = baseButton palette |> .text
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        [ palette.primary
+            |> scaleOpacity buttonHoverOpacity
+            |> fromColor
+            |> Background.color
+        ]
+    , otherwise =
+        []
+    }
+
+
+{-| A ToggleButton. Only use as a group in combination with `buttonRow`.
+
+![Toggle Button](https://material.io/develop/images/content/749a1ba8591d02356fa1d6eea2641d96.svg)
+
+_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_
+
+Toggle buttons should only be used with the `iconButton` widget, else use chips instead.
+
+Technical Remark:
+
+  - Border color was not defined in the [specification](https://material.io/components/buttons#toggle-button)
+  - There are two different versions, one where the selected color is gray and another where the color is primary.
+    I noticed the gray version was used more often, so i went with that one.
+
+-}
+toggleButton : Palette -> ButtonStyle msg
+toggleButton palette =
+    { container =
+        buttonFont
+            ++ [ Element.width <| Element.px 48
+               , Element.height <| Element.px 48
+               , Element.padding 4
+               , Border.width <| 1
+               , Element.mouseDown <|
+                    (palette.surface
+                        |> withShade palette.on.surface buttonPressedOpacity
+                        |> textAndBackground
+                    )
+                        ++ [ palette.on.surface
+                                |> scaleOpacity 0.14
+                                |> withShade palette.on.surface buttonPressedOpacity
+                                |> fromColor
+                                |> Border.color
+                           ]
+               , Element.focused []
+               , Element.mouseOver <|
+                    (palette.surface
+                        |> withShade palette.on.surface buttonHoverOpacity
+                        |> textAndBackground
+                    )
+                        ++ [ palette.on.surface
+                                |> scaleOpacity 0.14
+                                |> withShade palette.on.surface buttonHoverOpacity
+                                |> fromColor
+                                |> Border.color
+                           ]
+               ]
+    , labelRow =
+        [ Element.spacing <| 8
+        , Element.height Element.fill
+        , Element.width Element.fill
+        , Border.rounded 24
+        , Element.padding 8
+        , Element.focused <|
+            (palette.surface
+                |> withShade palette.on.surface buttonFocusOpacity
+                |> textAndBackground
+            )
+        ]
+    , text = [ Element.centerX ]
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ palette.surface
+                    |> fromColor
+                    |> Background.color
+               , palette.on.surface
+                    |> scaleOpacity 0.14
+                    |> fromColor
+                    |> Border.color
+               , gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               ]
+    , ifActive =
+        (palette.surface
+            |> withShade palette.on.surface buttonSelectedOpacity
+            |> textAndBackground
+        )
+            ++ [ palette.on.surface
+                    |> scaleOpacity 0.14
+                    |> withShade palette.on.surface buttonSelectedOpacity
+                    |> fromColor
+                    |> Border.color
+               , Element.mouseOver []
+               ]
+    , otherwise =
+        (palette.surface
+            |> textAndBackground
+        )
+            ++ [ palette.on.surface
+                    |> scaleOpacity 0.14
+                    |> fromColor
+                    |> Border.color
+               ]
+    }
+
+
+{-| An single selectable icon.
+
+![Icon Button](https://material.io/develop/images/content/9bc212d8a3ef79bb7ed83a5359651505.png)
+
+_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_
+
+Technical Remark:
+
+  - Could not find any specification details
+
+-}
+iconButton : Palette -> ButtonStyle msg
+iconButton palette =
+    { container =
+        (baseButton palette |> .container)
+            ++ [ Element.height <| Element.px 48
+               , Border.rounded 24
+
+               --, Font.color <| fromColor <| palette.primary
+               , Element.mouseDown
+                    [ palette.surface
+                        |> scaleOpacity buttonPressedOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.focused
+                    [ palette.surface
+                        |> scaleOpacity buttonFocusOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.mouseOver
+                    [ palette.surface
+                        |> scaleOpacity buttonHoverOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               ]
+    , labelRow =
+        [ Element.spacing 8
+        , Element.width <| Element.shrink
+        , Element.centerY
+        , Element.centerX
+        ]
+    , text = baseButton palette |> .text
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        [ palette.surface
+            |> scaleOpacity buttonHoverOpacity
+            |> fromColor
+            |> Background.color
+        ]
+    , otherwise =
+        []
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- C H I P
+-------------------------------------------------------------------------------}
+
+
+{-| Chips have the same behaviour as buttons but are visually less important.
+
+In the [official documentation](https://material.io/components/chips#types) chips have different names depending on where they are used:
+
+  - **Input Chips** are used inside a text field. Use `textInput` for this feature.
+  - **Choice Chips** are used for selcting an option.
+    The material design guidelines recommend using `toggleButton` for icons with no text and chips for text with no icons.
+  - **Filter Chips** are used for selecting multiple options. They typically have a done-icon when selected.
+  - **Action chips** are like button. Make sure to include an icon when using action chips.
+
+Technical Remark:
+
+  - There seems to be a bug, where in the mouseOver effects are now visible.
+    This might have something to do with .
+    This needs to be investigated, but for now i leave it at that.
+
+  - Desided against the implementation of an outlined chip.
+    Please open a new issue or a PR if you want to have it implemented.
+
+-}
+chip : Palette -> ButtonStyle msg
+chip palette =
+    { container =
+        [ Element.height <| Element.px 32
+        , Element.paddingEach
+            { top = 0
+            , right = 12
+            , bottom = 0
+            , left = 4
+            }
+        , Border.rounded <| 16
+        , Element.mouseDown <|
+            (palette.on.surface
+                |> scaleOpacity 0.12
+                |> withShade palette.on.surface buttonPressedOpacity
+                |> textAndBackground
+            )
+        , Element.focused <|
+            (palette.on.surface
+                |> scaleOpacity 0.12
+                |> withShade palette.on.surface buttonFocusOpacity
+                |> textAndBackground
+            )
+        , Element.mouseOver <|
+            (palette.on.surface
+                |> scaleOpacity 0.12
+                |> withShade palette.on.surface buttonHoverOpacity
+                |> textAndBackground
+            )
+        ]
+    , labelRow = [ Element.spacing 0, Element.centerY ]
+    , text =
+        [ Element.paddingEach
+            { top = 0
+            , right = 0
+            , bottom = 0
+            , left = 8
+            }
+        ]
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ (palette.on.surface
+                    |> scaleOpacity 0.12
+                    |> withShade palette.on.surface buttonDisabledOpacity
+                    |> textAndBackground
+               )
+            ++ [ Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        (palette.on.surface
+            |> scaleOpacity 0.12
+            |> withShade palette.on.surface buttonSelectedOpacity
+            |> textAndBackground
+        )
+            ++ [ Border.shadow <| shadow 4 ]
+    , otherwise =
+        palette.on.surface
+            |> scaleOpacity 0.12
+            |> textAndBackground
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- L I S T
+-------------------------------------------------------------------------------}
+
+
+{-| A simple styling for a row.
+-}
+row : RowStyle msg
+row =
+    { containerRow =
+        [ Element.paddingXY 0 8
+        , Element.spacing 8
+        ]
+    , element = []
+    , ifFirst = []
+    , ifLast = []
+    , otherwise = []
+    }
+
+
+{-| A simple styling for a column.
+-}
+column : ColumnStyle msg
+column =
+    { containerColumn =
+        [ Element.paddingXY 0 8
+        , Element.spacing 8
+        ]
+    , element = []
+    , ifFirst = []
+    , ifLast = []
+    , otherwise = []
+    }
+
+
+{-| a Row of buttons.
+
+Only use in combination with `toggleButton`
+
+-}
+buttonRow : RowStyle msg
+buttonRow =
+    { containerRow = []
+    , element =
+        [ Border.rounded 2
+        ]
+    , ifFirst =
+        [ Border.roundEach
+            { topLeft = 2
+            , topRight = 0
+            , bottomLeft = 2
+            , bottomRight = 0
+            }
+        ]
+    , ifLast =
+        [ Border.roundEach
+            { topLeft = 0
+            , topRight = 2
+            , bottomLeft = 0
+            , bottomRight = 2
+            }
+        ]
+    , otherwise =
+        [ Border.rounded 0
+        ]
+    }
+
+
+{-| A List styled like a card.
+
+Technical Remark:
+
+This is a simplification of the [Material Design Card
+](https://material.io/components/cards) and might get replaced at a later date.
+
+-}
+cardColumn : Palette -> ColumnStyle msg
+cardColumn palette =
+    { containerColumn =
+        [ Element.width <| Element.fill
+        , Element.mouseOver <|
+            [ Border.shadow <| shadow 4 ]
+        , Element.alignTop
+        , Border.rounded 4
+        ]
+    , element =
+        [ Element.padding 16
+        , Border.rounded 4
+        , Border.width 1
+        , palette.surface
+            |> fromColor
+            |> Background.color
+        , palette.surface
+            |> accessibleTextColor
+            |> fromColor
+            |> Font.color
+        , palette.on.surface
+            |> scaleOpacity 0.14
+            |> fromColor
+            |> Border.color
+        , Element.width <| Element.minimum 344 <| Element.fill
+        ]
+    , ifFirst =
+        [ Border.roundEach
+            { topLeft = 4
+            , topRight = 4
+            , bottomLeft = 0
+            , bottomRight = 0
+            }
+        ]
+    , ifLast =
+        [ Border.roundEach
+            { topLeft = 0
+            , topRight = 0
+            , bottomLeft = 4
+            , bottomRight = 4
+            }
+        , Border.widthEach
+            { top = 0
+            , left = 1
+            , right = 1
+            , bottom = 1
+            }
+        ]
+    , otherwise =
+        [ Border.rounded 0
+        , Border.widthEach
+            { top = 0
+            , left = 1
+            , right = 1
+            , bottom = 1
+            }
+        ]
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- D I A L O G
+-------------------------------------------------------------------------------}
+
+
+{-| An alert dialog for important decisions. Use a snackbar for less important notification.
+
+![Alert Dialog](https://material.io/develop/images/content/9d61e2d1bd60599344c7fae5e71c9667.png)
+
+_Image taken from [material.io](https://material.io/develop/android/components/buttons/)_
+
+
+-}
+alertDialog : Palette -> DialogStyle msg
+alertDialog palette =
+    { containerColumn =
+        [ Border.rounded 4
+        , Element.fill
+            |> Element.maximum 560
+            |> Element.minimum 280
+            |> Element.width
+        , Element.height <| Element.minimum 182 <| Element.shrink
+        , Background.color <| fromColor <| palette.surface
+        ]
+    , title = h6 ++ [ Element.paddingXY 24 20 ]
+    , text = [ Element.paddingXY 24 0 ]
+    , buttonRow =
+        [ Element.paddingXY 8 8
+        , Element.spacing 8
+        , Element.alignRight
+        , Element.alignBottom
+        ]
+    , acceptButton = containedButton palette
+    , dismissButton = textButton palette
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- E X P A N S I O N   P A N E L
+-------------------------------------------------------------------------------}
+
+
+icon : String -> Int -> List (Svg Never) -> Element Never
+icon string size =
+    Svg.svg
+        [ Svg.Attributes.height <| String.fromInt size
+        , Svg.Attributes.stroke "currentColor"
+        , Svg.Attributes.fill "currentColor"
+
+        --, Svg.Attributes.strokeLinecap "round"
+        --, Svg.Attributes.strokeLinejoin "round"
+        --, Svg.Attributes.strokeWidth "2"
+        , Svg.Attributes.viewBox string
+        , Svg.Attributes.width <| String.fromInt size
+        ]
+        >> Element.html
+        >> Element.el []
+
+
+expand_less : Element Never
+expand_less =
+    icon "0 0 48 48" 24 [ Svg.path [ Svg.Attributes.d "M24 16L12 28l2.83 2.83L24 21.66l9.17 9.17L36 28z" ] [] ]
+
+
+expand_more : Element Never
+expand_more =
+    icon "0 0 48 48" 24 [ Svg.path [ Svg.Attributes.d "M33.17 17.17L24 26.34l-9.17-9.17L12 20l12 12 12-12z" ] [] ]
+
+
+{-| The expansion Panel is an outdated part of the material design specification.
+In modern implementation it gets replaced with a very sophisticated list widget.
+
+Technical Remarks:
+
+  - The expansion panel is part of an [older version](https://material.io/archive/guidelines/components/expansion-panels.html) of the Material Design.
+    The newer version is part of the List component.
+    The styling is taken from the [new specification](https://material.io/components/lists#specs).
+  - The Icons are taken from [danmarcab/material-icons](https://dark.elm.dmy.fr/packages/danmarcab/material-icons/latest/).
+
+-}
+expansionPanel : Palette -> ExpansionPanelStyle msg
+expansionPanel palette =
+    { containerColumn =
+        [ Background.color <| fromColor <| palette.surface
+        , Element.width <| Element.fill
+        ]
+    , panelRow =
+        [ Element.height <| Element.px 48
+        , Element.spaceEvenly
+        , Element.padding 14
+        , Element.width <| Element.fill
+        ]
+    , labelRow =
+        [ Element.spacing 32
+        ]
+    , content =
+        [ Element.padding 14 ]
+    , expandIcon =
+        expand_more
+            |> Element.el
+                [ gray
+                    |> fromColor
+                    |> Font.color
+                ]
+    , collapseIcon =
+        expand_less
+            |> Element.el
+                [ gray
+                    |> fromColor
+                    |> Font.color
+                ]
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- S N A C K B A R
+-------------------------------------------------------------------------------}
+
+
+{-| A typical snackbar
+
+![Snackbar](https://material.io/develop/images/content/f2ec5451582a06af5eb20e3dfb3d27d5.svg)
+
+_Image take from [material.io](https://material.io/develop/android/components/snackbar/)_
+
+Technical Remark:
+
+  - The text color of the button was not given in the specification. This implementation
+    adujsts the luminance of the color to fit the [w3 accessability standard](https://www.w3.org/TR/WCAG20/#Contrast)
+
+-}
+snackbar : Palette -> SnackbarStyle msg
+snackbar palette =
+    { containerRow =
+        [ dark
+            |> fromColor
+            |> Background.color
+        , dark
+            |> accessibleTextColor
+            |> fromColor
+            |> Font.color
+        , Border.rounded 4
+        , Element.width <| Element.maximum 344 <| Element.fill
+        , Element.paddingXY 8 6
+        , Element.spacing 8
+        , Border.shadow <| shadow 2
+        ]
+    , text =
+        [ Element.centerX
+        , Element.paddingXY 10 8
+        ]
+    , button =
+        textButton palette
+            |> (\b ->
+                    { b
+                        | container =
+                            b.container
+                                ++ [ dark
+                                        |> accessibleWithTextColor palette.primary
+                                        |> fromColor
+                                        |> Font.color
+                                   ]
+                    }
+               )
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- T E X T   I N P U T
+-------------------------------------------------------------------------------}
+
+
+{-| A text input style that is included only to support input chips.
+
+Technical Remark:
+
+  - This is just a temporary implementation. It will soon be replaced with the official implementation.
+
+-}
+textInput : Palette -> TextInputStyle msg
+textInput palette =
+    { chipButton = chip palette
+    , chipsRow = [ Element.spacing 8 ]
+    , containerRow =
+        (palette.surface
+            |> textAndBackground
+        )
+            ++ [ Element.spacing 8
+               , Element.paddingXY 8 0
+               , Border.width 1
+               , Border.rounded 4
+               , palette.on.surface
+                    |> scaleOpacity 0.14
+                    |> fromColor
+                    |> Border.color
+               , Element.focused
+                    [ Border.shadow <| shadow 4
+                    , palette.primary
+                        |> fromColor
+                        |> Border.color
+                    ]
+               , Element.mouseOver [ Border.shadow <| shadow 2 ]
+               ]
+    , input =
+        (palette.surface
+            |> textAndBackground
+        )
+            ++ [ Border.width 0
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- T A B
+-------------------------------------------------------------------------------}
+
+{-| A single Tab button.
+
+Technical Remark:
+
+* The official specification states that the background color should be the surface color,
+   but the pictures and actuall implementations all have no background color.
+   So here the background color is also not set.
+-}
+tabButton : Palette -> ButtonStyle msg
+tabButton palette =
+    { container =
+        buttonFont
+            ++ [ Element.height <| Element.px 48
+               , Element.fill
+                    |> Element.maximum 360
+                    |> Element.minimum 90
+                    |> Element.width
+               , Element.paddingXY 12 16
+               , Font.color <| fromColor <| palette.primary
+               , Element.mouseDown
+                    [ palette.primary
+                        |> scaleOpacity buttonPressedOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.focused
+                    [ palette.primary
+                        |> scaleOpacity buttonFocusOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.mouseOver
+                    [ palette.primary
+                        |> scaleOpacity buttonHoverOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               ]
+    , labelRow =
+        [ Element.spacing <| 8
+        , Element.centerY
+        , Element.centerX
+        ]
+    , text = []
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        [ Element.height <| Element.px 48
+        , Border.widthEach
+            { bottom = 2
+            , left = 0
+            , right = 0
+            , top = 0
+            }
+        ]
+    , otherwise =
+        []
+    }
+
+
+{-| A Tab bar meant for only the upper most level. Do not use a tab within a tab.
+-}
+tab : Palette -> TabStyle msg
+tab palette =
+    { button = tabButton palette
+    , optionRow =
+        [ Element.spaceEvenly
+        , Border.shadow <| shadow 4
+        ]
+    , containerColumn = [ Element.spacing 8 ]
+    , content = [ Element.width <| Element.fill ]
+    }
+
+
+
+{-------------------------------------------------------------------------------
+-- L A Y O U T
+-------------------------------------------------------------------------------}
+
+
+more_vert : Element Never
+more_vert =
+    icon "0 0 48 48" 24 [ 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 : Element Never
+search =
+    icon "0 0 48 48" 24 [ 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 : Element Never
+menu =
+    icon "0 0 48 48" 24 [ Svg.path [ Svg.Attributes.d "M6 36h36v-4H6v4zm0-10h36v-4H6v4zm0-14v4h36v-4H6z" ] [] ]
+
+
+menuTabButton : Palette -> ButtonStyle msg
+menuTabButton palette =
+    { container =
+        buttonFont
+            ++ [ Element.height <| Element.px 56
+               , Element.fill
+                    |> Element.maximum 360
+                    |> Element.minimum 90
+                    |> Element.width
+               , Element.paddingXY 12 16
+               , palette.primary
+                    |> accessibleTextColor
+                    |> fromColor
+                    |> Font.color
+               , Element.alignBottom
+               , Element.mouseDown
+                    [ palette.primary
+                        |> scaleOpacity buttonPressedOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.focused
+                    [ palette.primary
+                        |> scaleOpacity buttonFocusOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               , Element.mouseOver
+                    [ palette.primary
+                        |> scaleOpacity buttonHoverOpacity
+                        |> fromColor
+                        |> Background.color
+                    ]
+               ]
+    , labelRow =
+        [ Element.spacing <| 8
+        , Element.centerY
+        , Element.centerX
+        ]
+    , text = []
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        [ Border.widthEach
+            { bottom = 2
+            , left = 0
+            , right = 0
+            , top = 0
+            }
+        ]
+    , otherwise =
+        []
+    }
+
+
+drawerButton : Palette -> ButtonStyle msg
+drawerButton palette =
+    { container =
+        [ Font.size 14
+        , Font.semiBold
+        , Font.letterSpacing 0.25
+        , Element.height <| Element.px 36
+        , Element.width <| Element.fill
+        , Element.paddingXY 8 8
+        , Border.rounded <| 4
+        , palette.surface
+            |> accessibleTextColor
+            |> fromColor
+            |> Font.color
+        , Element.mouseDown
+            [ palette.primary
+                |> scaleOpacity buttonPressedOpacity
+                |> fromColor
+                |> Background.color
+            ]
+        , Element.focused
+            [ palette.primary
+                |> scaleOpacity buttonFocusOpacity
+                |> fromColor
+                |> Background.color
+            ]
+        , Element.mouseOver
+            [ palette.primary
+                |> scaleOpacity buttonHoverOpacity
+                |> fromColor
+                |> Background.color
+            ]
+        ]
+    , labelRow = baseButton palette |> .labelRow
+    , text = baseButton palette |> .text
+    , ifDisabled =
+        (baseButton palette |> .ifDisabled)
+            ++ [ gray
+                    |> fromColor
+                    |> Font.color
+               , Element.mouseDown []
+               , Element.mouseOver []
+               , Element.focused []
+               ]
+    , ifActive =
+        [ palette.primary
+            |> scaleOpacity buttonHoverOpacity
+            |> fromColor
+            |> Background.color
+        , palette.primary
+            |> fromColor
+            |> Font.color
+        ]
+    , otherwise =
+        []
+    }
+
+
+{-| The Layout Widget combines the following Material design concepts:
+
+* Top bar
+* Navigation drawer
+* Side Sheet
+* Dialog
+* Snackbar
+
+Future updates might try to seperate them into there own widgets.
+But for now they are only available as an all-in-one solution.
+
+Technical Remark:
+
+  - Due to [a bug in Elm-Ui](https://github.com/mdgriffith/elm-ui/issues/47) the menu button still behave wierd.
+    I've not found a workaround for it.
+  - The Icons are taken from [danmarcab/material-icons](https://dark.elm.dmy.fr/packages/danmarcab/material-icons/latest/).
+  - The drawer button as not taken from the specification (This will been to be added later)
+
+-}
+layout : Palette -> LayoutStyle msg
+layout palette =
+    { container =
+        (palette.background |> textAndBackground)
+            ++ [ Font.family
+                    [ Font.typeface "Roboto"
+                    , Font.sansSerif
+                    ]
+               , Font.size 16
+               , Font.letterSpacing 0.5
+               ]
+    , snackbar = snackbar palette
+    , layout = Element.layout
+    , header =
+        (palette.primary
+            |> textAndBackground
+        )
+            ++ [ Element.height <| Element.px 56
+               , Element.padding 16
+               , Element.width <| Element.minimum 360 <| Element.fill
+               ]
+    , menuButton = iconButton palette
+    , sheetButton = drawerButton palette
+    , menuTabButton = menuTabButton palette
+    , sheet =
+        (palette.surface |> textAndBackground)
+            ++ [ Element.width <| Element.maximum 360 <| Element.fill
+               , Element.padding 8
+               , Element.spacing 8
+               ]
+    , menuIcon = menu
+    , moreVerticalIcon = more_vert
+    , spacing = 8
+    , title = h6 ++ [ Element.paddingXY 8 0 ]
+    , searchIcon = search
+    , search =
+        (palette.surface |> textAndBackground)
+            ++ [ Element.spacing 8
+               , Element.paddingXY 8 8
+               , Element.height <| Element.px 32
+               , Border.width 1
+               , Border.rounded 4
+               , palette.on.surface
+                    |> scaleOpacity 0.14
+                    |> fromColor
+                    |> Border.color
+               , Element.focused
+                    [ Border.shadow <| shadow 4
+                    ]
+               , Element.mouseOver [ Border.shadow <| shadow 2 ]
+               , Element.width <| Element.maximum 360 <| Element.fill
+               , Element.alignRight
+               ]
+    , searchFill =
+        palette.surface |> textAndBackground
+    }
diff --git a/src/Widget/Style/Template.elm b/src/Widget/Style/Template.elm
new file mode 100644
index 0000000..2149525
--- /dev/null
+++ b/src/Widget/Style/Template.elm
@@ -0,0 +1,383 @@
+module Widget.Style.Template exposing
+    ( box, decoration, icon
+    , button, column, dialog, expansionPanel, layout, row, snackbar, sortTable, tab, textInput
+    )
+
+{-| ![Example using the Template style](https://orasund.github.io/elm-ui-widgets/assets/template-style.png)
+
+This package contains mockups designed for writing your own style.
+
+Start by copying the following code and then replace the fields one by one.
+
+```
+type alias Style msg =
+    { dialog : DialogStyle msg
+    , expansionPanel : ExpansionPanelStyle msg
+    , button : ButtonStyle msg
+    , primaryButton : ButtonStyle msg
+    , tab : TabStyle msg
+    , textInput : TextInputStyle msg
+    , chipButton : ButtonStyle msg
+    , row : RowStyle msg
+    , buttonRow : RowStyle msg
+    , column : ColumnStyle msg
+    , cardColumn : ColumnStyle msg
+    , sortTable : SortTableStyle msg
+    , selectButton : ButtonStyle msg
+    , layout : LayoutStyle msg
+    }
+
+style : Style msg
+style =
+    { sortTable = Template.sortTable <| "sortTable"
+    , row = Template.row <| "row"
+    , buttonRow = Template.row <| "buttonRow"
+    , cardColumn = Template.column <| "cardRow"
+    , column = Template.column <| "column"
+    , button = Template.button <| "button"
+    , primaryButton = Template.button <| "primaryButton"
+    , tab = Template.tab <| "tab"
+    , textInput = Template.textInput <| "textInput"
+    , chipButton = Template.button <| "chipButton"
+    , expansionPanel = Template.expansionPanel "expansionPanel"
+    , selectButton = Template.button "selectButton"
+    , dialog = Template.dialog "dialog"
+    , layout = Template.layout "layout"
+    }
+```
+
+
+# Base Elements
+
+@docs box, decoration, icon
+
+
+# Mockups
+
+@docs button, column, dialog, expansionPanel, layout, row, snackbar, sortTable, tab, textInput
+
+-}
+
+import Element exposing (Attribute, Element)
+import Element.Background as Background
+import Element.Border as Border
+import Element.Font as Font
+import Widget.Style
+    exposing
+        ( ButtonStyle
+        , ColumnStyle
+        , DialogStyle
+        , ExpansionPanelStyle
+        , LayoutStyle
+        , RowStyle
+        , SnackbarStyle
+        , SortTableStyle
+        , TabStyle
+        , TextInputStyle
+        )
+
+
+fontSize : Int
+fontSize =
+    10
+
+
+{-| A box representing an element
+-}
+box : String -> List (Attribute msg)
+box string =
+    [ Border.width 1
+    , Background.color <| Element.rgba 1 1 1 0.5
+    , Element.padding 10
+    , Element.spacing 10
+    , Element.above <|
+        Element.el [ Font.size <| fontSize ] <|
+            Element.text string
+    ]
+
+
+{-| An additional attribute representing a state change.
+-}
+decoration : String -> List (Attribute msg)
+decoration string =
+    [ Element.below <|
+        Element.el [ Font.size <| fontSize ] <|
+            Element.text string
+    , Background.color <| Element.rgb 0.66 0.66 0.66
+    ]
+
+
+{-| A circle representing an icon
+-}
+icon : String -> Element msg
+icon string =
+    Element.none
+        |> Element.el
+            [ Element.width <| Element.px 12
+            , Element.height <| Element.px 12
+            , Border.rounded 6
+            , Border.width 1
+            , Element.above <|
+                Element.el [ Font.size <| fontSize ] <|
+                    Element.text string
+            ]
+
+
+{-|
+
+```
+button : String -> ButtonStyle msg
+button string =
+    { container = box <| string ++ ":container"
+    , labelRow = box <| string ++ ":labelRow"
+    , text = box <| string ++ ":text"
+    , ifDisabled = decoration <| string ++ ":ifDisabled"
+    , ifActive = decoration <| string ++ ":ifActive"
+    , otherwise = decoration <| string ++ ":otherwise"
+    }
+```
+
+-}
+button : String -> ButtonStyle msg
+button string =
+    { container = box <| string ++ ":container"
+    , labelRow = box <| string ++ ":labelRow"
+    , text = box <| string ++ ":text"
+    , ifDisabled = decoration <| string ++ ":ifDisabled"
+    , ifActive = decoration <| string ++ ":ifActive"
+    , otherwise = decoration <| string ++ ":otherwise"
+    }
+
+
+{-|
+
+```
+snackbar : String -> SnackbarStyle msg
+snackbar string =
+    { containerRow = box <| string ++ ":containerRow"
+    , button = button <| string ++ ":button"
+    , text = box <| string ++ ":text"
+    }
+```
+
+-}
+snackbar : String -> SnackbarStyle msg
+snackbar string =
+    { containerRow = box <| string ++ ":containerRow"
+    , button = button <| string ++ ":button"
+    , text = box <| string ++ ":text"
+    }
+
+
+{-|
+
+```
+dialog : String -> DialogStyle msg
+dialog string =
+    { containerColumn = box <| string ++ ":containerColumn"
+    , title = box <| string ++ ":title"
+    , text = box <| string ++ ":text"
+    , buttonRow = box <| string ++ ":buttonRow"
+    , acceptButton = button <| string ++ ":acceptButton"
+    , dismissButton = button <| string ++ ":dismissButton"
+    }
+```
+
+-}
+dialog : String -> DialogStyle msg
+dialog string =
+    { containerColumn = box <| string ++ ":containerColumn"
+    , title = box <| string ++ ":title"
+    , text = box <| string ++ ":text"
+    , buttonRow = box <| string ++ ":buttonRow"
+    , acceptButton = button <| string ++ ":acceptButton"
+    , dismissButton = button <| string ++ ":dismissButton"
+    }
+
+
+{-|
+
+```
+expansionPanel : String -> ExpansionPanelStyle msg
+expansionPanel string =
+    { containerColumn = box <| string ++ ":containerColumn"
+    , panelRow = box <| string ++ ":panelRow"
+    , labelRow = box <| string ++ ":labelRow"
+    , content = box <| string ++ ":content"
+    , expandIcon = icon <| string ++ ":expandIcon"
+    , collapseIcon = icon <| string ++ ":collapseIcon"
+    }
+
+```
+
+-}
+expansionPanel : String -> ExpansionPanelStyle msg
+expansionPanel string =
+    { containerColumn = box <| string ++ ":containerColumn"
+    , panelRow = box <| string ++ ":panelRow"
+    , labelRow = box <| string ++ ":labelRow"
+    , content = box <| string ++ ":content"
+    , expandIcon = icon <| string ++ ":expandIcon"
+    , collapseIcon = icon <| string ++ ":collapseIcon"
+    }
+
+
+{-|
+
+```
+textInput : String -> TextInputStyle msg
+textInput string =
+    { chipButton = button <| string ++ ":chipButton"
+    , chipsRow = box <| string ++ ":chipsRow"
+    , containerRow = box <| string ++ ":containerRow"
+    , input = box <| string ++ ":input"
+    }
+
+```
+
+-}
+textInput : String -> TextInputStyle msg
+textInput string =
+    { chipButton = button <| string ++ ":chipButton"
+    , chipsRow = box <| string ++ ":chipsRow"
+    , containerRow = box <| string ++ ":containerRow"
+    , input = box <| string ++ ":input"
+    }
+
+
+{-|
+
+```
+tab : String -> TabStyle msg
+tab string =
+    { button = button <| string ++ ":button"
+    , optionRow = box <| string ++ ":optionRow"
+    , containerColumn = box <| string ++ ":containerColumn"
+    , content = box <| string ++ ":content"
+    }
+```
+
+-}
+tab : String -> TabStyle msg
+tab string =
+    { button = button <| string ++ ":button"
+    , optionRow = box <| string ++ ":optionRow"
+    , containerColumn = box <| string ++ ":containerColumn"
+    , content = box <| string ++ ":content"
+    }
+
+
+{-|
+
+```
+row : String -> RowStyle msg
+row string =
+    { containerRow = box <| string ++ ":containerRow"
+    , element = box <| string ++ ":element"
+    , ifFirst = decoration <| string ++ ":ifFirst"
+    , ifLast = decoration <| string ++ ":ifLast"
+    , otherwise = decoration <| string ++ ":otherwise"
+    }
+```
+
+-}
+row : String -> RowStyle msg
+row string =
+    { containerRow = box <| string ++ ":containerRow"
+    , element = box <| string ++ ":element"
+    , ifFirst = decoration <| string ++ ":ifFirst"
+    , ifLast = decoration <| string ++ ":ifLast"
+    , otherwise = decoration <| string ++ ":otherwise"
+    }
+
+
+{-|
+
+```
+column : String -> ColumnStyle msg
+column string =
+    { containerColumn = box <| string ++ ":containerColumn"
+    , element = box <| string ++ ":element"
+    , ifFirst = decoration <| string ++ ":ifFirst"
+    , ifLast = decoration <| string ++ ":ifLast"
+    , otherwise = decoration <| string ++ ":otherwise"
+    }
+```
+
+-}
+column : String -> ColumnStyle msg
+column string =
+    { containerColumn = box <| string ++ ":containerColumn"
+    , element = box <| string ++ ":element"
+    , ifFirst = decoration <| string ++ ":ifFirst"
+    , ifLast = decoration <| string ++ ":ifLast"
+    , otherwise = decoration <| string ++ ":otherwise"
+    }
+
+
+{-|
+
+```
+sortTable : String -> SortTableStyle msg
+sortTable string =
+    { containerTable = box <| string ++ ":containerTable"
+    , headerButton = button <| string ++ ":headerButton"
+    , ascIcon = icon <| string ++ ":ascIcon"
+    , descIcon = icon <| string ++ ":descIcon"
+    , defaultIcon = icon <| string ++ ":defaultIcon"
+    }
+```
+
+-}
+sortTable : String -> SortTableStyle msg
+sortTable string =
+    { containerTable = box <| string ++ ":containerTable"
+    , headerButton = button <| string ++ ":headerButton"
+    , ascIcon = icon <| string ++ ":ascIcon"
+    , descIcon = icon <| string ++ ":descIcon"
+    , defaultIcon = icon <| string ++ ":defaultIcon"
+    }
+
+
+{-|
+
+```
+layout : String -> LayoutStyle msg
+layout string =
+    { container = box <| string ++ ":container"
+    , snackbar = snackbar <| string ++ ":snackbar"
+    , layout = Element.layout
+    , header = box <| string ++ ":header"
+    , menuButton = button <| string ++ ":menuButton"
+    , sheetButton = button <| string ++ ":sheetButton"
+    , menuTabButton = button <| string ++ ":menuTabButton"
+    , sheet = box <| string ++ ":sheet"
+    , menuIcon = icon <| string ++ ":menuIcon"
+    , moreVerticalIcon = icon <| string ++ ":moreVerticalIcon"
+    , spacing = 8
+    , title = box <| string ++ ":title"
+    , searchIcon = icon <| string ++ ":searchIcon"
+    , search = box <| string ++ ":search"
+    , searchFill = box <| string ++ ":searchFill"
+    }
+```
+
+-}
+layout : String -> LayoutStyle msg
+layout string =
+    { container = box <| string ++ ":container"
+    , snackbar = snackbar <| string ++ ":snackbar"
+    , layout = Element.layout
+    , header = box <| string ++ ":header"
+    , menuButton = button <| string ++ ":menuButton"
+    , sheetButton = button <| string ++ ":sheetButton"
+    , menuTabButton = button <| string ++ ":menuTabButton"
+    , sheet = box <| string ++ ":sheet"
+    , menuIcon = icon <| string ++ ":menuIcon"
+    , moreVerticalIcon = icon <| string ++ ":moreVerticalIcon"
+    , spacing = 8
+    , title = box <| string ++ ":title"
+    , searchIcon = icon <| string ++ ":searchIcon"
+    , search = box <| string ++ ":search"
+    , searchFill = box <| string ++ ":searchFill"
+    }
diff --git a/src/Widget/ValidatedInput.elm b/src/Widget/ValidatedInput.elm
deleted file mode 100644
index e3aa08e..0000000
--- a/src/Widget/ValidatedInput.elm
+++ /dev/null
@@ -1,161 +0,0 @@
-module Widget.ValidatedInput exposing
-    ( Model, Msg, init, update, view
-    , getError, getRaw, getValue
-    )
-
-{-| The validated Input is a wrapper around `Input.text`.
-They can validate the input and return an error if nessarry.
-
-
-# Basics
-
-@docs Model, Msg, init, update, view
-
-
-# Access the Model
-
-@docs getError, getRaw, getValue
-
--}
-
-import Element exposing (Attribute, Element)
-import Element.Events as Events
-import Element.Input as Input exposing (Placeholder)
-
-
-{-| -}
-type Model err a
-    = Model
-        { raw : Maybe String
-        , value : a
-        , err : Maybe err
-        , validator : String -> Result err a
-        , toString : a -> String
-        }
-
-
-{-| returns the raw value (the value that the user currently sees)
--}
-getRaw : Model err a -> String
-getRaw (Model { raw, value, toString }) =
-    case raw of
-        Just string ->
-            string
-
-        Nothing ->
-            value |> toString
-
-
-{-| returns the value (the value that has been last successfully validated)
--}
-getValue : Model err a -> a
-getValue (Model { value }) =
-    value
-
-
-{-| returns the error (if one exists)
--}
-getError : Model err a -> Maybe err
-getError (Model { err }) =
-    err
-
-
-{-| -}
-type Msg
-    = ChangedRaw String
-    | LostFocus
-    | StartEditing
-
-
-{-| The initial state contains
-
-  - `value`: starting value
-  - `validator`: a vaidation function (a decoder)
-  - `toString`: a function that returns a string representation
-
--}
-init : { value : a, validator : String -> Result err a, toString : a -> String } -> Model err a
-init { validator, toString, value } =
-    Model
-        { raw = Nothing
-        , value = value
-        , err = Nothing
-        , validator = validator
-        , toString = toString
-        }
-
-
-{-| -}
-update : Msg -> Model err a -> Model err a
-update msg (Model model) =
-    case msg of
-        StartEditing ->
-            Model
-                { model
-                    | raw = model.value |> model.toString |> Just
-                }
-
-        ChangedRaw string ->
-            Model
-                { model
-                    | raw = Just string
-                    , err = Nothing
-                }
-
-        LostFocus ->
-            case model.raw of
-                Just string ->
-                    case model.validator string of
-                        Ok value ->
-                            Model
-                                { model
-                                    | value = value
-                                    , raw = Nothing
-                                    , err = Nothing
-                                }
-
-                        Err err ->
-                            Model
-                                { model
-                                    | raw = Nothing
-                                    , err = Just err
-                                }
-
-                Nothing ->
-                    Model model
-
-
-{-| the view function, the parameters include
-
-  - `msgMapper`: A function wrapping the `Msg` into a `msg`
-  - `placeholder`: See Element.text for more information
-  - `label`: The (hidden) label of the input (needed for screen readers)
-  - `readOnly`: a representation of the validated value
-    (clicking on the element will turn on edit mode)
-
--}
-view :
-    List (Attribute msg)
-    -> Model err a
-    ->
-        { msgMapper : Msg -> msg
-        , placeholder : Maybe (Placeholder msg)
-        , label : String
-        , readOnly : a -> Element msg
-        }
-    -> Element msg
-view attributes (Model model) { msgMapper, placeholder, label, readOnly } =
-    case model.raw of
-        Just string ->
-            Input.text (attributes ++ [ Events.onLoseFocus <| msgMapper <| LostFocus ])
-                { onChange = ChangedRaw >> msgMapper
-                , text = string
-                , placeholder = placeholder
-                , label = Input.labelHidden label
-                }
-
-        Nothing ->
-            Input.button []
-                { onPress = Just (StartEditing |> msgMapper)
-                , label = model.value |> readOnly
-                }