Merge pull request #776 from NoRedInk/hack/tessa/browse-mode

Hack/tessa/browse mode
This commit is contained in:
Lindsay Wardell 2021-11-08 08:56:34 -08:00 committed by GitHub
commit 8ad148be5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 745 additions and 180 deletions

View File

@ -33,11 +33,7 @@ hint = 'Use Accessibility.Widgetd.Widget'
[forbidden.Html] [forbidden.Html]
hint = 'Use Html.Styled' hint = 'Use Html.Styled'
usages = [ usages = ['styleguide-app/../src/Nri/Ui/Button/V8.elm']
'styleguide-app/../src/Nri/Ui/Button/V8.elm',
'styleguide-app/Examples/Modal.elm',
'styleguide-app/Main.elm',
]
[forbidden."Nri.Ui.Accordion.V1"] [forbidden."Nri.Ui.Accordion.V1"]
hint = 'upgrade to V3' hint = 'upgrade to V3'

View File

@ -23,7 +23,7 @@ import Nri.Ui.Html.V3 exposing (viewIf)
{-| The default page information is for the button {-| The default page information is for the button
which will direct the user back to the main page of which will direct the user back to the main page of
the SPA. Specify it's name and the message which will the SPA. Specify its name and the message which will
navigate to the page. navigate to the page.
-} -}
type alias DefaultPage msg = type alias DefaultPage msg =

View File

