mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2025-01-03 12:02:19 +03:00
Merge pull request #320 from NoRedInk/nri-ui-text-without-headings
add Nri.Ui.Text.V4 without headings
This commit is contained in:
commit
e477fe4efa
1
elm.json
1
elm.json
@ -71,6 +71,7 @@
|
||||
"Nri.Ui.Tabs.V4",
|
||||
"Nri.Ui.Text.V2",
|
||||
"Nri.Ui.Text.V3",
|
||||
"Nri.Ui.Text.V4",
|
||||
"Nri.Ui.Text.Writing.V1",
|
||||
"Nri.Ui.TextArea.V3",
|
||||
"Nri.Ui.TextArea.V4",
|
||||
|
@ -5,8 +5,17 @@ module Nri.Ui.Heading.V1 exposing
|
||||
, view
|
||||
)
|
||||
|
||||
{-| Headings such as you'd find in Nri.Ui.Text.V3, but customization options for
|
||||
accessibility.
|
||||
{-| Headings with customization options for accessibility.
|
||||
|
||||
|
||||
## 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 heading styles have padding.
|
||||
- **Heading styles** do not have margin. It is up to the caller to add
|
||||
appropriate margin to the layout.
|
||||
|
||||
@docs Heading, heading
|
||||
|
||||
|
@ -46,12 +46,9 @@ make a new Text version, please remove them.
|
||||
|
||||
-}
|
||||
|
||||
import Css exposing (..)
|
||||
import Html.Styled exposing (..)
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import Nri.Ui.Colors.V1 exposing (..)
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Html.Styled exposing (Html)
|
||||
import Nri.Ui.Heading.V1 as Heading
|
||||
import Nri.Ui.Text.V4 as V4
|
||||
|
||||
|
||||
{-| This is a Page Heading.
|
||||
@ -97,117 +94,43 @@ smallHeading content =
|
||||
{-| This is some medium body copy.
|
||||
-}
|
||||
mediumBody : List (Html msg) -> Html msg
|
||||
mediumBody content =
|
||||
p
|
||||
[ paragraphStyles
|
||||
{ font = Fonts.baseFont
|
||||
, color = gray20
|
||||
, size = 18
|
||||
, lineHeight = 28
|
||||
, weight = 400
|
||||
, margin = 10
|
||||
}
|
||||
]
|
||||
content
|
||||
mediumBody =
|
||||
V4.mediumBody
|
||||
|
||||
|
||||
{-| This is some small body copy.
|
||||
-}
|
||||
smallBody : List (Html msg) -> Html msg
|
||||
smallBody content =
|
||||
p
|
||||
[ paragraphStyles
|
||||
{ font = Fonts.baseFont
|
||||
, color = gray20
|
||||
, size = 15
|
||||
, lineHeight = 23
|
||||
, weight = 400
|
||||
, margin = 7
|
||||
}
|
||||
]
|
||||
content
|
||||
smallBody =
|
||||
V4.smallBody
|
||||
|
||||
|
||||
{-| This is some small body copy but it's gray.
|
||||
-}
|
||||
smallBodyGray : List (Html msg) -> Html msg
|
||||
smallBodyGray 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)
|
||||
, lastChild
|
||||
[ margin zero
|
||||
]
|
||||
]
|
||||
smallBodyGray =
|
||||
V4.smallBodyGray
|
||||
|
||||
|
||||
{-| This is a little note or caption.
|
||||
-}
|
||||
caption : List (Html msg) -> Html msg
|
||||
caption content =
|
||||
p
|
||||
[ paragraphStyles
|
||||
{ font = Fonts.baseFont
|
||||
, color = gray45
|
||||
, size = 13
|
||||
, lineHeight = 18
|
||||
, weight = 400
|
||||
, margin = 5
|
||||
}
|
||||
]
|
||||
content
|
||||
caption =
|
||||
V4.caption
|
||||
|
||||
|
||||
{-| User-generated text.
|
||||
-}
|
||||
ugMediumBody : List (Html msg) -> Html msg
|
||||
ugMediumBody =
|
||||
p
|
||||
[ css
|
||||
[ Fonts.quizFont
|
||||
, fontSize (px 18)
|
||||
, lineHeight (px 30)
|
||||
, whiteSpace preLine
|
||||
, color gray20
|
||||
, margin zero
|
||||
]
|
||||
]
|
||||
V4.ugMediumBody
|
||||
|
||||
|
||||
{-| User-generated text.
|
||||
-}
|
||||
ugSmallBody : List (Html msg) -> Html msg
|
||||
ugSmallBody =
|
||||
p
|
||||
[ css
|
||||
[ Fonts.quizFont
|
||||
, fontSize (px 16)
|
||||
, lineHeight (px 25)
|
||||
, whiteSpace preLine
|
||||
, color gray20
|
||||
, margin zero
|
||||
]
|
||||
]
|
||||
V4.ugSmallBody
|
||||
|
||||
|
||||
{-| Eliminate widows (single words on their own line caused by
|
||||
@ -215,29 +138,5 @@ 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 ""
|
||||
noWidow =
|
||||
V4.noWidow
|
||||
|
193
src/Nri/Ui/Text/V4.elm
Normal file
193
src/Nri/Ui/Text/V4.elm
Normal file
@ -0,0 +1,193 @@
|
||||
module Nri.Ui.Text.V4 exposing
|
||||
( caption, mediumBody, smallBody, smallBodyGray
|
||||
, ugMediumBody, ugSmallBody
|
||||
, noWidow
|
||||
)
|
||||
|
||||
{-| Changes from V3:
|
||||
|
||||
- Removes Headings (they now live in Nri.Ui.Heading.V1)
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
|
||||
## Paragraph styles
|
||||
|
||||
@docs caption, mediumBody, smallBody, smallBodyGray
|
||||
|
||||
|
||||
## User-authored content blocks:
|
||||
|
||||
@docs ugMediumBody, ugSmallBody
|
||||
|
||||
|
||||
## Modifying strings to display nicely:
|
||||
|
||||
@docs noWidow
|
||||
|
||||
-}
|
||||
|
||||
import Css exposing (..)
|
||||
import Html.Styled exposing (..)
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import Nri.Ui.Colors.V1 exposing (..)
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
|
||||
|
||||
{-| This is some medium body copy.
|
||||
-}
|
||||
mediumBody : List (Html msg) -> Html msg
|
||||
mediumBody 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 (Html msg) -> Html msg
|
||||
smallBody 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 (Html msg) -> Html msg
|
||||
smallBodyGray 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)
|
||||
, lastChild
|
||||
[ margin zero
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
{-| This is a little note or caption.
|
||||
-}
|
||||
caption : List (Html msg) -> Html msg
|
||||
caption content =
|
||||
p
|
||||
[ paragraphStyles
|
||||
{ font = Fonts.baseFont
|
||||
, color = gray45
|
||||
, size = 13
|
||||
, lineHeight = 18
|
||||
, weight = 400
|
||||
, margin = 5
|
||||
}
|
||||
]
|
||||
content
|
||||
|
||||
|
||||
{-| User-generated text.
|
||||
-}
|
||||
ugMediumBody : 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 (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 ""
|
@ -16,7 +16,6 @@ import Nri.Ui.AssetPath exposing (Asset)
|
||||
import Nri.Ui.Button.V9 as Button
|
||||
import Nri.Ui.Icon.V5 as Icon
|
||||
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
|
||||
import Nri.Ui.Text.V3 as Text
|
||||
|
||||
|
||||
{-| -}
|
||||
|
@ -15,7 +15,7 @@ import ModuleExample as ModuleExample exposing (Category(..), ModuleExample, Mod
|
||||
import Nri.Ui.ClickableText.V2 as ClickableText exposing (Size(..))
|
||||
import Nri.Ui.Icon.V5 as Icon
|
||||
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
|
||||
import Nri.Ui.Text.V3 as Text
|
||||
import Nri.Ui.Text.V4 as Text
|
||||
|
||||
|
||||
{-| -}
|
||||
|
@ -13,8 +13,9 @@ import Html.Styled as Html exposing (Html)
|
||||
import Html.Styled.Attributes exposing (css, style, title)
|
||||
import ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.Colors.V1 exposing (..)
|
||||
import Nri.Ui.Heading.V1 as Heading
|
||||
import Nri.Ui.Icon.V5 as Icon
|
||||
import Nri.Ui.Text.V3 as Text
|
||||
import Nri.Ui.Text.V4 as Text
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -128,7 +129,10 @@ viewIconSection :
|
||||
-> Html msg
|
||||
viewIconSection headerText icons =
|
||||
Html.section []
|
||||
[ Text.subHeading [ Html.text headerText ]
|
||||
[ Heading.heading [ Html.text headerText ]
|
||||
|> Heading.withDocumentLevel Heading.H2
|
||||
|> Heading.withVisualLevel Heading.Subhead
|
||||
|> Heading.view
|
||||
, Html.div [ css [ Css.displayFlex, Css.flexWrap Css.wrap ] ]
|
||||
(List.map viewIcon icons)
|
||||
]
|
||||
|
@ -9,13 +9,13 @@ module Examples.Text exposing (example)
|
||||
import Html.Styled as Html
|
||||
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.Heading.V1 as Heading exposing (DocumentLevel(..), VisualLevel(..), heading, withDocumentLevel, withVisualLevel)
|
||||
import Nri.Ui.Text.V3 as Text
|
||||
import Nri.Ui.Text.V4 as Text
|
||||
|
||||
|
||||
{-| -}
|
||||
example : ModuleExample msg
|
||||
example =
|
||||
{ name = "Nri.Ui.Text.V3 (with headers from Nri.Ui.Heading.V1)"
|
||||
{ name = "Nri.Ui.Text.V4 (with headers from Nri.Ui.Heading.V1)"
|
||||
, category = Text
|
||||
, content =
|
||||
let
|
||||
@ -44,13 +44,19 @@ example =
|
||||
|> withDocumentLevel H4
|
||||
|> Heading.view
|
||||
, Html.hr [] []
|
||||
, Text.heading [ Html.text "Paragraph styles" ]
|
||||
, heading [ Html.text "Paragraph styles" ]
|
||||
|> withVisualLevel Top
|
||||
|> withDocumentLevel H2
|
||||
|> Heading.view
|
||||
, Text.mediumBody [ Html.text <| "This is a mediumBody. " ++ longerBody ]
|
||||
, Text.smallBody [ Html.text <| "This is a smallBody. " ++ longerBody ]
|
||||
, Text.smallBodyGray [ Html.text <| "This is a smallBodyGray. " ++ longerBody ]
|
||||
, Text.caption [ Html.text <| "This is a caption. " ++ longerBody ]
|
||||
, Html.hr [] []
|
||||
, Text.heading [ Html.text "Paragraph styles for user-authored content" ]
|
||||
, heading [ Html.text "Paragraph styles for user-authored content" ]
|
||||
|> withVisualLevel Top
|
||||
|> withDocumentLevel H2
|
||||
|> Heading.view
|
||||
, Text.ugMediumBody [ Html.text <| "This is an ugMediumBody. " ++ longerBody ]
|
||||
, Text.ugSmallBody [ Html.text <| "This is an ugSmallBody. " ++ longerBody ]
|
||||
]
|
||||
|
@ -11,7 +11,7 @@ import Html.Styled as Html
|
||||
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.AssetPath exposing (Asset(..))
|
||||
import Nri.Ui.Checkbox.V5 as Checkbox
|
||||
import Nri.Ui.Text.V3 as Text
|
||||
import Nri.Ui.Heading.V1 as Heading
|
||||
import Nri.Ui.TextArea.V4 as TextArea
|
||||
|
||||
|
||||
@ -38,7 +38,10 @@ example parentMessage state =
|
||||
{ name = "Nri.Ui.TextArea.V4"
|
||||
, category = Inputs
|
||||
, content =
|
||||
[ Text.heading [ Html.text "Textarea controls" ]
|
||||
[ Heading.heading [ Html.text "Textarea controls" ]
|
||||
|> Heading.withDocumentLevel Heading.H1
|
||||
|> Heading.withVisualLevel Heading.Top
|
||||
|> Heading.view
|
||||
, Html.div []
|
||||
[ Checkbox.viewWithLabel
|
||||
{ identifier = "show-textarea-label"
|
||||
|
@ -1,29 +1,45 @@
|
||||
module Headings exposing (h1, h2, h3, h4, h5)
|
||||
|
||||
import Html.Styled exposing (Html)
|
||||
import Nri.Ui.Text.V3 as Text
|
||||
import Nri.Ui.Heading.V1 as Headings exposing (..)
|
||||
import Nri.Ui.Text.V4 as Text
|
||||
|
||||
|
||||
h1 : List (Html msg) -> Html msg
|
||||
h1 =
|
||||
Text.heading
|
||||
heading
|
||||
>> withVisualLevel Top
|
||||
>> withDocumentLevel H1
|
||||
>> view
|
||||
|
||||
|
||||
h2 : List (Html msg) -> Html msg
|
||||
h2 =
|
||||
Text.heading
|
||||
heading
|
||||
>> withVisualLevel Top
|
||||
>> withDocumentLevel H2
|
||||
>> view
|
||||
|
||||
|
||||
h3 : List (Html msg) -> Html msg
|
||||
h3 =
|
||||
Text.subHeading
|
||||
heading
|
||||
>> withVisualLevel Subhead
|
||||
>> withDocumentLevel H3
|
||||
>> view
|
||||
|
||||
|
||||
h4 : List (Html msg) -> Html msg
|
||||
h4 =
|
||||
Text.subHeading
|
||||
heading
|
||||
>> withVisualLevel Subhead
|
||||
>> withDocumentLevel H4
|
||||
>> view
|
||||
|
||||
|
||||
h5 : List (Html msg) -> Html msg
|
||||
h5 =
|
||||
Text.subHeading
|
||||
heading
|
||||
>> withVisualLevel Subhead
|
||||
>> withDocumentLevel H5
|
||||
>> view
|
||||
|
Loading…
Reference in New Issue
Block a user