From 5a4f19ac81864311b1bec979ef2e139251a3d13d Mon Sep 17 00:00:00 2001 From: Brian Hicks Date: Mon, 13 Jul 2020 09:41:01 -0500 Subject: [PATCH 1/5] add Nri.Ui.Text.V5 --- elm.json | 3 +- src/Nri/Ui/Text/V5.elm | 245 +++++++++++++++++++++++++++++++++ tests/elm-verify-examples.json | 1 + 3 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 src/Nri/Ui/Text/V5.elm diff --git a/elm.json b/elm.json index 0f6c7938..7c771cd8 100644 --- a/elm.json +++ b/elm.json @@ -60,6 +60,7 @@ "Nri.Ui.Tabs.V5", "Nri.Ui.Text.V2", "Nri.Ui.Text.V4", + "Nri.Ui.Text.V5", "Nri.Ui.Text.Writing.V1", "Nri.Ui.TextArea.V4", "Nri.Ui.TextInput.V6", @@ -90,4 +91,4 @@ "avh4/elm-program-test": "3.1.0 <= v < 4.0.0", "elm-explorations/test": "1.2.0 <= v < 2.0.0" } -} \ No newline at end of file +} diff --git a/src/Nri/Ui/Text/V5.elm b/src/Nri/Ui/Text/V5.elm new file mode 100644 index 00000000..bcb178ae --- /dev/null +++ b/src/Nri/Ui/Text/V5.elm @@ -0,0 +1,245 @@ +module Nri.Ui.Text.V5 exposing + ( caption, mediumBody, smallBody, smallBodyGray + , ugMediumBody, ugSmallBody + , Attribute, singleLine + , noWidow + ) + +{-| Post-release patches + + - adjusts link styles + +Changes from V3: + + - Removes Headings (they now live in Nri.Ui.Heading.V2) + +Changes from V4: + + - Added `Attribute` for customizing styles + + +## Understanding spacing + + - All text styles have a specific line-height. This is set so that when text in the given style + is long enough to wrap, the spacing between wrapped lines looks good. + - No text styles have padding. + - **Heading styles** do not have margin. It is up to the caller to add appropriate margin to the layout. + - **Paragraph styles** only have bottom margin, but with **:last-child bottom margin set to zero**. + This bottom margin is set to look good when multiple paragraphs of the same style follow one another. + - If you want content after the paragraph and don't want the margin, put the paragraph in a `div` so that it will be the last-child, which will get rid of the bottom margin. + - **User-authored content blocks** preserve line breaks and do not have margin. + + +## Headings + +Headings now live in Nri.Ui.Heading.V2. Here's a mapping to help with upgrades: + + | Nri.Ui.Text.V3 | Nri.Ui.Heading.V2 | + |===================|===================| + | Text.heading | Heading.h1 | + | Text.tagline | Heading.h2 | + | Text.subHeading | Heading.h3 | + | Text.smallHeading | Heading.h4 | + +If you look at your new code and go "hmm, those shouldn't be at this level of +heading" then you can customize the tag apart from the style using the new +API. See the Nri.Ui.Heading.V2 docs for details. + + +## Paragraph styles + +@docs caption, mediumBody, smallBody, smallBodyGray + + +## User-authored content blocks: + +@docs ugMediumBody, ugSmallBody + + +## Customizations + +@docs Attribute, singleLine + + +## Modifying strings to display nicely: + +@docs noWidow + +-} + +import Css exposing (..) +import Css.Global exposing (a, descendants) +import Html.Styled exposing (..) +import Html.Styled.Attributes exposing (css) +import Nri.Ui.Colors.V1 exposing (..) +import Nri.Ui.Fonts.V1 as Fonts + + +{-| -} +type Attribute + = SingleLine + + +{-| Text with this attribute will never wrap. +-} +singleLine : Attribute +singleLine = + SingleLine + + +{-| This is some medium body copy. +-} +mediumBody : List Attribute -> List (Html msg) -> Html msg +mediumBody attributes content = + p + [ paragraphStyles + { font = Fonts.baseFont + , color = gray20 + , size = 18 + , lineHeight = 28 + , weight = 400 + , margin = 10 + } + ] + content + + +{-| This is some small body copy. +-} +smallBody : List Attribute -> List (Html msg) -> Html msg +smallBody attributes content = + p + [ paragraphStyles + { font = Fonts.baseFont + , color = gray20 + , size = 15 + , lineHeight = 23 + , weight = 400 + , margin = 7 + } + ] + content + + +{-| This is some small body copy but it's gray. +-} +smallBodyGray : List Attribute -> List (Html msg) -> Html msg +smallBodyGray attributes content = + p + [ paragraphStyles + { font = Fonts.baseFont + , color = gray45 + , size = 15 + , lineHeight = 23 + , weight = 400 + , margin = 7 + } + ] + content + + +paragraphStyles config = + css + [ config.font + , fontSize (px config.size) + , color config.color + , lineHeight (px config.lineHeight) + , fontWeight (int config.weight) + , padding zero + , textAlign left + , margin4 (px 0) (px 0) (px config.margin) (px 0) + , Css.Global.descendants + [ Css.Global.a + [ textDecoration none + , color azure + , borderBottom3 (px 1) solid azure + , visited + [ color azure ] + ] + ] + , lastChild + [ margin zero + ] + ] + + +{-| This is a little note or caption. +-} +caption : List Attribute -> List (Html msg) -> Html msg +caption attributes content = + p + [ paragraphStyles + { font = Fonts.baseFont + , color = gray45 + , size = 13 + , lineHeight = 18 + , weight = 400 + , margin = 5 + } + ] + content + + +{-| User-generated text. +-} +ugMediumBody : List Attribute -> List (Html msg) -> Html msg +ugMediumBody = + p + [ css + [ Fonts.quizFont + , fontSize (px 18) + , lineHeight (px 30) + , whiteSpace preLine + , color gray20 + , margin zero + ] + ] + + +{-| User-generated text. +-} +ugSmallBody : List Attribute -> List (Html msg) -> Html msg +ugSmallBody = + p + [ css + [ Fonts.quizFont + , fontSize (px 16) + , lineHeight (px 25) + , whiteSpace preLine + , color gray20 + , margin zero + ] + ] + + +{-| Eliminate widows (single words on their own line caused by +wrapping) by inserting a non-breaking space if there are at least two +words. +-} +noWidow : String -> String +noWidow inputs = + let + -- this value is a unicode non-breaking space since Elm + -- doesn't support named character entities + nbsp = + "\u{00A0}" + + words = + String.split " " inputs + + insertPoint = + List.length words - 1 + in + words + |> List.indexedMap + (\i word -> + if i == 0 then + word + + else if i == insertPoint && insertPoint > 0 then + nbsp ++ word + + else + " " ++ word + ) + |> String.join "" diff --git a/tests/elm-verify-examples.json b/tests/elm-verify-examples.json index 4f803703..053597f3 100644 --- a/tests/elm-verify-examples.json +++ b/tests/elm-verify-examples.json @@ -56,6 +56,7 @@ "Nri.Ui.Tabs.V5", "Nri.Ui.Text.V2", "Nri.Ui.Text.V4", + "Nri.Ui.Text.V5", "Nri.Ui.Text.Writing.V1", "Nri.Ui.TextArea.V4", "Nri.Ui.TextInput.V6", From 273fe45f41ba3963a76e31ddfa27efc784d327d2 Mon Sep 17 00:00:00 2001 From: Brian Hicks Date: Mon, 13 Jul 2020 09:50:19 -0500 Subject: [PATCH 2/5] accept and apply styles --- src/Nri/Ui/Text/V5.elm | 46 +++++++++++++++++++++++++++++--- styleguide-app/Examples/Text.elm | 16 +++++------ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/Nri/Ui/Text/V5.elm b/src/Nri/Ui/Text/V5.elm index bcb178ae..2a06e10f 100644 --- a/src/Nri/Ui/Text/V5.elm +++ b/src/Nri/Ui/Text/V5.elm @@ -87,12 +87,35 @@ singleLine = SingleLine +styleForAttributes : List Attribute -> Style +styleForAttributes attrs = + let + config = + List.foldl + (\attr soFar -> + case attr of + SingleLine -> + { soFar | singleLine = True } + ) + { singleLine = False } + attrs + in + batch + [ if config.singleLine then + whiteSpace noWrap + + else + batch [] + ] + + {-| This is some medium body copy. -} mediumBody : List Attribute -> List (Html msg) -> Html msg mediumBody attributes content = p [ paragraphStyles + attributes { font = Fonts.baseFont , color = gray20 , size = 18 @@ -110,6 +133,7 @@ smallBody : List Attribute -> List (Html msg) -> Html msg smallBody attributes content = p [ paragraphStyles + attributes { font = Fonts.baseFont , color = gray20 , size = 15 @@ -127,6 +151,7 @@ smallBodyGray : List Attribute -> List (Html msg) -> Html msg smallBodyGray attributes content = p [ paragraphStyles + attributes { font = Fonts.baseFont , color = gray45 , size = 15 @@ -138,7 +163,18 @@ smallBodyGray attributes content = content -paragraphStyles config = +paragraphStyles : + List Attribute + -> + { color : Color + , font : Style + , lineHeight : Float + , margin : Float + , size : Float + , weight : Int + } + -> Html.Styled.Attribute msg +paragraphStyles attributes config = css [ config.font , fontSize (px config.size) @@ -160,6 +196,7 @@ paragraphStyles config = , lastChild [ margin zero ] + , styleForAttributes attributes ] @@ -169,6 +206,7 @@ caption : List Attribute -> List (Html msg) -> Html msg caption attributes content = p [ paragraphStyles + attributes { font = Fonts.baseFont , color = gray45 , size = 13 @@ -183,7 +221,7 @@ caption attributes content = {-| User-generated text. -} ugMediumBody : List Attribute -> List (Html msg) -> Html msg -ugMediumBody = +ugMediumBody attributes = p [ css [ Fonts.quizFont @@ -192,6 +230,7 @@ ugMediumBody = , whiteSpace preLine , color gray20 , margin zero + , styleForAttributes attributes ] ] @@ -199,7 +238,7 @@ ugMediumBody = {-| User-generated text. -} ugSmallBody : List Attribute -> List (Html msg) -> Html msg -ugSmallBody = +ugSmallBody attributes = p [ css [ Fonts.quizFont @@ -208,6 +247,7 @@ ugSmallBody = , whiteSpace preLine , color gray20 , margin zero + , styleForAttributes attributes ] ] diff --git a/styleguide-app/Examples/Text.elm b/styleguide-app/Examples/Text.elm index 9d166670..7b7fa2ab 100644 --- a/styleguide-app/Examples/Text.elm +++ b/styleguide-app/Examples/Text.elm @@ -13,7 +13,7 @@ import Html.Styled as Html import Html.Styled.Attributes as Attributes import KeyboardSupport exposing (Direction(..), Key(..)) import Nri.Ui.Heading.V2 as Heading -import Nri.Ui.Text.V4 as Text +import Nri.Ui.Text.V5 as Text {-| -} @@ -58,14 +58,14 @@ example = , Html.text " When I stepped out, into the bright sunlight from the darkness of the movie house, I had only two things on my mind: Paul Newman, and a ride home." ] in - [ Text.caption [ Html.text "NOTE: When using these styles, please read the documentation in the Elm module about \"Understanding spacing\"" ] + [ Text.caption [] [ Html.text "NOTE: When using these styles, please read the documentation in the Elm module about \"Understanding spacing\"" ] , Heading.h2 [ Heading.style Heading.Top ] [ Html.text "Paragraph styles" ] - , Text.mediumBody (exampleHtml "mediumBody") - , Text.smallBody (exampleHtml "smallBody") - , Text.smallBodyGray (exampleHtml "smallBodyGray") - , Text.caption (exampleHtml "caption") + , Text.mediumBody [] (exampleHtml "mediumBody") + , Text.smallBody [] (exampleHtml "smallBody") + , Text.smallBodyGray [] (exampleHtml "smallBodyGray") + , Text.caption [] (exampleHtml "caption") , Heading.h2 [ Heading.style Heading.Top ] [ Html.text "Paragraph styles for user-authored content" ] - , Text.ugMediumBody (exampleUGHtml "ugMediumBody") - , Text.ugSmallBody (exampleUGHtml "ugSmallBody") + , Text.ugMediumBody [] (exampleUGHtml "ugMediumBody") + , Text.ugSmallBody [] (exampleUGHtml "ugSmallBody") ] } From 7ab6ce1dd59b1e716563a2b1db04049fb4c2dfab Mon Sep 17 00:00:00 2001 From: Brian Hicks Date: Mon, 13 Jul 2020 09:59:36 -0500 Subject: [PATCH 3/5] add custom CSS override to Text --- src/Nri/Ui/Text/V5.elm | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Nri/Ui/Text/V5.elm b/src/Nri/Ui/Text/V5.elm index 2a06e10f..8f8e73a6 100644 --- a/src/Nri/Ui/Text/V5.elm +++ b/src/Nri/Ui/Text/V5.elm @@ -1,7 +1,7 @@ module Nri.Ui.Text.V5 exposing ( caption, mediumBody, smallBody, smallBodyGray , ugMediumBody, ugSmallBody - , Attribute, singleLine + , Attribute, singleLine, css , noWidow ) @@ -58,7 +58,7 @@ API. See the Nri.Ui.Heading.V2 docs for details. ## Customizations -@docs Attribute, singleLine +@docs Attribute, singleLine, css ## Modifying strings to display nicely: @@ -70,7 +70,7 @@ API. See the Nri.Ui.Heading.V2 docs for details. import Css exposing (..) import Css.Global exposing (a, descendants) import Html.Styled exposing (..) -import Html.Styled.Attributes exposing (css) +import Html.Styled.Attributes as Attrs import Nri.Ui.Colors.V1 exposing (..) import Nri.Ui.Fonts.V1 as Fonts @@ -78,6 +78,7 @@ import Nri.Ui.Fonts.V1 as Fonts {-| -} type Attribute = SingleLine + | Css (List Style) {-| Text with this attribute will never wrap. @@ -87,6 +88,14 @@ singleLine = SingleLine +{-| Add some custom CSS to the text. If you find yourself using this a lot, +please add a stricter attribute to noredink-ui! +-} +css : List Style -> Attribute +css = + Css + + styleForAttributes : List Attribute -> Style styleForAttributes attrs = let @@ -96,8 +105,13 @@ styleForAttributes attrs = case attr of SingleLine -> { soFar | singleLine = True } + + Css styles -> + { soFar | styles = soFar.styles ++ styles } ) - { singleLine = False } + { singleLine = False + , styles = [] + } attrs in batch @@ -106,6 +120,7 @@ styleForAttributes attrs = else batch [] + , batch config.styles ] @@ -175,7 +190,7 @@ paragraphStyles : } -> Html.Styled.Attribute msg paragraphStyles attributes config = - css + Attrs.css [ config.font , fontSize (px config.size) , color config.color @@ -223,7 +238,7 @@ caption attributes content = ugMediumBody : List Attribute -> List (Html msg) -> Html msg ugMediumBody attributes = p - [ css + [ Attrs.css [ Fonts.quizFont , fontSize (px 18) , lineHeight (px 30) @@ -240,7 +255,7 @@ ugMediumBody attributes = ugSmallBody : List Attribute -> List (Html msg) -> Html msg ugSmallBody attributes = p - [ css + [ Attrs.css [ Fonts.quizFont , fontSize (px 16) , lineHeight (px 25) From 1c14e66db222ddc72acc707a07eb9c78d1723452 Mon Sep 17 00:00:00 2001 From: Brian Hicks Date: Mon, 13 Jul 2020 10:11:22 -0500 Subject: [PATCH 4/5] rename singleLine to noBreak --- src/Nri/Ui/Text/V5.elm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Nri/Ui/Text/V5.elm b/src/Nri/Ui/Text/V5.elm index 8f8e73a6..51abafd3 100644 --- a/src/Nri/Ui/Text/V5.elm +++ b/src/Nri/Ui/Text/V5.elm @@ -1,7 +1,7 @@ module Nri.Ui.Text.V5 exposing ( caption, mediumBody, smallBody, smallBodyGray , ugMediumBody, ugSmallBody - , Attribute, singleLine, css + , Attribute, noBreak, css , noWidow ) @@ -58,7 +58,7 @@ API. See the Nri.Ui.Heading.V2 docs for details. ## Customizations -@docs Attribute, singleLine, css +@docs Attribute, noBreak, css ## Modifying strings to display nicely: @@ -77,15 +77,15 @@ import Nri.Ui.Fonts.V1 as Fonts {-| -} type Attribute - = SingleLine + = NoBreak | Css (List Style) {-| Text with this attribute will never wrap. -} -singleLine : Attribute -singleLine = - SingleLine +noBreak : Attribute +noBreak = + NoBreak {-| Add some custom CSS to the text. If you find yourself using this a lot, @@ -103,19 +103,19 @@ styleForAttributes attrs = List.foldl (\attr soFar -> case attr of - SingleLine -> - { soFar | singleLine = True } + NoBreak -> + { soFar | noBreak = True } Css styles -> { soFar | styles = soFar.styles ++ styles } ) - { singleLine = False + { noBreak = False , styles = [] } attrs in batch - [ if config.singleLine then + [ if config.noBreak then whiteSpace noWrap else From 789d0ae7c8430e0874f239c928b1c1d07a41462f Mon Sep 17 00:00:00 2001 From: Brian Hicks Date: Mon, 13 Jul 2020 10:11:33 -0500 Subject: [PATCH 5/5] add examples of attribute-based customization to the style guide --- styleguide-app/Examples/Text.elm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/styleguide-app/Examples/Text.elm b/styleguide-app/Examples/Text.elm index 7b7fa2ab..800b04df 100644 --- a/styleguide-app/Examples/Text.elm +++ b/styleguide-app/Examples/Text.elm @@ -8,6 +8,7 @@ module Examples.Text exposing (example, State, Msg) import AtomicDesignType exposing (AtomicDesignType(..)) import Category exposing (Category(..)) +import Css import Example exposing (Example) import Html.Styled as Html import Html.Styled.Attributes as Attributes @@ -67,5 +68,19 @@ example = , Heading.h2 [ Heading.style Heading.Top ] [ Html.text "Paragraph styles for user-authored content" ] , Text.ugMediumBody [] (exampleUGHtml "ugMediumBody") , Text.ugSmallBody [] (exampleUGHtml "ugSmallBody") + , Heading.h2 [ Heading.style Heading.Top ] [ Html.text "One-Off Styles" ] + , Text.mediumBody + [ Text.css [ Css.padding (Css.px 20) ] ] + [ Html.text "I've got more padding than my siblings!" ] + , Html.div + [ Attributes.css + [ Css.width (Css.px 80) + , Css.border3 (Css.px 1) Css.solid (Css.hex "000") + ] + ] + [ Text.mediumBody + [ Text.noBreak ] + [ Html.text "I won't ever break, no matter how narrow my container is." ] + ] ] }