@ -1,8 +1,8 @@
module Nri.Ui.Switch.V1 exposing (view, Attribute, onSwitch, disabled, id, label) module Nri.Ui.Switch.V1 exposing (view, Attribute, onSwitch, disabled, id, label, custom)
{-| {-|
@docs view, Attribute, onSwitch, disabled, id, label @docs view, Attribute, onSwitch, disabled, id, label, custom
-} -}
@ -27,6 +27,7 @@ type Attribute msg
| Id String | Id String
| Label (Html msg) | Label (Html msg)
| Disabled | Disabled
| Custom (List (Html.Attribute Never))
{-| Specify what happens when the switch is toggled. {-| Specify what happens when the switch is toggled.
@ -63,10 +64,18 @@ label =
Label Label
{-| Pass custom attributes through to be attached to the underlying input.
-}
custom : List (Html.Attribute Never) -> Attribute msg
custom =
Custom
type alias Config msg = type alias Config msg =
{ onSwitch : Maybe (Bool -> msg) { onSwitch : Maybe (Bool -> msg)
, id : String , id : String
, label : Maybe (Html msg) , label : Maybe (Html msg)
, attributes : List (Html.Attribute Never)
} }
@ -75,6 +84,7 @@ defaultConfig =
{ onSwitch = Nothing { onSwitch = Nothing
, id = "nri-ui-switch-with-default-id" , id = "nri-ui-switch-with-default-id"
, label = Nothing , label = Nothing
, attributes = []
} }
@ -93,6 +103,9 @@ customize attr config =
Label label_ -> Label label_ ->
{ config | label = Just label_ } { config | label = Just label_ }
Custom custom_ ->
{ config | attributes = custom_ }
{-| Render a switch. The boolean here indicates whether the switch is on {-| Render a switch. The boolean here indicates whether the switch is on
or not. or not.
@ -133,6 +146,7 @@ view attrs isOn =
{ id = config.id { id = config.id
, onCheck = config.onSwitch , onCheck = config.onSwitch
, checked = isOn , checked = isOn
, attributes = config.attributes
} }
, Nri.Ui.Svg.V1.toHtml , Nri.Ui.Svg.V1.toHtml
(viewSwitch (viewSwitch
@ -162,26 +176,29 @@ viewCheckbox :
{ id : String { id : String
, onCheck : Maybe (Bool -> msg) , onCheck : Maybe (Bool -> msg)
, checked : Bool , checked : Bool
, attributes : List (Html.Attribute Never)
} }
-> Html msg -> Html msg
viewCheckbox config = viewCheckbox config =
Html.checkbox config.id Html.checkbox config.id
(Just config.checked) (Just config.checked)
[ Attributes.id config.id ([ Attributes.id config.id
, Attributes.css , Attributes.css
[ Css.position Css.absolute [ Css.position Css.absolute
, Css.top (Css.px 10) , Css.top (Css.px 10)
, Css.left (Css.px 10) , Css.left (Css.px 10)
, Css.zIndex (Css.int 0) , Css.zIndex (Css.int 0)
, Css.opacity (Css.num 0) , Css.opacity (Css.num 0)
] ]
, case config.onCheck of , case config.onCheck of
Just onCheck -> Just onCheck ->
Events.onCheck onCheck Events.onCheck onCheck
Nothing -> Nothing ->
Widget.disabled True Widget.disabled True
] ]
++ List.map (Attributes.map never) config.attributes
)
viewSwitch : viewSwitch :

View File

@ -1,15 +1,22 @@
module Example exposing (Example, view, wrapMsg, wrapState) module Example exposing (Example, preview, view, wrapMsg, wrapState)
import Category exposing (Category) import Category exposing (Category)
import Css exposing (..) import Css exposing (..)
import Css.Global exposing (a, descendants) import Css.Global exposing (a, descendants)
import Html.Styled as Html exposing (Html) import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes import Html.Styled.Attributes as Attributes
import Html.Styled.Events as Events
import Html.Styled.Lazy as Lazy import Html.Styled.Lazy as Lazy
import KeyboardSupport exposing (KeyboardSupport) import KeyboardSupport exposing (KeyboardSupport)
import Nri.Ui.Colors.V1 exposing (..) import Nri.Ui.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors exposing (..)
import Nri.Ui.Container.V2 as Container
import Nri.Ui.Fonts.V1 as Fonts import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Html.Attributes.V2 as AttributeExtras exposing (targetBlank) import Nri.Ui.Html.Attributes.V2 as AttributeExtras exposing (targetBlank)
import Nri.Ui.UiIcon.V1 as UiIcon
import Routes exposing (Route)
type alias Example state msg = type alias Example state msg =
@ -18,12 +25,18 @@ type alias Example state msg =
, state : state , state : state
, update : msg -> state -> ( state, Cmd msg ) , update : msg -> state -> ( state, Cmd msg )
, subscriptions : state -> Sub msg , subscriptions : state -> Sub msg
, preview : List (Html Never)
, view : state -> List (Html msg) , view : state -> List (Html msg)
, categories : List Category , categories : List Category
, keyboardSupport : List KeyboardSupport , keyboardSupport : List KeyboardSupport
} }
fullName : Example state msg -> String
fullName example =
"Nri.Ui." ++ example.name ++ ".V" ++ String.fromInt example.version
wrapMsg : wrapMsg :
(msg -> msg2) (msg -> msg2)
-> (msg2 -> Maybe msg) -> (msg2 -> Maybe msg)
@ -43,6 +56,7 @@ wrapMsg wrapMsg_ unwrapMsg example =
Nothing -> Nothing ->
( state, Cmd.none ) ( state, Cmd.none )
, subscriptions = \state -> Sub.map wrapMsg_ (example.subscriptions state) , subscriptions = \state -> Sub.map wrapMsg_ (example.subscriptions state)
, preview = example.preview
, view = \state -> List.map (Html.map wrapMsg_) (example.view state) , view = \state -> List.map (Html.map wrapMsg_) (example.view state)
, categories = example.categories , categories = example.categories
, keyboardSupport = example.keyboardSupport , keyboardSupport = example.keyboardSupport
@ -71,6 +85,7 @@ wrapState wrapState_ unwrapState example =
unwrapState unwrapState
>> Maybe.map example.subscriptions >> Maybe.map example.subscriptions
>> Maybe.withDefault Sub.none >> Maybe.withDefault Sub.none
, preview = example.preview
, view = , view =
unwrapState unwrapState
>> Maybe.map example.view >> Maybe.map example.view
@ -80,22 +95,77 @@ wrapState wrapState_ unwrapState example =
} }
view : Example state msg -> Html msg preview : (Route -> msg2) -> Example state msg -> Html msg2
view = preview navigate =
Lazy.lazy view_ Lazy.lazy (preview_ navigate)
preview_ : (Route -> msg2) -> Example state msg -> Html msg2
preview_ navigate example =
Container.view
[ Container.gray
, Container.css
[ Css.flexBasis (Css.px 150)
, Css.hover
[ Css.backgroundColor Colors.glacier
, Css.cursor Css.pointer
]
]
, Container.custom [ Events.onClick (navigate (Routes.Doodad example.name)) ]
, Container.html
(ClickableText.link example.name
[ ClickableText.href (exampleHref example)
, ClickableText.css [ Css.marginBottom (Css.px 10) ]
]
:: [ Html.div
[ Attributes.css
[ Css.displayFlex
, Css.flexDirection Css.column
]
]
(List.map (Html.map never) example.preview)
]
)
]
view : Maybe Route -> Example state msg -> Html msg
view previousRoute example =
Container.view
[ Container.pillow
, Container.css
[ Css.position Css.relative
, Css.margin (Css.px 10)
, Css.minHeight (Css.calc (Css.vh 100) Css.minus (Css.px 20))
, Css.boxSizing Css.borderBox
]
, Container.html
[ Lazy.lazy view_ example
, ClickableSvg.link ("Close " ++ example.name ++ " example")
UiIcon.x
[ ClickableSvg.href
(Maybe.withDefault Routes.All previousRoute
|> Routes.toString
)
, ClickableSvg.small
, ClickableSvg.css
[ Css.position Css.absolute
, Css.top (Css.px 15)
, Css.right (Css.px 15)
]
]
]
]
view_ : Example state msg -> Html msg view_ : Example state msg -> Html msg
view_ example = view_ example =
let
fullName =
"Nri.Ui." ++ example.name ++ ".V" ++ String.fromInt example.version
in
Html.div Html.div
[ -- this class makes the axe accessibility checking output easier to parse [ -- this class makes the axe accessibility checking output easier to parse
String.replace "." "-" example.name String.replace "." "-" example.name
|> (++) "module-example__" |> (++) "module-example__"
|> Attributes.class |> Attributes.class
, Attributes.id (String.replace "." "-" example.name)
] ]
[ Html.div [ Html.div
[ Attributes.css [ Attributes.css
@ -107,52 +177,57 @@ view_ example =
, descendants [ Css.Global.a [ textDecoration none ] ] , descendants [ Css.Global.a [ textDecoration none ] ]
] ]
] ]
[ Html.styled Html.h2 [ exampleLink example
[ color navy , docsLink example
, fontSize (px 20) , srcLink example
, marginTop zero
, marginBottom zero
, Fonts.baseFont
]
[]
[ Html.a
[ Attributes.href ("#/doodad/" ++ example.name)
, Attributes.class "module-example__doodad-link"
, -- this data attribute is used to name the Percy screenshots
String.replace "." "-" example.name
|> Attributes.attribute "data-percy-name"
]
[ Html.text fullName ]
]
, String.replace "." "-" fullName
|> (++) "https://package.elm-lang.org/packages/NoRedInk/noredink-ui/latest/"
|> viewLink "Docs"
, String.replace "." "/" fullName
++ ".elm"
|> (++) "https://github.com/NoRedInk/noredink-ui/blob/master/src/"
|> viewLink "Source"
] ]
, KeyboardSupport.view example.keyboardSupport , KeyboardSupport.view example.keyboardSupport
, Html.div , Html.div [] (example.view example.state)
[ Attributes.css ]
[ padding (px 40)
, boxShadow5 zero (px 2) (px 4) zero (rgba 0 0 0 0.25)
, border3 (px 1) solid gray92 exampleHref : Example state msg -> String
, borderRadius (px 20) exampleHref example =
, margin3 (px 10) zero (px 40) Routes.toString (Routes.Doodad example.name)
exampleLink : Example state msg -> Html msg
exampleLink example =
Heading.h2 []
[ ClickableText.link (fullName example)
[ ClickableText.href (exampleHref example)
, ClickableText.large
, ClickableText.custom
[ -- this data attribute is used to name the Percy screenshots
String.replace "." "-" example.name
|> Attributes.attribute "data-percy-name"
] ]
] ]
(example.view example.state)
] ]
viewLink : String -> String -> Html msg docsLink : Example state msg -> Html msg
viewLink text href = docsLink example =
Html.a let
([ Attributes.href href link =
, Attributes.css [ Css.display Css.block, marginLeft (px 20) ] "https://package.elm-lang.org/packages/NoRedInk/noredink-ui/latest/"
] ++ String.replace "." "-" (fullName example)
++ targetBlank in
) ClickableText.link "Docs"
[ Html.text text [ ClickableText.linkExternal link
, ClickableText.css [ Css.marginLeft (Css.px 20) ]
]
srcLink : Example state msg -> Html msg
srcLink example =
let
link =
String.replace "." "/" (fullName example)
++ ".elm"
|> (++) "https://github.com/NoRedInk/noredink-ui/blob/master/src/"
in
ClickableText.link "Source"
[ ClickableText.linkExternal link
, ClickableText.css [ Css.marginLeft (Css.px 20) ]
] ]

