From df0a35c1354f024aa30deda8abd89b36b0f5df75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Thu, 17 Mar 2016 22:23:06 +0100 Subject: [PATCH 01/12] chore(app): ignoring vscode files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 105004f..45a3878 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ elm.js index.html docs.json documentation.json +.vscode/ \ No newline at end of file From b26567c2c3b9c48d047013f184c62c3ba3da4b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Thu, 17 Mar 2016 22:30:49 +0100 Subject: [PATCH 02/12] feat(badges):initial demo setup --- examples/Demo.elm | 2 ++ examples/Demo/Badges.elm | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 examples/Demo/Badges.elm diff --git a/examples/Demo.elm b/examples/Demo.elm index e14d969..ee28fc3 100644 --- a/examples/Demo.elm +++ b/examples/Demo.elm @@ -17,6 +17,7 @@ import Demo.Buttons import Demo.Grid import Demo.Textfields import Demo.Snackbar +import Demo.Badges --import Demo.Template -- MODEL @@ -118,6 +119,7 @@ tabs = , ("Template", \addr model -> [Demo.Template.view (Signal.forwardTo addr TemplateAction) model.template]) -} + , ("Badges", \addr model -> Demo.Badges.view) ] diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm new file mode 100644 index 0000000..4a21d9e --- /dev/null +++ b/examples/Demo/Badges.elm @@ -0,0 +1,11 @@ +module Demo.Badges where + +-- import Material.Badge exposing (..) +import Html exposing (..) + + +view : List Html +view = + [ + h1 [][text "Badges"] + ] From ef7d2a99166d82b789708e1155df86016b814c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Sat, 19 Mar 2016 18:23:47 +0100 Subject: [PATCH 03/12] feat(badge):initial implementation --- examples/Demo/Badges.elm | 11 ++++- src/Material/Badge.elm | 87 ++++++++++++++++++++++++++++++++++++++++ src/Material/Icon.elm | 77 +++++++++++++++++++++++++++-------- 3 files changed, 157 insertions(+), 18 deletions(-) create mode 100644 src/Material/Badge.elm diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm index 4a21d9e..720cf89 100644 --- a/examples/Demo/Badges.elm +++ b/examples/Demo/Badges.elm @@ -1,11 +1,18 @@ module Demo.Badges where --- import Material.Badge exposing (..) +import Material.Icon as Icon +import Material.Badge as Badge import Html exposing (..) +import Html.Attributes exposing (..) view : List Html view = [ - h1 [][text "Badges"] + h1 [][text "Badges"], + Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.viewDefault "16")}, + Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.view { overlap = False, noBackground = False} "99")}, + Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.view { overlap = False, noBackground = True} "4")}, + Icon.view "add" Icon.S18 [], + Icon.i "add" ] diff --git a/src/Material/Badge.elm b/src/Material/Badge.elm new file mode 100644 index 0000000..b1eeb0e --- /dev/null +++ b/src/Material/Badge.elm @@ -0,0 +1,87 @@ +module Material.Badge + ( Options + , view + , viewDefault + , BadgeInfo + ) where + +{-| From the [Material Design Lite documentation](http://www.getmdl.io/components/#badges-section): + +The Material Design Lite (MDL) badge component is an onscreen notification element. A badge consists of a small circle, typically containing a number or other characters, that appears in proximity to another object. A badge can be both a notifier that there are additional items associated with an object and an indicator of how many items there are. + +You can use a badge to unobtrusively draw the user's attention to items they might not otherwise notice, or to emphasize that items may need their attention. For example: + +A "New messages" notification might be followed by a badge containing the number of unread messages. +A "You have unpurchased items in your shopping cart" reminder might include a badge showing the number of items in the cart. +A "Join the discussion!" button might have an accompanying badge indicating the number of users currently participating in the discussion. +A badge is almost always positioned near a link so that the user has a convenient way to access the additional information indicated by the badge. However, depending on the intent, the badge itself may or may not be part of the link. + +Badges are a new feature in user interfaces, and provide users with a visual clue to help them discover additional relevant content. Their design and use is therefore an important factor in the overall user experience. + +@docs viewDefault, view, BadgeInfo, Options +-} + + +import Html exposing (Attribute) +import Html.Attributes exposing (attribute) + + +{-| Internal Type used by other elements. Not sure if this should be documented. +-} +type alias BadgeInfo = + { classes : String + , dataBadge : Attribute + } + +{-| Options for Badge + ovelap: Bool to set css class - mdl-badge--overlap. Make the badge overlap with its container + noBackground: Bool to set css class - mdl-badge--no-background. Applies open-circle effect to badge +-} +type alias Options = + { overlap : Bool + , noBackground : Bool + } + +defaultOptions : Options +defaultOptions = + { + overlap = True + , noBackground = False + } + +{-| View function for Badge + + First parameter will set Badge options. See Options for more info. + Last parameter will set a value to data-badge="value". Assigns string value to badge + + import Material.Badge as Badge + + badgeInfo : Badge.BadgeInfo + badgeInfo = Badge.view { overlap = False, noBackground = False} "3" +-} +view : Options -> String -> BadgeInfo +view options databadge = + let classes = + [ + {css = " mdl-badge", show = True} + , {css = " mdl-badge--no-background", show = options.noBackground} + , {css = " mdl-badge--overlap", show = options.overlap} + ] + |> List.filter .show + |> List.map .css + |> List.foldl (++) "" + in + { classes = " mdl-badge" ++ classes, dataBadge = attribute "data-badge" databadge} + + +{-| Create BadgeInfo with default values + + Parameter will set a value to data-badge="value". Assigns string value to badge + + import Material.Badge as Badge + + badgeInfo : Badge.BadgeInfo + badgeInfo = Badge.viewDefault "3" +-} +viewDefault : String -> BadgeInfo +viewDefault databadge = view defaultOptions databadge diff --git a/src/Material/Icon.elm b/src/Material/Icon.elm index 7b52263..43202be 100644 --- a/src/Material/Icon.elm +++ b/src/Material/Icon.elm @@ -1,5 +1,6 @@ module Material.Icon ( Size(..) + , viewWithOptions , view , i ) where @@ -15,13 +16,12 @@ This implementation assumes that you have or an equivalent means of loading the icons in your HTML header. -@docs i, Size, view +@docs i, Size, viewWithOptions, view -} - import Html exposing (i, text, Html, Attribute) -import Html.Attributes exposing (class) - +import Html.Attributes exposing (class, attribute) +import Material.Badge as Badge {-| Size of an icon. Constructors indicate their pixel size, i.e., `S18` is 18px. The constructor `S` gives you the default size, 24px. @@ -29,6 +29,60 @@ import Html.Attributes exposing (class) type Size = S18 | S24 | S36 | S48 | S +{-| Options +See Badge on how to create a badge. +-} +type alias Options = + { + badgeInfo : Maybe Badge.BadgeInfo + } + +defaultOptions : Options +defaultOptions = + { + badgeInfo = Nothing + } + + +{-| View function for icons. Supply the +[Material Icons Library](https://design.google.com/icons/) name as +the first argument (replace spaces with underscores); and the size of the icon +as the second. Do not use this function to produce clickable icons; use +icon buttons in Material.Button for that. + +I.e., to produce a 48px +["trending flat"](https://design.google.com/icons/#ic_trending_flat) icon with +no attributes: + +See Badge for info on how to create a badge for options. + + import Material.Icon as Icon + + icon : Html + icon = Icon.viewWithOptions "trending_flat" Icon.S48 [] { badgeInfo = Just (Badge.viewDefault "16") + +This function will override any `class` set in `List Attribute`. +-} +viewWithOptions : String -> Size -> List Attribute -> Options-> Html +viewWithOptions name size attrs options = + let + sz = + case size of + S18 -> " md-18" + S24 -> " md-24" + S36 -> " md-36" + S48 -> " md-48" + S -> "" + appAttrs = + case options.badgeInfo of + Just badgeInfo -> List.append attrs [badgeInfo.dataBadge] + Nothing -> attrs + optionClasses = + case options.badgeInfo of + Just badgeInfo -> badgeInfo.classes + Nothing -> "" + in + Html.i (class ("material-icons" ++ sz ++ optionClasses ) :: appAttrs) [text name] {-| View function for icons. Supply the [Material Icons Library](https://design.google.com/icons/) name as @@ -47,18 +101,9 @@ no attributes: This function will override any `class` set in `List Attribute`. -} + view : String -> Size -> List Attribute -> Html -view name size attrs = - let - sz = - case size of - S18 -> " md-18" - S24 -> " md-24" - S36 -> " md-36" - S48 -> " md-48" - S -> "" - in - Html.i (class ("material-icons" ++ sz) :: attrs) [text name] +view name size attrs = viewWithOptions name size attrs defaultOptions {-| Render a default-sized icon with no behaviour. The @@ -73,4 +118,4 @@ I.e., to produce a default size (24xp) "trending flat" icon: icon = Icon.i "trending_flat" -} i : String -> Html -i name = view name S [] +i name = view name S [] From 03cb5fca28300e5939dedade927411626351d7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Sat, 19 Mar 2016 22:27:11 +0100 Subject: [PATCH 04/12] feat(badges):cleanup --- examples/Demo/Badges.elm | 2 +- src/Material/Badge.elm | 53 +++++++++++++++++++++++----------------- src/Material/Icon.elm | 3 +++ 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm index 720cf89..422085e 100644 --- a/examples/Demo/Badges.elm +++ b/examples/Demo/Badges.elm @@ -10,7 +10,7 @@ view : List Html view = [ h1 [][text "Badges"], - Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.viewDefault "16")}, + Icon.viewWithOptions "face" Icon.S18 [] { badgeInfo = Just (Badge.viewDefault "16")}, Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.view { overlap = False, noBackground = False} "99")}, Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.view { overlap = False, noBackground = True} "4")}, Icon.view "add" Icon.S18 [], diff --git a/src/Material/Badge.elm b/src/Material/Badge.elm index b1eeb0e..bb1ecb1 100644 --- a/src/Material/Badge.elm +++ b/src/Material/Badge.elm @@ -1,5 +1,5 @@ module Material.Badge - ( Options + ( Model , view , viewDefault , BadgeInfo @@ -7,16 +7,26 @@ module Material.Badge {-| From the [Material Design Lite documentation](http://www.getmdl.io/components/#badges-section): -The Material Design Lite (MDL) badge component is an onscreen notification element. A badge consists of a small circle, typically containing a number or other characters, that appears in proximity to another object. A badge can be both a notifier that there are additional items associated with an object and an indicator of how many items there are. - -You can use a badge to unobtrusively draw the user's attention to items they might not otherwise notice, or to emphasize that items may need their attention. For example: - -A "New messages" notification might be followed by a badge containing the number of unread messages. -A "You have unpurchased items in your shopping cart" reminder might include a badge showing the number of items in the cart. -A "Join the discussion!" button might have an accompanying badge indicating the number of users currently participating in the discussion. -A badge is almost always positioned near a link so that the user has a convenient way to access the additional information indicated by the badge. However, depending on the intent, the badge itself may or may not be part of the link. - -Badges are a new feature in user interfaces, and provide users with a visual clue to help them discover additional relevant content. Their design and use is therefore an important factor in the overall user experience. +> The Material Design Lite (MDL) badge component is an onscreen notification element. +> A badge consists of a small circle, typically containing a number or other characters, +> that appears in proximity to another object. A badge can be both a notifier that there +> are additional items associated with an object and an indicator of how many items there are. +> +> You can use a badge to unobtrusively draw the user's attention to items they might not +> otherwise notice, or to emphasize that items may need their attention. For example: +> +> A "New messages" notification might be followed by a badge containing the number of unread messages. +> A "You have unpurchased items in your shopping cart" reminder might include a badge +> showing the number of items in the cart. +> A "Join the discussion!" button might have an accompanying badge indicating the number of +> users currently participating in the discussion. +> A badge is almost always positioned near a link so that the user has a convenient way to access +> the additional information indicated by the badge. However, depending on the intent, the +> badge itself may or may not be part of the link. +> +> Badges are a new feature in user interfaces, and provide users with a visual clue to help them +> discover additional relevant content. Their design and use is therefore an important +> factor in the overall user experience. @docs viewDefault, view, BadgeInfo, Options -} @@ -33,19 +43,18 @@ type alias BadgeInfo = , dataBadge : Attribute } -{-| Options for Badge +{-| Model for Badge ovelap: Bool to set css class - mdl-badge--overlap. Make the badge overlap with its container noBackground: Bool to set css class - mdl-badge--no-background. Applies open-circle effect to badge -} -type alias Options = +type alias Model = { overlap : Bool , noBackground : Bool } -defaultOptions : Options -defaultOptions = - { - overlap = True +model : Model +model = + { overlap = True , noBackground = False } @@ -59,13 +68,13 @@ defaultOptions = badgeInfo : Badge.BadgeInfo badgeInfo = Badge.view { overlap = False, noBackground = False} "3" -} -view : Options -> String -> BadgeInfo -view options databadge = +view : Model -> String -> BadgeInfo +view model databadge = let classes = [ {css = " mdl-badge", show = True} - , {css = " mdl-badge--no-background", show = options.noBackground} - , {css = " mdl-badge--overlap", show = options.overlap} + , {css = " mdl-badge--no-background", show = model.noBackground} + , {css = " mdl-badge--overlap", show = model.overlap} ] |> List.filter .show |> List.map .css @@ -84,4 +93,4 @@ view options databadge = badgeInfo = Badge.viewDefault "3" -} viewDefault : String -> BadgeInfo -viewDefault databadge = view defaultOptions databadge +viewDefault databadge = view model databadge diff --git a/src/Material/Icon.elm b/src/Material/Icon.elm index 43202be..bfb3570 100644 --- a/src/Material/Icon.elm +++ b/src/Material/Icon.elm @@ -37,6 +37,9 @@ type alias Options = badgeInfo : Maybe Badge.BadgeInfo } +{-| default options +See Badge on how to create a badge. +-} defaultOptions : Options defaultOptions = { From d05ca57a00203d8739c845a7c491821f54145a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Wed, 23 Mar 2016 10:29:51 +0100 Subject: [PATCH 05/12] Enables style to also handle custom attributes --- src/Material/Style.elm | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Material/Style.elm b/src/Material/Style.elm index 5e83c76..eaa917b 100644 --- a/src/Material/Style.elm +++ b/src/Material/Style.elm @@ -1,7 +1,7 @@ module Material.Style ( Style , styled - , cs, cs', css, css' + , cs, cs', css, css', attrib , stylesheet ) where @@ -17,7 +17,7 @@ add to or remove from the contents of an already constructed class Attribute.) @docs Style # Constructors -@docs cs, cs', css, css' +@docs cs, cs', css, css', attrib # Application @docs styled @@ -41,9 +41,16 @@ import Html.Attributes type Style = Class String | CSS (String, String) + | Attr (String, String) | NOP +attrOf : Style -> Maybe (String, String) +attrOf style = + case style of + Attr attrib -> Just attrib + _ -> Nothing + cssOf : Style -> Maybe (String, String) cssOf style = case style of @@ -75,10 +82,14 @@ Note that if you do specify `style`, `class`, or `classList` attributes in -} styled : (List Attribute -> a) -> List Style -> List Attribute -> a styled ctor styles attrs = + let + styleAttrs = (List.filterMap attrOf styles) + |> List.map (\attrib -> Html.Attributes.attribute (fst attrib) ( snd attrib)) + in ctor ( Html.Attributes.style (List.filterMap cssOf styles) :: Html.Attributes.class (String.join " " (List.filterMap classOf styles)) - :: attrs + :: List.append attrs styleAttrs ) @@ -103,6 +114,12 @@ css : String -> String -> Style css key value = CSS (key, value) +{-| Add a custom attribute +-} +attrib : String -> String -> Style +attrib key value = + Attr (key, value) + {-| Conditionally add a CSS style to a component -} From ced0d21dcbb5c2383f1a062f68a107d7f58cf144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Wed, 23 Mar 2016 10:31:31 +0100 Subject: [PATCH 06/12] Updates badge to use Style implementation --- src/Material/Badge.elm | 46 ++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/Material/Badge.elm b/src/Material/Badge.elm index bb1ecb1..572af2c 100644 --- a/src/Material/Badge.elm +++ b/src/Material/Badge.elm @@ -1,8 +1,7 @@ module Material.Badge ( Model - , view - , viewDefault - , BadgeInfo + , badgeStyle + , badgeStyleDefault ) where {-| From the [Material Design Lite documentation](http://www.getmdl.io/components/#badges-section): @@ -31,18 +30,12 @@ module Material.Badge @docs viewDefault, view, BadgeInfo, Options -} - +import String import Html exposing (Attribute) import Html.Attributes exposing (attribute) +import Material.Style exposing (Style, cs, cs', styled, attrib) -{-| Internal Type used by other elements. Not sure if this should be documented. --} -type alias BadgeInfo = - { classes : String - , dataBadge : Attribute - } - {-| Model for Badge ovelap: Bool to set css class - mdl-badge--overlap. Make the badge overlap with its container noBackground: Bool to set css class - mdl-badge--no-background. Applies open-circle effect to badge @@ -58,39 +51,40 @@ model = , noBackground = False } -{-| View function for Badge + +{-| Style function for Badge First parameter will set Badge options. See Options for more info. Last parameter will set a value to data-badge="value". Assigns string value to badge import Material.Badge as Badge - badgeInfo : Badge.BadgeInfo - badgeInfo = Badge.view { overlap = False, noBackground = False} "3" + badgeStyleList : List Style + badgeStyleList = Badge.badgeStyle { overlap = False, noBackground = False} "3" -} -view : Model -> String -> BadgeInfo -view model databadge = +badgeStyle : Model -> String -> List Style +badgeStyle model databadge = let classes = [ - {css = " mdl-badge", show = True} - , {css = " mdl-badge--no-background", show = model.noBackground} - , {css = " mdl-badge--overlap", show = model.overlap} + {css = "mdl-badge", show = True} + , {css = "mdl-badge--no-background", show = model.noBackground} + , {css = "mdl-badge--overlap", show = model.overlap} ] |> List.filter .show |> List.map .css - |> List.foldl (++) "" + |> String.join " " in - { classes = " mdl-badge" ++ classes, dataBadge = attribute "data-badge" databadge} + [cs classes, attrib "data-badge" databadge] -{-| Create BadgeInfo with default values +{-| Create Badge Style List with default values Parameter will set a value to data-badge="value". Assigns string value to badge import Material.Badge as Badge - badgeInfo : Badge.BadgeInfo - badgeInfo = Badge.viewDefault "3" + badgeStyleListDefault : List Style + badgeStyleListDefault = Badge.badgeStyleDefault "3" -} -viewDefault : String -> BadgeInfo -viewDefault databadge = view model databadge +badgeStyleDefault : String -> List Style +badgeStyleDefault databadge = badgeStyle model databadge From dc28cd8294c1358cb8548b1ae7da81ea2c219c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Wed, 23 Mar 2016 10:34:40 +0100 Subject: [PATCH 07/12] Updates Demo Badge to use Style. Initial implementation --- examples/Demo.elm | 3 +-- examples/Demo/Badges.elm | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/examples/Demo.elm b/examples/Demo.elm index ee28fc3..e69f289 100644 --- a/examples/Demo.elm +++ b/examples/Demo.elm @@ -119,10 +119,9 @@ tabs = , ("Template", \addr model -> [Demo.Template.view (Signal.forwardTo addr TemplateAction) model.template]) -} - , ("Badges", \addr model -> Demo.Badges.view) + , ("Badges", \addr model -> Demo.Badges.view ) ] - tabViews : Array (Addr -> Model -> List Html) tabViews = List.map snd tabs |> Array.fromList diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm index 422085e..5ee4d78 100644 --- a/examples/Demo/Badges.elm +++ b/examples/Demo/Badges.elm @@ -1,18 +1,18 @@ module Demo.Badges where -import Material.Icon as Icon -import Material.Badge as Badge import Html exposing (..) -import Html.Attributes exposing (..) +import Html.Attributes exposing (class, style, key) +import Material.Badge as Badge +import Material.Style exposing (..) +-- VIEW view : List Html -view = - [ - h1 [][text "Badges"], - Icon.viewWithOptions "face" Icon.S18 [] { badgeInfo = Just (Badge.viewDefault "16")}, - Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.view { overlap = False, noBackground = False} "99")}, - Icon.viewWithOptions "add" Icon.S18 [] { badgeInfo = Just (Badge.view { overlap = False, noBackground = True} "4")}, - Icon.view "add" Icon.S18 [], - Icon.i "add" - ] +view = [ div [][p [][] + , styled span (Badge.badgeStyle { overlap = False, noBackground = False} "4") [ ] [ text "Span with badge" ] + , p [][] + , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "7") [ ] [ text "Span with no background badge" ] + , p [][] + , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "14") [ ] [ text "Span with badge overlap" ] + ] + ] \ No newline at end of file From a8f104144a9d82e56dad00630acf236c3a4c9455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Wed, 23 Mar 2016 11:05:40 +0100 Subject: [PATCH 08/12] Reverted back to initial implementation to keep Icon changes out of this PR --- src/Material/Icon.elm | 80 +++++++++---------------------------------- 1 file changed, 16 insertions(+), 64 deletions(-) diff --git a/src/Material/Icon.elm b/src/Material/Icon.elm index bfb3570..7b52263 100644 --- a/src/Material/Icon.elm +++ b/src/Material/Icon.elm @@ -1,6 +1,5 @@ module Material.Icon ( Size(..) - , viewWithOptions , view , i ) where @@ -16,12 +15,13 @@ This implementation assumes that you have or an equivalent means of loading the icons in your HTML header. -@docs i, Size, viewWithOptions, view +@docs i, Size, view -} + import Html exposing (i, text, Html, Attribute) -import Html.Attributes exposing (class, attribute) -import Material.Badge as Badge +import Html.Attributes exposing (class) + {-| Size of an icon. Constructors indicate their pixel size, i.e., `S18` is 18px. The constructor `S` gives you the default size, 24px. @@ -29,63 +29,6 @@ import Material.Badge as Badge type Size = S18 | S24 | S36 | S48 | S -{-| Options -See Badge on how to create a badge. --} -type alias Options = - { - badgeInfo : Maybe Badge.BadgeInfo - } - -{-| default options -See Badge on how to create a badge. --} -defaultOptions : Options -defaultOptions = - { - badgeInfo = Nothing - } - - -{-| View function for icons. Supply the -[Material Icons Library](https://design.google.com/icons/) name as -the first argument (replace spaces with underscores); and the size of the icon -as the second. Do not use this function to produce clickable icons; use -icon buttons in Material.Button for that. - -I.e., to produce a 48px -["trending flat"](https://design.google.com/icons/#ic_trending_flat) icon with -no attributes: - -See Badge for info on how to create a badge for options. - - import Material.Icon as Icon - - icon : Html - icon = Icon.viewWithOptions "trending_flat" Icon.S48 [] { badgeInfo = Just (Badge.viewDefault "16") - -This function will override any `class` set in `List Attribute`. --} -viewWithOptions : String -> Size -> List Attribute -> Options-> Html -viewWithOptions name size attrs options = - let - sz = - case size of - S18 -> " md-18" - S24 -> " md-24" - S36 -> " md-36" - S48 -> " md-48" - S -> "" - appAttrs = - case options.badgeInfo of - Just badgeInfo -> List.append attrs [badgeInfo.dataBadge] - Nothing -> attrs - optionClasses = - case options.badgeInfo of - Just badgeInfo -> badgeInfo.classes - Nothing -> "" - in - Html.i (class ("material-icons" ++ sz ++ optionClasses ) :: appAttrs) [text name] {-| View function for icons. Supply the [Material Icons Library](https://design.google.com/icons/) name as @@ -104,9 +47,18 @@ no attributes: This function will override any `class` set in `List Attribute`. -} - view : String -> Size -> List Attribute -> Html -view name size attrs = viewWithOptions name size attrs defaultOptions +view name size attrs = + let + sz = + case size of + S18 -> " md-18" + S24 -> " md-24" + S36 -> " md-36" + S48 -> " md-48" + S -> "" + in + Html.i (class ("material-icons" ++ sz) :: attrs) [text name] {-| Render a default-sized icon with no behaviour. The @@ -121,4 +73,4 @@ I.e., to produce a default size (24xp) "trending flat" icon: icon = Icon.i "trending_flat" -} i : String -> Html -i name = view name S [] +i name = view name S [] From a17c53dfddddb79083f30864d4fc2375604a7d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Wed, 23 Mar 2016 19:14:58 +0100 Subject: [PATCH 09/12] Changed style implementation of style for multiple styles. Not fully working --- examples/Demo/Badges.elm | 8 +++--- src/Material/Badge.elm | 58 +++++++++++----------------------------- src/Material/Style.elm | 22 ++++++++++++--- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm index 5ee4d78..d37a68f 100644 --- a/examples/Demo/Badges.elm +++ b/examples/Demo/Badges.elm @@ -9,10 +9,10 @@ import Material.Style exposing (..) view : List Html view = [ div [][p [][] - , styled span (Badge.badgeStyle { overlap = False, noBackground = False} "4") [ ] [ text "Span with badge" ] + , styled span [Badge.withBadge "56", Badge.overlap] [ ] [ text "Span with badge" ] , p [][] - , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "7") [ ] [ text "Span with no background badge" ] - , p [][] - , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "14") [ ] [ text "Span with badge overlap" ] + -- , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "7") [ ] [ text "Span with no background badge" ] + -- , p [][] + -- , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "14") [ ] [ text "Span with badge overlap" ] ] ] \ No newline at end of file diff --git a/src/Material/Badge.elm b/src/Material/Badge.elm index 572af2c..f928dad 100644 --- a/src/Material/Badge.elm +++ b/src/Material/Badge.elm @@ -1,7 +1,7 @@ module Material.Badge - ( Model - , badgeStyle - , badgeStyleDefault + ( noBackground + , overlap + , withBadge ) where {-| From the [Material Design Lite documentation](http://www.getmdl.io/components/#badges-section): @@ -33,23 +33,20 @@ module Material.Badge import String import Html exposing (Attribute) import Html.Attributes exposing (attribute) -import Material.Style exposing (Style, cs, cs', styled, attrib) +import Material.Style exposing (Style, cs, attrib, multiple) -{-| Model for Badge - ovelap: Bool to set css class - mdl-badge--overlap. Make the badge overlap with its container - noBackground: Bool to set css class - mdl-badge--no-background. Applies open-circle effect to badge +{-| No background for badge -} -type alias Model = - { overlap : Bool - , noBackground : Bool - } +noBackground : Style +noBackground = + cs "mdl-badge--no-background" -model : Model -model = - { overlap = True - , noBackground = False - } +{-| Overlap Badge +-} +overlap : Style +overlap = + cs "mdl-badge--overlap" {-| Style function for Badge @@ -62,29 +59,6 @@ model = badgeStyleList : List Style badgeStyleList = Badge.badgeStyle { overlap = False, noBackground = False} "3" -} -badgeStyle : Model -> String -> List Style -badgeStyle model databadge = - let classes = - [ - {css = "mdl-badge", show = True} - , {css = "mdl-badge--no-background", show = model.noBackground} - , {css = "mdl-badge--overlap", show = model.overlap} - ] - |> List.filter .show - |> List.map .css - |> String.join " " - in - [cs classes, attrib "data-badge" databadge] - - -{-| Create Badge Style List with default values - - Parameter will set a value to data-badge="value". Assigns string value to badge - - import Material.Badge as Badge - - badgeStyleListDefault : List Style - badgeStyleListDefault = Badge.badgeStyleDefault "3" --} -badgeStyleDefault : String -> List Style -badgeStyleDefault databadge = badgeStyle model databadge +withBadge : String -> Style +withBadge databadge = + multiple [cs "mdl-badge", attrib "data-badge" databadge] diff --git a/src/Material/Style.elm b/src/Material/Style.elm index eaa917b..283d9c9 100644 --- a/src/Material/Style.elm +++ b/src/Material/Style.elm @@ -1,7 +1,7 @@ module Material.Style ( Style , styled - , cs, cs', css, css', attrib + , cs, cs', css, css', attrib, multiple , stylesheet ) where @@ -17,7 +17,7 @@ add to or remove from the contents of an already constructed class Attribute.) @docs Style # Constructors -@docs cs, cs', css, css', attrib +@docs cs, cs', css, css', attrib, multiple # Application @docs styled @@ -42,8 +42,15 @@ type Style = Class String | CSS (String, String) | Attr (String, String) + | Multiple (List Style) | NOP +multipleOf : Style -> Maybe (List Style) +multipleOf style = + case style of + Multiple multiple -> Just multiple + _ -> Nothing + attrOf : Style -> Maybe (String, String) attrOf style = @@ -81,8 +88,12 @@ Note that if you do specify `style`, `class`, or `classList` attributes in (*), they will be discarded. -} styled : (List Attribute -> a) -> List Style -> List Attribute -> a -styled ctor styles attrs = +styled ctor styles attrs = let + multipleStyles = (List.filterMap multipleOf styles) + -- could need some help on how to proceed here + + -- (List.filterMap multipleOf styles) styleAttrs = (List.filterMap attrOf styles) |> List.map (\attrib -> Html.Attributes.attribute (fst attrib) ( snd attrib)) in @@ -120,6 +131,11 @@ attrib : String -> String -> Style attrib key value = Attr (key, value) +{-| Add a custom attribute +-} +multiple : List Style -> Style +multiple styles = + Multiple (styles) {-| Conditionally add a CSS style to a component -} From 903091e62588e908d0708726ccc5e622652c4e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Thu, 24 Mar 2016 09:29:47 +0100 Subject: [PATCH 10/12] Enables Style to handle recursive (Multiple) styles. Updated Badge implementation and demo --- examples/Demo/Badges.elm | 11 +++++++---- src/Material/Badge.elm | 17 +++++++---------- src/Material/Style.elm | 20 ++++++++++++++------ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm index d37a68f..66bfb10 100644 --- a/examples/Demo/Badges.elm +++ b/examples/Demo/Badges.elm @@ -9,10 +9,13 @@ import Material.Style exposing (..) view : List Html view = [ div [][p [][] - , styled span [Badge.withBadge "56", Badge.overlap] [ ] [ text "Span with badge" ] + , styled span [Badge.withBadge "2"] [ ] [ text "Span with badge" ] + , p [][] + , styled span [Badge.withBadge "22", Badge.noBackground] [ ] [ text "Span with no background badge" ] + , p [][] + , styled span [Badge.withBadge "33", Badge.overlap] [ ] [ text "Span with badge overlap" ] + , p [][] + , styled span [Badge.withBadge "99", Badge.overlap, Badge.noBackground] [ ] [ text "Span with badge overlap and no background" ] , p [][] - -- , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "7") [ ] [ text "Span with no background badge" ] - -- , p [][] - -- , styled span (Badge.badgeStyle { overlap = True, noBackground = False} "14") [ ] [ text "Span with badge overlap" ] ] ] \ No newline at end of file diff --git a/src/Material/Badge.elm b/src/Material/Badge.elm index f928dad..34b6a49 100644 --- a/src/Material/Badge.elm +++ b/src/Material/Badge.elm @@ -27,7 +27,7 @@ module Material.Badge > discover additional relevant content. Their design and use is therefore an important > factor in the overall user experience. -@docs viewDefault, view, BadgeInfo, Options +@docs withBadge, noBackground, overlap -} import String @@ -36,28 +36,25 @@ import Html.Attributes exposing (attribute) import Material.Style exposing (Style, cs, attrib, multiple) -{-| No background for badge +{-| Optional style for Badge. No background for badge -} noBackground : Style noBackground = cs "mdl-badge--no-background" -{-| Overlap Badge +{-| Optional style for Badge. Overlap Badge -} overlap : Style overlap = cs "mdl-badge--overlap" -{-| Style function for Badge - - First parameter will set Badge options. See Options for more info. - Last parameter will set a value to data-badge="value". Assigns string value to badge +{-| Main style for Badge + The parameter will set a value to data-badge="value". Assigns string value to badge import Material.Badge as Badge - - badgeStyleList : List Style - badgeStyleList = Badge.badgeStyle { overlap = False, noBackground = False} "3" + badgeStyle : Style + badgeStyle = Badge.withBadge "3" -} withBadge : String -> Style withBadge databadge = diff --git a/src/Material/Style.elm b/src/Material/Style.elm index 283d9c9..ad87e8d 100644 --- a/src/Material/Style.elm +++ b/src/Material/Style.elm @@ -72,6 +72,14 @@ classOf style = _ -> Nothing +flatten : Style -> List Style -> List Style +flatten style styles = + case style of + Multiple styles' -> + List.foldl flatten styles' styles + style -> + style :: styles + {-| Handle the common case of setting attributes of a standard Html node from a List Style. Use like this: @@ -90,16 +98,16 @@ Note that if you do specify `style`, `class`, or `classList` attributes in styled : (List Attribute -> a) -> List Style -> List Attribute -> a styled ctor styles attrs = let - multipleStyles = (List.filterMap multipleOf styles) + -- multipleStyles = (List.filterMap multipleOf styles) -- could need some help on how to proceed here - - -- (List.filterMap multipleOf styles) - styleAttrs = (List.filterMap attrOf styles) + flatStyles = List.foldl flatten [] styles + -- (List.filterMap multipleOf styles) + styleAttrs = (List.filterMap attrOf flatStyles) |> List.map (\attrib -> Html.Attributes.attribute (fst attrib) ( snd attrib)) in ctor - ( Html.Attributes.style (List.filterMap cssOf styles) - :: Html.Attributes.class (String.join " " (List.filterMap classOf styles)) + ( Html.Attributes.style (List.filterMap cssOf flatStyles) + :: Html.Attributes.class (String.join " " (List.filterMap classOf flatStyles)) :: List.append attrs styleAttrs ) From 3fbdadfe885e698e9e9dbd55de1d09bda4ff251b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Thu, 24 Mar 2016 10:00:55 +0100 Subject: [PATCH 11/12] Cleans up commented code --- src/Material/Style.elm | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Material/Style.elm b/src/Material/Style.elm index ad87e8d..a2d0ead 100644 --- a/src/Material/Style.elm +++ b/src/Material/Style.elm @@ -98,10 +98,7 @@ Note that if you do specify `style`, `class`, or `classList` attributes in styled : (List Attribute -> a) -> List Style -> List Attribute -> a styled ctor styles attrs = let - -- multipleStyles = (List.filterMap multipleOf styles) - -- could need some help on how to proceed here flatStyles = List.foldl flatten [] styles - -- (List.filterMap multipleOf styles) styleAttrs = (List.filterMap attrOf flatStyles) |> List.map (\attrib -> Html.Attributes.attribute (fst attrib) ( snd attrib)) in From 4867ee1918f292f5dc0a4a9e6391ef1d4ad637d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Rosseb=C3=B8?= Date: Thu, 24 Mar 2016 10:01:29 +0100 Subject: [PATCH 12/12] Updated Badge example to also show HTML symbols --- examples/Demo/Badges.elm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/Demo/Badges.elm b/examples/Demo/Badges.elm index 66bfb10..f9761ce 100644 --- a/examples/Demo/Badges.elm +++ b/examples/Demo/Badges.elm @@ -17,5 +17,11 @@ view = [ div [][p [][] , p [][] , styled span [Badge.withBadge "99", Badge.overlap, Badge.noBackground] [ ] [ text "Span with badge overlap and no background" ] , p [][] + , styled span [Badge.withBadge "♥"] [ ] [ text "Span with HTML symbol - Black heart suit" ] + , p [][] + , styled span [Badge.withBadge "→"] [ ] [ text "Span with HTML symbol - Rightwards arrow" ] + , p [][] + , styled span [Badge.withBadge "Δ"] [ ] [ text "Span with HTML symbol - Delta" ] + , p [][] ] ] \ No newline at end of file