View File

@ -25,6 +25,7 @@ import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator
import Nri.Ui.Fonts.V1 as Fonts import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Svg.V1 as Svg import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Text.V6 as Text
import Nri.Ui.UiIcon.V1 as UiIcon import Nri.Ui.UiIcon.V1 as UiIcon
import Set exposing (Set) import Set exposing (Set)
import Task import Task
@ -38,6 +39,21 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ -- faking a mini version of the Accordion component to give styleguide users a sense of what the
-- component might look like
Html.div []
[ Html.div [ css [ Css.displayFlex, Css.alignItems Css.center ] ]
[ defaultCaret False
, Text.smallBody [ Text.plaintext "Closed" ]
]
, Html.div [ css [ Css.displayFlex, Css.alignItems Css.center ] ]
[ defaultCaret True
, Text.smallBody [ Text.plaintext "Open" ]
]
, Text.caption [ Text.plaintext "Accordion content." ]
]
]
, view = view , view = view
, categories = [ Layout ] , categories = [ Layout ]
, keyboardSupport = , keyboardSupport =
@ -57,13 +73,14 @@ example =
} }
defaultCaret : Bool -> Html msg
defaultCaret =
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
{-| -} {-| -}
view : State -> List (Html Msg) view : State -> List (Html Msg)
view model = view model =
let
defaultCaret =
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
in
[ Heading.h3 [] [ Html.text "Accordion.view" ] [ Heading.h3 [] [ Html.text "Accordion.view" ]
, Accordion.view , Accordion.view
{ entries = { entries =

View File

@ -33,6 +33,21 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
IconExamples.preview
[ AssignmentIcon.planningDiagnosticCircled
, AssignmentIcon.unitDiagnosticCircled
, AssignmentIcon.practiceCircled
, AssignmentIcon.quizCircled
, AssignmentIcon.quickWriteCircled
, AssignmentIcon.guidedDraftCircled
, AssignmentIcon.peerReviewCircled
, AssignmentIcon.selfReviewCircled
, AssignmentIcon.startPrimary
, AssignmentIcon.assessment
, AssignmentIcon.standards
, AssignmentIcon.writing
]
, view = , view =
\_ -> \_ ->
[ IconExamples.view "Diagnostic" [ IconExamples.view "Diagnostic"

View File

@ -29,6 +29,14 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Balloon.balloon
[ Balloon.onTop
, Balloon.navy
, Balloon.paddingPx 15
]
(text "This is a balloon.")
]
, view = view , view = view
} }

View File

@ -6,6 +6,7 @@ module Examples.Button exposing (Msg, State, example)
-} -}
import Accessibility.Styled.Key as Key
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css exposing (middle, verticalAlign) import Css exposing (middle, verticalAlign)
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
@ -28,6 +29,27 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Button.link "Primary"
[ Button.small
, Button.fillContainerWidth
, Button.custom [ Key.tabbable False ]
]
, Button.link "Secondary"
[ Button.small
, Button.fillContainerWidth
, Button.secondary
, Button.css [ Css.marginTop (Css.px 8) ]
, Button.custom [ Key.tabbable False ]
]
, Button.link "Premium"
[ Button.small
, Button.fillContainerWidth
, Button.premium
, Button.css [ Css.marginTop (Css.px 8) ]
, Button.custom [ Key.tabbable False ]
]
]
, view = \state -> [ viewButtonExamples state ] , view = \state -> [ viewButtonExamples state ]
, categories = [ Buttons ] , categories = [ Buttons ]
, keyboardSupport = [] , keyboardSupport = []

View File

@ -38,6 +38,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\state -> \state ->
[ viewInteractableCheckbox "styleguide-checkbox-interactable" state [ viewInteractableCheckbox "styleguide-checkbox-interactable" state

View File

@ -6,6 +6,7 @@ module Examples.ClickableSvg exposing (Msg, State, example)
-} -}
import Accessibility.Styled.Key as Key
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css import Css
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
@ -36,6 +37,23 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ ClickableSvg.link "ClickableSvg small"
UiIcon.link
[ ClickableSvg.small
, ClickableSvg.custom [ Key.tabbable False ]
]
, ClickableSvg.link "ClickableSvg medium"
UiIcon.link
[ ClickableSvg.medium
, ClickableSvg.custom [ Key.tabbable False ]
]
, ClickableSvg.link "ClickableSvg large"
UiIcon.link
[ ClickableSvg.large
, ClickableSvg.custom [ Key.tabbable False ]
]
]
, view = , view =
\state -> \state ->
let let

View File

@ -6,6 +6,7 @@ module Examples.ClickableText exposing (Msg, State, example)
-} -}
import Accessibility.Styled.Key as Key
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css exposing (middle, verticalAlign) import Css exposing (middle, verticalAlign)
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
@ -32,6 +33,23 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ ClickableText.link "Small"
[ ClickableText.icon UiIcon.link
, ClickableText.small
, ClickableText.custom [ Key.tabbable False ]
]
, ClickableText.link "Medium"
[ ClickableText.icon UiIcon.link
, ClickableText.medium
, ClickableText.custom [ Key.tabbable False ]
]
, ClickableText.link "Large"
[ ClickableText.icon UiIcon.link
, ClickableText.large
, ClickableText.custom [ Key.tabbable False ]
]
]
, view = \state -> [ viewExamples state ] , view = \state -> [ viewExamples state ]
, categories = [ Buttons ] , categories = [ Buttons ]
, keyboardSupport = [] , keyboardSupport = []

View File

@ -14,6 +14,7 @@ import Html.Styled.Attributes as Attributes exposing (css)
import KeyboardSupport exposing (Direction(..), Key(..)) import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Colors.Extra import Nri.Ui.Colors.Extra
import Nri.Ui.Colors.V1 as Colors import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading import Nri.Ui.Heading.V2 as Heading
import SolidColor exposing (highContrast) import SolidColor exposing (highContrast)
@ -41,6 +42,12 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ ( "green", Colors.green )
, ( "purple", Colors.purple )
, ( "mustard", Colors.mustard )
]
|> List.map viewPreviewSwatch
, view = , view =
\_ -> \_ ->
[ [ ( "gray20", Colors.gray20, "Main text" ) [ [ ( "gray20", Colors.gray20, "Main text" )
@ -117,6 +124,22 @@ example =
} }
viewPreviewSwatch : ( String, Css.Color ) -> Html.Html msg
viewPreviewSwatch ( name, color ) =
Html.div
[ Attributes.css
[ Css.textAlign Css.center
, Css.padding2 (Css.px 8) Css.zero
, Css.margin2 (Css.px 4) Css.zero
, Css.borderRadius (Css.px 4)
, Css.backgroundColor color
, Css.color color
, Css.fontSize (Css.px 14)
]
]
[ Html.text name ]
viewColors : List ColorExample -> Html.Html msg viewColors : List ColorExample -> Html.Html msg
viewColors colors = viewColors colors =
colors colors

View File

@ -33,6 +33,7 @@ example =
[ Browser.Events.onResize WindowResized [ Browser.Events.onResize WindowResized
, Confetti.subscriptions ConfettiMsg state , Confetti.subscriptions ConfettiMsg state
] ]
, preview = []
, view = , view =
\state -> \state ->
[ Button.button "Launch confetti!" [ Button.button "Launch confetti!"

View File

@ -35,6 +35,17 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Container.view []
, Container.view
[ Container.invalid
, Container.css [ Css.marginTop (Css.px 8) ]
]
, Container.view
[ Container.disabled
, Container.css [ Css.marginTop (Css.px 8) ]
]
]
, view = , view =
\state -> \state ->
let let

View File

@ -36,6 +36,12 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ DisclosureIndicator.medium [] False
, DisclosureIndicator.medium [] True
, DisclosureIndicator.large [] False
, DisclosureIndicator.large [] True
]
, view = , view =
\state -> \state ->
[ Text.smallBodyGray [ Text.plaintext "The disclosure indicator is only the caret. It is NOT a button -- you must create a button or clickabletext yourself!" ] [ Text.smallBodyGray [ Text.plaintext "The disclosure indicator is only the caret. It is NOT a button -- you must create a button or clickabletext yourself!" ]

View File

@ -35,5 +35,6 @@ example =
, state = {} , state = {}
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = [ Divider.view "Dividing Line" ]
, view = \state -> [ Divider.view "Dividing Line" ] , view = \state -> [ Divider.view "Dividing Line" ]
} }

View File

@ -7,8 +7,9 @@ module Examples.Fonts exposing (example, State, Msg)
-} -}
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css exposing (Style)
import Example exposing (Example) import Example exposing (Example)
import Html.Styled as Html import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css) import Html.Styled.Attributes exposing (css)
import KeyboardSupport exposing (Direction(..), Key(..)) import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Fonts.V1 as Fonts import Nri.Ui.Fonts.V1 as Fonts
@ -35,6 +36,12 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ ( "baseFont", Fonts.baseFont )
, ( "quizFont", Fonts.quizFont )
, ( "ugFont", Fonts.ugFont )
]
|> List.map viewPreview
, view = , view =
\_ -> \_ ->
[ Heading.h3 [] [ Html.text "baseFont" ] [ Heading.h3 [] [ Html.text "baseFont" ]
@ -48,3 +55,20 @@ example =
[ Html.text "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" ] [ Html.text "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" ]
] ]
} }
viewPreview : ( String, Style ) -> Html msg
viewPreview ( name, font ) =
Html.div
[ css
[ Css.displayFlex
, Css.justifyContent Css.spaceBetween
, font
, Css.fontSize (Css.px 14)
]
]
[ Html.p [ css [ Css.margin2 (Css.px 8) Css.zero ] ]
[ Html.text name ]
, Html.p [ css [ Css.margin2 (Css.px 8) Css.zero ] ]
[ Html.text "AaBbCc" ]
]

View File

@ -35,6 +35,12 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Heading.h1 [] [ Html.text "h1" ]
, Heading.h2 [] [ Html.text "h2" ]
, Heading.h3 [] [ Html.text "h3" ]
, Heading.h4 [] [ Html.text "h4" ]
]
, view = , view =
\_ -> \_ ->
[ Heading.h1 [] [ Html.text "This is the main page heading." ] [ Heading.h1 [] [ Html.text "This is the main page heading." ]

View File

@ -1,4 +1,4 @@
module Examples.IconExamples exposing (view, viewWithCustomStyles) module Examples.IconExamples exposing (preview, view, viewWithCustomStyles)
import Css import Css
import Html.Styled as Html exposing (Html) import Html.Styled as Html exposing (Html)
@ -9,6 +9,23 @@ import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Text.V6 as Text import Nri.Ui.Text.V6 as Text
preview : List Svg.Svg -> List (Html msg)
preview icons =
[ Html.div
[ css
[ Css.displayFlex
, Css.flexWrap Css.wrap
, Css.property "gap" "10px"
, Css.color Colors.gray45
]
]
(List.map
(Svg.withWidth (Css.px 30) >> Svg.withHeight (Css.px 30) >> Svg.toHtml)
icons
)
]
view : String -> List ( String, Svg.Svg ) -> Html msg view : String -> List ( String, Svg.Svg ) -> Html msg
view headerText icons = view headerText icons =
let let

View File

@ -94,6 +94,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = subscriptions , subscriptions = subscriptions
, preview = []
, view = , view =
\{ showLoadingFadeIn, showLoading, showSpinners } -> \{ showLoadingFadeIn, showLoading, showSpinners } ->
[ if showLoading then [ if showLoading then

View File

@ -10,9 +10,12 @@ import Category exposing (Category(..))
import Css import Css
import Example exposing (Example) import Example exposing (Example)
import Examples.IconExamples as IconExamples import Examples.IconExamples as IconExamples
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import KeyboardSupport exposing (Direction(..), Key(..)) import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Colors.V1 as Colors import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Logo.V1 as Logo import Nri.Ui.Logo.V1 as Logo
import Nri.Ui.Svg.V1 as Svg
{-| -} {-| -}
@ -35,6 +38,14 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
Html.div [ css [ Css.marginBottom (Css.px 8) ] ] [ Svg.toHtml Logo.noredink ]
:: IconExamples.preview
[ Logo.facebook
, Logo.twitter
, Logo.cleverC
, Logo.googleG
]
, view = , view =
\_ -> \_ ->
[ IconExamples.viewWithCustomStyles "NRI" [ IconExamples.viewWithCustomStyles "NRI"

View File

@ -34,6 +34,7 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\_ -> \_ ->
[ IconExamples.view "Levels" [ IconExamples.view "Levels"

View File

@ -47,6 +47,7 @@ example =
} }
, { keys = [ Esc ], result = "Closes the menu" } , { keys = [ Esc ], result = "Closes the menu" }
] ]
, preview = []
, view = view , view = view
} }

View File

@ -177,6 +177,11 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Message.view [ Message.plaintext "Tiny tip" ]
, Message.view [ Message.success, Message.plaintext "Tiny success" ]
, Message.view [ Message.error, Message.plaintext "Tiny error" ]
]
, view = , view =
\state -> \state ->
let let

View File

@ -7,22 +7,26 @@ module Examples.Modal exposing (Msg, State, example)
-} -}
import Accessibility.Styled as Html exposing (Html, div, h3, h4, p, span, text) import Accessibility.Styled as Html exposing (Html, div, h3, h4, p, span, text)
import Accessibility.Styled.Key as Key
import Browser.Dom as Dom import Browser.Dom as Dom
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css exposing (..) import Css exposing (..)
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
import Debug.Control.Extra as ControlExtra import Debug.Control.Extra as ControlExtra
import Example exposing (Example) import Example exposing (Example)
import Html as Root
import Html.Styled.Attributes as Attributes exposing (css) import Html.Styled.Attributes as Attributes exposing (css)
import KeyboardSupport exposing (Direction(..), Key(..)) import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Button.V10 as Button import Nri.Ui.Button.V10 as Button
import Nri.Ui.Checkbox.V5 as Checkbox import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.ClickableText.V3 as ClickableText import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.Extra
import Nri.Ui.Colors.V1 as Colors import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.FocusTrap.V1 as FocusTrap import Nri.Ui.FocusTrap.V1 as FocusTrap
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Modal.V11 as Modal import Nri.Ui.Modal.V11 as Modal
import Nri.Ui.Text.V6 as Text import Nri.Ui.Text.V6 as Text
import Nri.Ui.UiIcon.V1 as UiIcon
import Task import Task
@ -125,6 +129,51 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = subscriptions , subscriptions = subscriptions
, preview =
[ -- faking a mini version of the Modal component to give styleguide users a sense of what the
-- component might look like
div
[ css
[ Css.backgroundColor (Nri.Ui.Colors.Extra.withAlpha 0.9 Colors.navy)
, Css.borderRadius (Css.px 4)
, Css.padding2 (Css.px 25) Css.zero
, Css.displayFlex
, Css.alignItems Css.center
, Css.justifyContent Css.center
]
]
[ div
[ css
[ Css.backgroundColor Colors.white
, Css.padding (Css.px 10)
, Css.borderRadius (Css.px 10)
, Css.boxShadow5 Css.zero (Css.px 1) (Css.px 10) Css.zero (Css.rgba 0 0 0 0.35)
, Css.textAlign Css.center
, Css.color Colors.navy
, Fonts.baseFont
, Css.margin Css.auto
, Css.width (Css.px 100)
, Css.height (Css.px 60)
, Css.fontSize (Css.px 10)
, Css.fontWeight Css.bold
, Css.position Css.relative
]
]
[ text "Modal"
, ClickableSvg.link "Close"
UiIcon.x
[ ClickableSvg.exactWidth 10
, ClickableSvg.exactHeight 10
, ClickableSvg.css
[ Css.position absolute
, Css.top (Css.px 10)
, Css.right (Css.px 10)
]
, ClickableSvg.custom [ Key.tabbable False ]
]
]
]
]
, view = , view =
\state -> \state ->
let let

View File

@ -17,6 +17,7 @@ import Html.Styled.Attributes exposing (css)
import Http import Http
import KeyboardSupport exposing (Direction(..), Key(..)) import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Colors.V1 as Colors import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Page.V3 as Page exposing (RecoveryText(..)) import Nri.Ui.Page.V3 as Page exposing (RecoveryText(..))
@ -62,6 +63,32 @@ example =
, state = { httpError = CommonControls.httpError, recoveryText = initRecoveryText } , state = { httpError = CommonControls.httpError, recoveryText = initRecoveryText }
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ -- faking a mini version of the Page component to give styleguide users a sense of what the
-- component might look like
Html.div
[ css
[ Css.displayFlex
, Css.alignItems Css.center
, Css.flexDirection Css.column
, Css.backgroundColor Colors.white
, Css.borderRadius (Css.px 4)
, Css.padding (Css.px 20)
]
]
[ Html.div [ css [ Css.fontSize (Css.px 40) ] ] [ Html.text "😵" ]
, Html.p
[ css
[ Css.color Colors.navy
, Fonts.baseFont
, Css.fontWeight Css.bold
, Css.textAlign Css.center
, Css.margin Css.zero
]
]
[ Html.text "There was a problem!" ]
]
]
, view = , view =
\model -> \model ->
let let

View File

@ -38,6 +38,12 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
IconExamples.preview
[ Pennant.premiumFlag
, Pennant.expiredPremiumFlag
, Pennant.disabledPremiumFlag
]
, view = , view =
\_ -> \_ ->
[ IconExamples.viewWithCustomStyles "Premium Pennants" [ IconExamples.viewWithCustomStyles "Premium Pennants"

View File

@ -34,6 +34,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = subscriptions , subscriptions = subscriptions
, preview = []
, view = view , view = view
, categories = [ Inputs ] , categories = [ Inputs ]
, keyboardSupport = , keyboardSupport =

View File

@ -36,6 +36,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\state -> \state ->
let let

View File

@ -26,6 +26,7 @@ example =
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, categories = [ Inputs ] , categories = [ Inputs ]
, keyboardSupport = [] , keyboardSupport = []
, preview = []
, view = , view =
\state -> \state ->
[ Html.Styled.label [ Html.Styled.label

View File

@ -42,6 +42,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\state -> \state ->
[ Keyed.node "div" [ Keyed.node "div"

View File

@ -40,6 +40,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\state -> \state ->
[ viewModal state.modal [ viewModal state.modal

View File

@ -41,6 +41,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\{ sortState } -> \{ sortState } ->
let let

View File

@ -33,6 +33,7 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = []
, view = , view =
\state -> \state ->
[ viewSettings state [ viewSettings state

View File

@ -6,12 +6,12 @@ module Examples.Switch exposing (Msg, State, example)
-} -}
import Accessibility.Styled.Key as Key
import Category import Category
import Example exposing (Example) import Example exposing (Example)
import Html.Styled as Html import Html.Styled as Html
import Nri.Ui.Heading.V2 as Heading import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Switch.V1 as Switch import Nri.Ui.Switch.V1 as Switch
import Nri.Ui.Text.V6 as Text
{-| -} {-| -}
@ -31,46 +31,47 @@ example =
, state = True , state = True
, update = \(Switch new) _ -> ( new, Cmd.none ) , update = \(Switch new) _ -> ( new, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Switch.view
[ Switch.label (Html.text "Toggle On")
, Switch.custom [ Key.tabbable False ]
]
False
, Switch.view
[ Switch.label (Html.text "Toggle Off")
, Switch.custom [ Key.tabbable False ]
]
True
]
, view = , view =
\interactiveIsOn -> \interactiveIsOn ->
[ Heading.h3 [] [ Html.text "Interactive" ] [ Heading.h3 [] [ Html.text "Interactive" ]
, Text.mediumBody , Switch.view
[ Text.html [ Switch.onSwitch Switch
[ Switch.view , Switch.id "switch-interactive"
[ Switch.onSwitch Switch , Switch.label
, Switch.id "switch-interactive" (if interactiveIsOn then
, Switch.label Html.text "On"
(if interactiveIsOn then
Html.text "On"
else else
Html.text "Off" Html.text "Off"
) )
]
interactiveIsOn
]
] ]
, Heading.h3 [] [ Html.text "Disabled" ] interactiveIsOn
, Text.mediumBody , Heading.h3 [] [ Html.text "Disabled (On)" ]
[ Text.html , Switch.view
[ Switch.view [ Switch.disabled
[ Switch.disabled , Switch.id "switch-disabled-on"
, Switch.id "switch-disabled-on" , Switch.label (Html.text "Permanently on")
, Switch.label (Html.text "Permanently on")
]
True
]
] ]
, Text.mediumBody True
[ Text.html , Heading.h3 [] [ Html.text "Disabled (Off)" ]
[ Switch.view , Switch.view
[ Switch.disabled [ Switch.disabled
, Switch.id "switch-disabled-off" , Switch.id "switch-disabled-off"
, Switch.label (Html.text "Permanently off") , Switch.label (Html.text "Permanently off")
]
False
]
] ]
False
] ]
, categories = [ Category.Inputs ] , categories = [ Category.Inputs ]
, keyboardSupport = [{- TODO -}] , keyboardSupport = [{- TODO -}]

View File

@ -37,6 +37,29 @@ example =
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, categories = [ Tables, Layout ] , categories = [ Tables, Layout ]
, keyboardSupport = [] , keyboardSupport = []
, preview =
[ Table.view
[ Table.string
{ header = "A"
, value = .a
, width = px 50
, cellStyles = always []
}
, Table.string
{ header = "B"
, value = .b
, width = px 50
, cellStyles = always []
}
]
[ { a = "Row 1 A"
, b = "Row 1 B"
}
, { a = "Row 2 A"
, b = "Row 2 B"
}
]
]
, view = , view =
\() -> \() ->
let let

View File

@ -19,10 +19,13 @@ import Html.Styled as Html exposing (Html, fromUnstyled)
import Html.Styled.Attributes exposing (css) import Html.Styled.Attributes exposing (css)
import KeyboardSupport exposing (Key(..)) import KeyboardSupport exposing (Key(..))
import List.Zipper exposing (Zipper) import List.Zipper exposing (Zipper)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1 as Svg import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Tabs.V7 as Tabs exposing (Alignment(..), Tab) import Nri.Ui.Tabs.V7 as Tabs exposing (Alignment(..), Tab)
import Nri.Ui.Text.V6 as Text
import Nri.Ui.Tooltip.V2 as Tooltip import Nri.Ui.Tooltip.V2 as Tooltip
import Nri.Ui.UiIcon.V1 as UiIcon import Nri.Ui.UiIcon.V1 as UiIcon
import Routes
import Task import Task
@ -117,9 +120,14 @@ update msg model =
) )
exampleName : String
exampleName =
"Tabs"
example : Example State Msg example : Example State Msg
example = example =
{ name = "Tabs" { name = exampleName
, version = 7 , version = 7
, categories = [ Layout ] , categories = [ Layout ]
, keyboardSupport = , keyboardSupport =
@ -136,6 +144,49 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ -- faking a mini version of the Tabs component to give styleguide users a sense of what the
-- component might look like
Html.div [ css [ Css.displayFlex, Css.flexWrap Css.wrap ] ]
[ Html.div
[ css
[ Css.backgroundColor Colors.white
, Css.padding (Css.px 4)
, Css.borderRadius4 (Css.px 4) (Css.px 4) Css.zero Css.zero
, Css.border3 (Css.px 1) Css.solid Colors.navy
, Css.borderBottomWidth Css.zero
]
]
[ Text.smallBody [ Text.plaintext "Tab 1" ] ]
, Html.div
[ css [ Css.width (Css.px 4), Css.borderBottom3 (Css.px 1) Css.solid Colors.navy ]
]
[]
, Html.div
[ css
[ Css.backgroundColor Colors.frost
, Css.padding (Css.px 4)
, Css.borderRadius4 (Css.px 4) (Css.px 4) Css.zero Css.zero
, Css.border3 (Css.px 1) Css.solid Colors.navy
]
]
[ Text.smallBody [ Text.plaintext "Tab 1" ] ]
, Html.div
[ css
[ Css.width (Css.px 30)
, Css.borderBottom3 (Css.px 1) Css.solid Colors.navy
]
]
[]
, Html.div
[ css
[ Css.paddingTop (Css.px 4)
, Css.minWidth (Css.px 100)
]
]
[ Text.caption [ Text.plaintext "Tab 1 content" ] ]
]
]
, view = , view =
\model -> \model ->
let let
@ -167,7 +218,7 @@ allTabs openTooltipId labelledBy =
|> Svg.toHtml |> Svg.toHtml
in in
[ Tabs.build { id = First, idString = "tab-0" } [ Tabs.build { id = First, idString = "tab-0" }
([ Tabs.spaHref "/#/doodad/Tabs" ([ Tabs.spaHref <| Routes.toString (Routes.Doodad exampleName)
, Tabs.tabString "1" , Tabs.tabString "1"
, Tabs.withTooltip , Tabs.withTooltip
[ Tooltip.plaintext "Link Example" [ Tooltip.plaintext "Link Example"

View File

@ -30,6 +30,13 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ ( "caption", Text.caption )
, ( "smallBody", Text.smallBody )
, ( "mediumBody", Text.mediumBody )
, ( "ugMediumBody", Text.ugMediumBody )
]
|> List.map viewPreview
, view = , view =
\state -> \state ->
let let
@ -57,6 +64,11 @@ example =
} }
viewPreview : ( String, List (Text.Attribute msg) -> Html msg ) -> Html msg
viewPreview ( name, view ) =
view [ Text.plaintext name ]
viewExamples : List ( String, List (Text.Attribute msg) -> Html msg ) -> List (Text.Attribute msg) -> Html msg viewExamples : List ( String, List (Text.Attribute msg) -> Html msg ) -> List (Text.Attribute msg) -> Html msg
viewExamples examples attributes = viewExamples examples attributes =
let let

View File

@ -32,6 +32,7 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview = [ TextWriting.footnote [ text "This is a footnote. " ] ]
, view = , view =
\_ -> \_ ->
let let

View File

@ -44,6 +44,7 @@ example =
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, categories = [ Inputs ] , categories = [ Inputs ]
, keyboardSupport = [] , keyboardSupport = []
, preview = []
, view = , view =
\state -> \state ->
[ Heading.h1 [] [ Html.text "Textarea controls" ] [ Heading.h1 [] [ Html.text "Textarea controls" ]

View File

@ -7,6 +7,7 @@ module Examples.TextInput exposing (Msg, State, example)
-} -}
import Accessibility.Styled as Html exposing (..) import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled.Key as Key
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css exposing (..) import Css exposing (..)
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
@ -32,6 +33,16 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ TextInput.view "Text Input"
[ TextInput.custom [ Key.tabbable False ]
]
, TextInput.view "Errored"
[ TextInput.value "invalid content"
, TextInput.errorIf True
, TextInput.custom [ Key.tabbable False ]
]
]
, view = , view =
\state -> \state ->
let let

View File

@ -7,6 +7,7 @@ module Examples.Tooltip exposing (example, State, Msg)
-} -}
import Accessibility.Styled as Html exposing (Html) import Accessibility.Styled as Html exposing (Html)
import Accessibility.Styled.Key as Key
import Category exposing (Category(..)) import Category exposing (Category(..))
import Css import Css
import Debug.Control as Control exposing (Control) import Debug.Control as Control exposing (Control)
@ -33,6 +34,32 @@ example =
, state = init , state = init
, update = update , update = update
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
[ Html.div
[ css
[ Css.marginTop (Css.px 60)
, Css.alignSelf Css.center
]
]
[ Tooltip.view
{ id = "preview-tooltip"
, trigger =
\attributes ->
ClickableSvg.button "example-preview-tooltip-icon"
UiIcon.gear
[ ClickableSvg.custom attributes
, ClickableSvg.small
, ClickableSvg.custom [ Key.tabbable False ]
]
}
[ Tooltip.plaintext "This is a tooltip."
, Tooltip.open True
, Tooltip.onTop
, Tooltip.smallPadding
, Tooltip.fitToContent
]
]
]
, view = view , view = view
} }

View File

@ -33,6 +33,21 @@ example =
, state = () , state = ()
, update = \_ state -> ( state, Cmd.none ) , update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none , subscriptions = \_ -> Sub.none
, preview =
IconExamples.preview
[ UiIcon.seeMore
, UiIcon.archive
, UiIcon.share
, UiIcon.footsteps
, UiIcon.person
, UiIcon.calendar
, UiIcon.missingDocument
, UiIcon.speechBalloon
, UiIcon.edit
, UiIcon.arrowTop
, UiIcon.checkmark
, UiIcon.equals
]
, view = , view =
\_ -> \_ ->
[ IconExamples.view "Interface" [ IconExamples.view "Interface"

View File

@ -1,6 +1,6 @@
module Main exposing (init, main) module Main exposing (init, main)
import Accessibility.Styled as Html exposing (Html, img, text) import Accessibility.Styled as Html exposing (Html)
import Browser exposing (Document, UrlRequest(..)) import Browser exposing (Document, UrlRequest(..))
import Browser.Dom import Browser.Dom
import Browser.Navigation exposing (Key) import Browser.Navigation exposing (Key)
@ -10,15 +10,16 @@ import Css.Media exposing (withMedia)
import Dict exposing (Dict) import Dict exposing (Dict)
import Example exposing (Example) import Example exposing (Example)
import Examples import Examples
import Html as RootHtml
import Html.Attributes import Html.Attributes
import Html.Styled.Attributes as Attributes exposing (..) import Html.Styled.Attributes as Attributes exposing (..)
import Html.Styled.Events as Events import Html.Styled.Events as Events
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.CssVendorPrefix.V1 as VendorPrefixed import Nri.Ui.CssVendorPrefix.V1 as VendorPrefixed
import Nri.Ui.Fonts.V1 as Fonts import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.MediaQuery.V1 exposing (mobile, notMobile) import Nri.Ui.MediaQuery.V1 exposing (mobile, notMobile)
import Nri.Ui.Page.V3 as Page
import Routes as Routes exposing (Route(..)) import Routes as Routes exposing (Route(..))
import Sort.Set as Set exposing (Set) import Sort.Set as Set exposing (Set)
import Task import Task
@ -40,6 +41,7 @@ main =
type alias Model = type alias Model =
{ -- Global UI { -- Global UI
route : Route route : Route
, previousRoute : Maybe Route
, moduleStates : Dict String (Example Examples.State Examples.Msg) , moduleStates : Dict String (Example Examples.State Examples.Msg)
, navigationKey : Key , navigationKey : Key
} }
@ -48,6 +50,7 @@ type alias Model =
init : () -> Url -> Key -> ( Model, Cmd Msg ) init : () -> Url -> Key -> ( Model, Cmd Msg )
init () url key = init () url key =
( { route = Routes.fromLocation url ( { route = Routes.fromLocation url
, previousRoute = Nothing
, moduleStates = , moduleStates =
Dict.fromList Dict.fromList
(List.map (\example -> ( example.name, example )) Examples.all) (List.map (\example -> ( example.name, example )) Examples.all)
@ -61,6 +64,7 @@ type Msg
= UpdateModuleStates String Examples.Msg = UpdateModuleStates String Examples.Msg
| OnUrlRequest Browser.UrlRequest | OnUrlRequest Browser.UrlRequest
| OnUrlChange Url | OnUrlChange Url
| ChangeRoute Route
| SkipToMainContent | SkipToMainContent
| NoOp | NoOp
@ -95,7 +99,18 @@ update action model =
( model, Browser.Navigation.load loc ) ( model, Browser.Navigation.load loc )
OnUrlChange route -> OnUrlChange route ->
( { model | route = Routes.fromLocation route }, Cmd.none ) ( { model
| route = Routes.fromLocation route
, previousRoute = Just model.route
}
, Cmd.none
)
ChangeRoute route ->
( model
, Browser.Navigation.pushUrl model.navigationKey
(Routes.toString route)
)
SkipToMainContent -> SkipToMainContent ->
( model ( model
@ -125,69 +140,86 @@ view_ model =
let let
examples filterBy = examples filterBy =
List.filter (\m -> filterBy m) (Dict.values model.moduleStates) List.filter (\m -> filterBy m) (Dict.values model.moduleStates)
mainContentHeader heading =
Heading.h1
[ Heading.customAttr (id "maincontent")
, Heading.customAttr (tabindex -1)
, Heading.css [ marginBottom (px 30) ]
]
[ Html.text heading ]
in in
case model.route of
Routes.Doodad doodad ->
case List.head (examples (\m -> m.name == doodad)) of
Just example ->
Html.main_ []
[ Example.view model.previousRoute example
|> Html.map (UpdateModuleStates example.name)
]
Nothing ->
Page.notFound
{ link = ChangeRoute Routes.All
, recoveryText = Page.ReturnTo "Component Library"
}
Routes.Category category ->
withSideNav model.route
[ mainContentHeader (Category.forDisplay category)
, examples
(\doodad ->
Set.memberOf
(Set.fromList Category.sorter doodad.categories)
category
)
|> viewPreviews (Category.forId category)
]
Routes.All ->
withSideNav model.route
[ mainContentHeader "All"
, viewPreviews "all" (examples (\_ -> True))
]
withSideNav : Route -> List (Html Msg) -> Html Msg
withSideNav currentRoute content =
Html.div Html.div
[ css [ css
[ displayFlex [ displayFlex
, withMedia [ mobile ] [ flexDirection column, alignItems stretch ] , withMedia [ mobile ] [ flexDirection column, alignItems stretch ]
, alignItems flexStart , alignItems flexStart
, minHeight (vh 100)
] ]
] ]
[ navigation model.route [ navigation currentRoute
, Html.main_ [ css [ flexGrow (int 1), sectionStyles ] ] , Html.main_
(case model.route of [ css
Routes.Doodad doodad -> [ flexGrow (int 1)
case List.head (examples (\m -> m.name == doodad)) of , margin2 (px 40) zero
Just example -> , Css.minHeight (Css.vh 100)
[ mainContentHeader ("Viewing " ++ doodad ++ " doodad only") ]
, Html.div [ id (String.replace "." "-" example.name) ] ]
[ Example.view example content
|> Html.map (UpdateModuleStates example.name)
]
]
Nothing ->
[ Html.text <| "Oops! We couldn't find " ++ doodad ]
Routes.Category category ->
[ mainContentHeader (Category.forDisplay category)
, examples
(\doodad ->
Set.memberOf
(Set.fromList Category.sorter doodad.categories)
category
)
|> List.map
(\example ->
Example.view example
|> Html.map (UpdateModuleStates example.name)
)
|> Html.div [ id (Category.forId category) ]
]
Routes.All ->
[ mainContentHeader "All"
, examples (\_ -> True)
|> List.map
(\example ->
Example.view example
|> Html.map (UpdateModuleStates example.name)
)
|> Html.div []
]
)
] ]
mainContentHeader : String -> Html msg
mainContentHeader heading =
Heading.h1
[ Heading.customAttr (id "maincontent")
, Heading.customAttr (tabindex -1)
, Heading.css [ marginBottom (px 30) ]
]
[ Html.text heading ]
viewPreviews : String -> List (Example state msg) -> Html Msg
viewPreviews containerId examples =
examples
|> List.map (\example -> Example.preview ChangeRoute example)
|> Html.div
[ id containerId
, css
[ Css.displayFlex
, Css.flexWrap Css.wrap
, Css.property "gap" "10px"
]
]
navigation : Route -> Html Msg navigation : Route -> Html Msg
navigation route = navigation route =
let let
@ -200,31 +232,31 @@ navigation route =
False False
link active hash displayName = link active hash displayName =
Html.a ClickableText.link displayName
[ css [ ClickableText.small
[ backgroundColor transparent , ClickableText.css
, borderStyle none [ Css.color Colors.navy
, textDecoration none , Css.display Css.block
, Css.padding (Css.px 8)
, Css.borderRadius (Css.px 8)
, if active then , if active then
color Colors.navy Css.backgroundColor Colors.glacier
else else
color Colors.azure Css.batch []
, Fonts.baseFont
] ]
, Attributes.href hash , ClickableText.href hash
] ]
[ Html.text displayName ]
navLink category = navLink category =
link (isActive category) link (isActive category)
("#/category/" ++ Debug.toString category) (Routes.toString (Routes.Category category))
(Category.forDisplay category) (Category.forDisplay category)
toNavLi element = toNavLi element =
Html.li Html.li
[ css [ css
[ margin2 (px 10) zero [ margin zero
, listStyle none , listStyle none
, textDecoration none , textDecoration none
] ]
@ -269,18 +301,12 @@ navigation route =
, id "skip" , id "skip"
] ]
[ Html.text "Skip to main content" ] [ Html.text "Skip to main content" ]
, Heading.h4 [] [ Html.text "Categories" ]
, (link (route == Routes.All) "#/" "All" , (link (route == Routes.All) "#/" "All"
:: List.map navLink Category.all :: List.map navLink Category.all
) )
|> List.map toNavLi |> List.map toNavLi
|> Html.ul |> Html.ul
[ css [ margin4 zero zero (px 40) zero, padding zero ] [ css [ margin zero, padding zero ]
, id "categories" , id "categories"
] ]
] ]
sectionStyles : Css.Style
sectionStyles =
Css.batch [ margin2 (px 40) zero ]

View File

@ -1,4 +1,4 @@
module Routes exposing (Route(..), fromLocation) module Routes exposing (Route(..), fromLocation, toString)
import Browser.Navigation as Navigation import Browser.Navigation as Navigation
import Category import Category
@ -12,6 +12,19 @@ type Route
| All | All
toString : Route -> String
toString route_ =
case route_ of
Doodad exampleName ->
"#/doodad/" ++ exampleName
Category c ->
"#/category/" ++ Debug.toString c
All ->
"#/"
route : Parser Route route : Parser Route
route = route =
Parser.oneOf Parser.oneOf