mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-12-24 14:13:20 +03:00
Merge remote-tracking branch 'origin/master' into tessa/select-with-label
This commit is contained in:
commit
4978d449b5
2
elm.json
2
elm.json
@ -3,7 +3,7 @@
|
||||
"name": "NoRedInk/noredink-ui",
|
||||
"summary": "UI Widgets we use at NRI",
|
||||
"license": "BSD-3-Clause",
|
||||
"version": "14.8.0",
|
||||
"version": "14.8.1",
|
||||
"exposed-modules": [
|
||||
"Nri.Ui",
|
||||
"Nri.Ui.Accordion.V1",
|
||||
|
@ -33,11 +33,7 @@ hint = 'Use Accessibility.Widgetd.Widget'
|
||||
|
||||
[forbidden.Html]
|
||||
hint = 'Use Html.Styled'
|
||||
usages = [
|
||||
'styleguide-app/../src/Nri/Ui/Button/V8.elm',
|
||||
'styleguide-app/Examples/Modal.elm',
|
||||
'styleguide-app/Main.elm',
|
||||
]
|
||||
usages = ['styleguide-app/../src/Nri/Ui/Button/V8.elm']
|
||||
|
||||
[forbidden."Nri.Ui.Accordion.V1"]
|
||||
hint = 'upgrade to V3'
|
||||
|
@ -1,7 +1,8 @@
|
||||
let
|
||||
sources = import ./nix/sources.nix;
|
||||
nixpkgs = import sources.nixpkgs { };
|
||||
niv = import sources.niv { };
|
||||
system = if builtins.currentSystem == "aarch64-darwin" then "x86_64-darwin" else builtins.currentSystem;
|
||||
nixpkgs = import sources.nixpkgs { inherit system; };
|
||||
niv = nixpkgs.callPackage sources.niv { };
|
||||
in with nixpkgs;
|
||||
stdenv.mkDerivation {
|
||||
name = "noredink-ui";
|
||||
|
@ -23,7 +23,7 @@ import Nri.Ui.Html.V3 exposing (viewIf)
|
||||
|
||||
{-| The default page information is for the button
|
||||
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.
|
||||
-}
|
||||
type alias DefaultPage msg =
|
||||
|
@ -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
|
||||
| Label (Html msg)
|
||||
| Disabled
|
||||
| Custom (List (Html.Attribute Never))
|
||||
|
||||
|
||||
{-| Specify what happens when the switch is toggled.
|
||||
@ -63,10 +64,18 @@ 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 =
|
||||
{ onSwitch : Maybe (Bool -> msg)
|
||||
, id : String
|
||||
, label : Maybe (Html msg)
|
||||
, attributes : List (Html.Attribute Never)
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +84,7 @@ defaultConfig =
|
||||
{ onSwitch = Nothing
|
||||
, id = "nri-ui-switch-with-default-id"
|
||||
, label = Nothing
|
||||
, attributes = []
|
||||
}
|
||||
|
||||
|
||||
@ -93,6 +103,9 @@ customize attr config =
|
||||
Label label_ ->
|
||||
{ config | label = Just label_ }
|
||||
|
||||
Custom custom_ ->
|
||||
{ config | attributes = custom_ }
|
||||
|
||||
|
||||
{-| Render a switch. The boolean here indicates whether the switch is on
|
||||
or not.
|
||||
@ -133,6 +146,7 @@ view attrs isOn =
|
||||
{ id = config.id
|
||||
, onCheck = config.onSwitch
|
||||
, checked = isOn
|
||||
, attributes = config.attributes
|
||||
}
|
||||
, Nri.Ui.Svg.V1.toHtml
|
||||
(viewSwitch
|
||||
@ -162,26 +176,29 @@ viewCheckbox :
|
||||
{ id : String
|
||||
, onCheck : Maybe (Bool -> msg)
|
||||
, checked : Bool
|
||||
, attributes : List (Html.Attribute Never)
|
||||
}
|
||||
-> Html msg
|
||||
viewCheckbox config =
|
||||
Html.checkbox config.id
|
||||
(Just config.checked)
|
||||
[ Attributes.id config.id
|
||||
, Attributes.css
|
||||
([ Attributes.id config.id
|
||||
, Attributes.css
|
||||
[ Css.position Css.absolute
|
||||
, Css.top (Css.px 10)
|
||||
, Css.left (Css.px 10)
|
||||
, Css.zIndex (Css.int 0)
|
||||
, Css.opacity (Css.num 0)
|
||||
]
|
||||
, case config.onCheck of
|
||||
, case config.onCheck of
|
||||
Just onCheck ->
|
||||
Events.onCheck onCheck
|
||||
|
||||
Nothing ->
|
||||
Widget.disabled True
|
||||
]
|
||||
]
|
||||
++ List.map (Attributes.map never) config.attributes
|
||||
)
|
||||
|
||||
|
||||
viewSwitch :
|
||||
|
@ -770,6 +770,7 @@ resetButton config =
|
||||
else
|
||||
Css.top (Css.px 25)
|
||||
]
|
||||
, ClickableSvg.custom [ Attributes.type_ "button" ]
|
||||
]
|
||||
|
||||
|
||||
@ -796,4 +797,5 @@ viewPasswordFloatingContent label toggle config =
|
||||
Css.top (Css.px 22)
|
||||
, Css.fontSize (Css.px 13)
|
||||
]
|
||||
, ClickableText.custom [ Attributes.type_ "button" ]
|
||||
]
|
||||
|
@ -1,15 +1,22 @@
|
||||
module Example exposing (Example, view, wrapMsg, wrapState)
|
||||
module Example exposing (Example, preview, view, wrapMsg, wrapState)
|
||||
|
||||
import Category exposing (Category)
|
||||
import Css exposing (..)
|
||||
import Css.Global exposing (a, descendants)
|
||||
import Html.Styled as Html exposing (Html)
|
||||
import Html.Styled.Attributes as Attributes
|
||||
import Html.Styled.Events as Events
|
||||
import Html.Styled.Lazy as Lazy
|
||||
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.Heading.V2 as Heading
|
||||
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 =
|
||||
@ -18,12 +25,18 @@ type alias Example state msg =
|
||||
, state : state
|
||||
, update : msg -> state -> ( state, Cmd msg )
|
||||
, subscriptions : state -> Sub msg
|
||||
, preview : List (Html Never)
|
||||
, view : state -> List (Html msg)
|
||||
, categories : List Category
|
||||
, keyboardSupport : List KeyboardSupport
|
||||
}
|
||||
|
||||
|
||||
fullName : Example state msg -> String
|
||||
fullName example =
|
||||
"Nri.Ui." ++ example.name ++ ".V" ++ String.fromInt example.version
|
||||
|
||||
|
||||
wrapMsg :
|
||||
(msg -> msg2)
|
||||
-> (msg2 -> Maybe msg)
|
||||
@ -43,6 +56,7 @@ wrapMsg wrapMsg_ unwrapMsg example =
|
||||
Nothing ->
|
||||
( state, Cmd.none )
|
||||
, subscriptions = \state -> Sub.map wrapMsg_ (example.subscriptions state)
|
||||
, preview = example.preview
|
||||
, view = \state -> List.map (Html.map wrapMsg_) (example.view state)
|
||||
, categories = example.categories
|
||||
, keyboardSupport = example.keyboardSupport
|
||||
@ -71,6 +85,7 @@ wrapState wrapState_ unwrapState example =
|
||||
unwrapState
|
||||
>> Maybe.map example.subscriptions
|
||||
>> Maybe.withDefault Sub.none
|
||||
, preview = example.preview
|
||||
, view =
|
||||
unwrapState
|
||||
>> Maybe.map example.view
|
||||
@ -80,22 +95,77 @@ wrapState wrapState_ unwrapState example =
|
||||
}
|
||||
|
||||
|
||||
view : Example state msg -> Html msg
|
||||
view =
|
||||
Lazy.lazy view_
|
||||
preview : (Route -> msg2) -> Example state msg -> Html msg2
|
||||
preview navigate =
|
||||
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 =
|
||||
let
|
||||
fullName =
|
||||
"Nri.Ui." ++ example.name ++ ".V" ++ String.fromInt example.version
|
||||
in
|
||||
Html.div
|
||||
[ -- this class makes the axe accessibility checking output easier to parse
|
||||
String.replace "." "-" example.name
|
||||
|> (++) "module-example__"
|
||||
|> Attributes.class
|
||||
, Attributes.id (String.replace "." "-" example.name)
|
||||
]
|
||||
[ Html.div
|
||||
[ Attributes.css
|
||||
@ -107,52 +177,57 @@ view_ example =
|
||||
, descendants [ Css.Global.a [ textDecoration none ] ]
|
||||
]
|
||||
]
|
||||
[ Html.styled Html.h2
|
||||
[ color navy
|
||||
, fontSize (px 20)
|
||||
, 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"
|
||||
[ exampleLink example
|
||||
, docsLink example
|
||||
, srcLink example
|
||||
]
|
||||
, KeyboardSupport.view example.keyboardSupport
|
||||
, Html.div
|
||||
[ Attributes.css
|
||||
[ padding (px 40)
|
||||
, boxShadow5 zero (px 2) (px 4) zero (rgba 0 0 0 0.25)
|
||||
, border3 (px 1) solid gray92
|
||||
, borderRadius (px 20)
|
||||
, margin3 (px 10) zero (px 40)
|
||||
, Html.div [] (example.view example.state)
|
||||
]
|
||||
|
||||
|
||||
exampleHref : Example state msg -> String
|
||||
exampleHref example =
|
||||
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
|
||||
viewLink text href =
|
||||
Html.a
|
||||
([ Attributes.href href
|
||||
, Attributes.css [ Css.display Css.block, marginLeft (px 20) ]
|
||||
]
|
||||
++ targetBlank
|
||||
)
|
||||
[ Html.text text
|
||||
docsLink : Example state msg -> Html msg
|
||||
docsLink example =
|
||||
let
|
||||
link =
|
||||
"https://package.elm-lang.org/packages/NoRedInk/noredink-ui/latest/"
|
||||
++ String.replace "." "-" (fullName example)
|
||||
in
|
||||
ClickableText.link "Docs"
|
||||
[ 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) ]
|
||||
]
|
||||
|
@ -25,6 +25,7 @@ import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V2 as Heading
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Set exposing (Set)
|
||||
import Task
|
||||
@ -38,6 +39,21 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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
|
||||
, categories = [ Layout ]
|
||||
, keyboardSupport =
|
||||
@ -57,13 +73,14 @@ example =
|
||||
}
|
||||
|
||||
|
||||
defaultCaret : Bool -> Html msg
|
||||
defaultCaret =
|
||||
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
|
||||
|
||||
|
||||
{-| -}
|
||||
view : State -> List (Html Msg)
|
||||
view model =
|
||||
let
|
||||
defaultCaret =
|
||||
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
|
||||
in
|
||||
[ Heading.h3 [] [ Html.text "Accordion.view" ]
|
||||
, Accordion.view
|
||||
{ entries =
|
||||
|
@ -33,6 +33,21 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.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 =
|
||||
\_ ->
|
||||
[ IconExamples.view "Diagnostic"
|
||||
|
@ -29,6 +29,14 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
[ Balloon.balloon
|
||||
[ Balloon.onTop
|
||||
, Balloon.navy
|
||||
, Balloon.paddingPx 15
|
||||
]
|
||||
(text "This is a balloon.")
|
||||
]
|
||||
, view = view
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ module Examples.Button exposing (Msg, State, example)
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Category exposing (Category(..))
|
||||
import Css exposing (middle, verticalAlign)
|
||||
import Debug.Control as Control exposing (Control)
|
||||
@ -28,6 +29,27 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 ]
|
||||
, categories = [ Buttons ]
|
||||
, keyboardSupport = []
|
||||
|
@ -38,6 +38,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
[ viewInteractableCheckbox "styleguide-checkbox-interactable" state
|
||||
|
@ -6,6 +6,7 @@ module Examples.ClickableSvg exposing (Msg, State, example)
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Category exposing (Category(..))
|
||||
import Css
|
||||
import Debug.Control as Control exposing (Control)
|
||||
@ -35,6 +36,23 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 =
|
||||
\state ->
|
||||
let
|
||||
|
@ -6,6 +6,7 @@ module Examples.ClickableText exposing (Msg, State, example)
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Category exposing (Category(..))
|
||||
import Css exposing (middle, verticalAlign)
|
||||
import Debug.Control as Control exposing (Control)
|
||||
@ -32,6 +33,23 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 ]
|
||||
, categories = [ Buttons ]
|
||||
, keyboardSupport = []
|
||||
|
@ -14,6 +14,7 @@ import Html.Styled.Attributes as Attributes exposing (css)
|
||||
import KeyboardSupport exposing (Direction(..), Key(..))
|
||||
import Nri.Ui.Colors.Extra
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V2 as Heading
|
||||
import SolidColor exposing (highContrast)
|
||||
|
||||
@ -41,6 +42,12 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.none )
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
[ ( "green", Colors.green )
|
||||
, ( "purple", Colors.purple )
|
||||
, ( "mustard", Colors.mustard )
|
||||
]
|
||||
|> List.map viewPreviewSwatch
|
||||
, view =
|
||||
\_ ->
|
||||
[ [ ( "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 colors =
|
||||
colors
|
||||
|
@ -33,6 +33,7 @@ example =
|
||||
[ Browser.Events.onResize WindowResized
|
||||
, Confetti.subscriptions ConfettiMsg state
|
||||
]
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
[ Button.button "Launch confetti!"
|
||||
|
@ -35,6 +35,17 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 =
|
||||
\state ->
|
||||
let
|
||||
|
@ -36,6 +36,12 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
[ DisclosureIndicator.medium [] False
|
||||
, DisclosureIndicator.medium [] True
|
||||
, DisclosureIndicator.large [] False
|
||||
, DisclosureIndicator.large [] True
|
||||
]
|
||||
, view =
|
||||
\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!" ]
|
||||
|
@ -35,5 +35,6 @@ example =
|
||||
, state = {}
|
||||
, update = \_ state -> ( state, Cmd.none )
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = [ Divider.view "Dividing Line" ]
|
||||
, view = \state -> [ Divider.view "Dividing Line" ]
|
||||
}
|
||||
|
@ -7,8 +7,9 @@ module Examples.Fonts exposing (example, State, Msg)
|
||||
-}
|
||||
|
||||
import Category exposing (Category(..))
|
||||
import Css exposing (Style)
|
||||
import Example exposing (Example)
|
||||
import Html.Styled as Html
|
||||
import Html.Styled as Html exposing (Html)
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import KeyboardSupport exposing (Direction(..), Key(..))
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
@ -35,6 +36,12 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.none )
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
[ ( "baseFont", Fonts.baseFont )
|
||||
, ( "quizFont", Fonts.quizFont )
|
||||
, ( "ugFont", Fonts.ugFont )
|
||||
]
|
||||
|> List.map viewPreview
|
||||
, view =
|
||||
\_ ->
|
||||
[ Heading.h3 [] [ Html.text "baseFont" ]
|
||||
@ -48,3 +55,20 @@ example =
|
||||
[ 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" ]
|
||||
]
|
||||
|
@ -35,6 +35,12 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.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 =
|
||||
\_ ->
|
||||
[ Heading.h1 [] [ Html.text "This is the main page heading." ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Examples.IconExamples exposing (view, viewWithCustomStyles)
|
||||
module Examples.IconExamples exposing (preview, view, viewWithCustomStyles)
|
||||
|
||||
import Css
|
||||
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
|
||||
|
||||
|
||||
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 headerText icons =
|
||||
let
|
||||
|
@ -94,6 +94,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
, preview = []
|
||||
, view =
|
||||
\{ showLoadingFadeIn, showLoading, showSpinners } ->
|
||||
[ if showLoading then
|
||||
|
@ -10,9 +10,12 @@ import Category exposing (Category(..))
|
||||
import Css
|
||||
import Example exposing (Example)
|
||||
import Examples.IconExamples as IconExamples
|
||||
import Html.Styled as Html exposing (Html)
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import KeyboardSupport exposing (Direction(..), Key(..))
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Logo.V1 as Logo
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -35,6 +38,14 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.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 =
|
||||
\_ ->
|
||||
[ IconExamples.viewWithCustomStyles "NRI"
|
||||
|
@ -34,6 +34,7 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.none )
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\_ ->
|
||||
[ IconExamples.view "Levels"
|
||||
|
@ -47,6 +47,7 @@ example =
|
||||
}
|
||||
, { keys = [ Esc ], result = "Closes the menu" }
|
||||
]
|
||||
, preview = []
|
||||
, view = view
|
||||
}
|
||||
|
||||
|
@ -177,6 +177,11 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 =
|
||||
\state ->
|
||||
let
|
||||
|
@ -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.Key as Key
|
||||
import Browser.Dom as Dom
|
||||
import Category exposing (Category(..))
|
||||
import Css exposing (..)
|
||||
import Debug.Control as Control exposing (Control)
|
||||
import Debug.Control.Extra as ControlExtra
|
||||
import Example exposing (Example)
|
||||
import Html as Root
|
||||
import Html.Styled.Attributes as Attributes exposing (css)
|
||||
import KeyboardSupport exposing (Direction(..), Key(..))
|
||||
import Nri.Ui.Button.V10 as Button
|
||||
import Nri.Ui.Checkbox.V5 as Checkbox
|
||||
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
|
||||
import Nri.Ui.ClickableText.V3 as ClickableText
|
||||
import Nri.Ui.Colors.Extra
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.FocusTrap.V1 as FocusTrap
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Modal.V11 as Modal
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Task
|
||||
|
||||
|
||||
@ -125,6 +129,51 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 =
|
||||
\state ->
|
||||
let
|
||||
|
@ -17,6 +17,7 @@ import Html.Styled.Attributes exposing (css)
|
||||
import Http
|
||||
import KeyboardSupport exposing (Direction(..), Key(..))
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V2 as Heading
|
||||
import Nri.Ui.Page.V3 as Page exposing (RecoveryText(..))
|
||||
|
||||
@ -62,6 +63,32 @@ example =
|
||||
, state = { httpError = CommonControls.httpError, recoveryText = initRecoveryText }
|
||||
, update = update
|
||||
, 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 =
|
||||
\model ->
|
||||
let
|
||||
|
@ -38,6 +38,12 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.none )
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
IconExamples.preview
|
||||
[ Pennant.premiumFlag
|
||||
, Pennant.expiredPremiumFlag
|
||||
, Pennant.disabledPremiumFlag
|
||||
]
|
||||
, view =
|
||||
\_ ->
|
||||
[ IconExamples.viewWithCustomStyles "Premium Pennants"
|
||||
|
@ -34,6 +34,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
, preview = []
|
||||
, view = view
|
||||
, categories = [ Inputs ]
|
||||
, keyboardSupport =
|
||||
|
@ -36,6 +36,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
let
|
||||
|
@ -29,6 +29,7 @@ example =
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, categories = [ Inputs ]
|
||||
, keyboardSupport = []
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
let
|
||||
|
@ -42,6 +42,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
[ Keyed.node "div"
|
||||
|
@ -40,6 +40,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
[ viewModal state.modal
|
||||
|
@ -41,6 +41,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\{ sortState } ->
|
||||
let
|
||||
|
@ -32,6 +32,7 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
[ viewSettings state
|
||||
|
@ -6,12 +6,12 @@ module Examples.Switch exposing (Msg, State, example)
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Category
|
||||
import Example exposing (Example)
|
||||
import Html.Styled as Html
|
||||
import Nri.Ui.Heading.V2 as Heading
|
||||
import Nri.Ui.Switch.V1 as Switch
|
||||
import Nri.Ui.Text.V6 as Text
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -31,46 +31,47 @@ example =
|
||||
, state = True
|
||||
, update = \(Switch new) _ -> ( new, Cmd.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 =
|
||||
\interactiveIsOn ->
|
||||
[ Heading.h3 [] [ Html.text "Interactive" ]
|
||||
, Text.mediumBody
|
||||
[ Text.html
|
||||
[ Switch.view
|
||||
[ Switch.onSwitch Switch
|
||||
, Switch.id "switch-interactive"
|
||||
, Switch.label
|
||||
(if interactiveIsOn then
|
||||
Html.text "On"
|
||||
, Switch.view
|
||||
[ Switch.onSwitch Switch
|
||||
, Switch.id "switch-interactive"
|
||||
, Switch.label
|
||||
(if interactiveIsOn then
|
||||
Html.text "On"
|
||||
|
||||
else
|
||||
Html.text "Off"
|
||||
)
|
||||
]
|
||||
interactiveIsOn
|
||||
]
|
||||
else
|
||||
Html.text "Off"
|
||||
)
|
||||
]
|
||||
, Heading.h3 [] [ Html.text "Disabled" ]
|
||||
, Text.mediumBody
|
||||
[ Text.html
|
||||
[ Switch.view
|
||||
[ Switch.disabled
|
||||
, Switch.id "switch-disabled-on"
|
||||
, Switch.label (Html.text "Permanently on")
|
||||
]
|
||||
True
|
||||
]
|
||||
interactiveIsOn
|
||||
, Heading.h3 [] [ Html.text "Disabled (On)" ]
|
||||
, Switch.view
|
||||
[ Switch.disabled
|
||||
, Switch.id "switch-disabled-on"
|
||||
, Switch.label (Html.text "Permanently on")
|
||||
]
|
||||
, Text.mediumBody
|
||||
[ Text.html
|
||||
[ Switch.view
|
||||
[ Switch.disabled
|
||||
, Switch.id "switch-disabled-off"
|
||||
, Switch.label (Html.text "Permanently off")
|
||||
]
|
||||
False
|
||||
]
|
||||
True
|
||||
, Heading.h3 [] [ Html.text "Disabled (Off)" ]
|
||||
, Switch.view
|
||||
[ Switch.disabled
|
||||
, Switch.id "switch-disabled-off"
|
||||
, Switch.label (Html.text "Permanently off")
|
||||
]
|
||||
False
|
||||
]
|
||||
, categories = [ Category.Inputs ]
|
||||
, keyboardSupport = [{- TODO -}]
|
||||
|
@ -37,6 +37,29 @@ example =
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, categories = [ Tables, Layout ]
|
||||
, 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 =
|
||||
\() ->
|
||||
let
|
||||
|
@ -19,10 +19,13 @@ import Html.Styled as Html exposing (Html, fromUnstyled)
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import KeyboardSupport exposing (Key(..))
|
||||
import List.Zipper exposing (Zipper)
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
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.UiIcon.V1 as UiIcon
|
||||
import Routes
|
||||
import Task
|
||||
|
||||
|
||||
@ -117,9 +120,14 @@ update msg model =
|
||||
)
|
||||
|
||||
|
||||
exampleName : String
|
||||
exampleName =
|
||||
"Tabs"
|
||||
|
||||
|
||||
example : Example State Msg
|
||||
example =
|
||||
{ name = "Tabs"
|
||||
{ name = exampleName
|
||||
, version = 7
|
||||
, categories = [ Layout ]
|
||||
, keyboardSupport =
|
||||
@ -136,6 +144,49 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 =
|
||||
\model ->
|
||||
let
|
||||
@ -167,7 +218,7 @@ allTabs openTooltipId labelledBy =
|
||||
|> Svg.toHtml
|
||||
in
|
||||
[ Tabs.build { id = First, idString = "tab-0" }
|
||||
([ Tabs.spaHref "/#/doodad/Tabs"
|
||||
([ Tabs.spaHref <| Routes.toString (Routes.Doodad exampleName)
|
||||
, Tabs.tabString "1"
|
||||
, Tabs.withTooltip
|
||||
[ Tooltip.plaintext "Link Example"
|
||||
|
@ -30,6 +30,13 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview =
|
||||
[ ( "caption", Text.caption )
|
||||
, ( "smallBody", Text.smallBody )
|
||||
, ( "mediumBody", Text.mediumBody )
|
||||
, ( "ugMediumBody", Text.ugMediumBody )
|
||||
]
|
||||
|> List.map viewPreview
|
||||
, view =
|
||||
\state ->
|
||||
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 examples attributes =
|
||||
let
|
||||
|
@ -32,6 +32,7 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.none )
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, preview = [ TextWriting.footnote [ text "This is a footnote. " ] ]
|
||||
, view =
|
||||
\_ ->
|
||||
let
|
||||
|
@ -44,6 +44,7 @@ example =
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, categories = [ Inputs ]
|
||||
, keyboardSupport = []
|
||||
, preview = []
|
||||
, view =
|
||||
\state ->
|
||||
[ Heading.h1 [] [ Html.text "Textarea controls" ]
|
||||
|
@ -7,6 +7,7 @@ module Examples.TextInput exposing (Msg, State, example)
|
||||
-}
|
||||
|
||||
import Accessibility.Styled as Html exposing (..)
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Category exposing (Category(..))
|
||||
import Css exposing (..)
|
||||
import Debug.Control as Control exposing (Control)
|
||||
@ -32,6 +33,16 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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 =
|
||||
\state ->
|
||||
let
|
||||
|
@ -7,6 +7,7 @@ module Examples.Tooltip exposing (example, State, Msg)
|
||||
-}
|
||||
|
||||
import Accessibility.Styled as Html exposing (Html)
|
||||
import Accessibility.Styled.Key as Key
|
||||
import Category exposing (Category(..))
|
||||
import Css
|
||||
import Debug.Control as Control exposing (Control)
|
||||
@ -33,6 +34,32 @@ example =
|
||||
, state = init
|
||||
, update = update
|
||||
, 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
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,21 @@ example =
|
||||
, state = ()
|
||||
, update = \_ state -> ( state, Cmd.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 =
|
||||
\_ ->
|
||||
[ IconExamples.view "Interface"
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.Dom
|
||||
import Browser.Navigation exposing (Key)
|
||||
@ -10,15 +10,16 @@ import Css.Media exposing (withMedia)
|
||||
import Dict exposing (Dict)
|
||||
import Example exposing (Example)
|
||||
import Examples
|
||||
import Html as RootHtml
|
||||
import Html.Attributes
|
||||
import Html.Styled.Attributes as Attributes exposing (..)
|
||||
import Html.Styled.Events as Events
|
||||
import Nri.Ui.ClickableText.V3 as ClickableText
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.CssVendorPrefix.V1 as VendorPrefixed
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Heading.V2 as Heading
|
||||
import Nri.Ui.MediaQuery.V1 exposing (mobile, notMobile)
|
||||
import Nri.Ui.Page.V3 as Page
|
||||
import Routes as Routes exposing (Route(..))
|
||||
import Sort.Set as Set exposing (Set)
|
||||
import Task
|
||||
@ -40,6 +41,7 @@ main =
|
||||
type alias Model =
|
||||
{ -- Global UI
|
||||
route : Route
|
||||
, previousRoute : Maybe Route
|
||||
, moduleStates : Dict String (Example Examples.State Examples.Msg)
|
||||
, navigationKey : Key
|
||||
}
|
||||
@ -48,6 +50,7 @@ type alias Model =
|
||||
init : () -> Url -> Key -> ( Model, Cmd Msg )
|
||||
init () url key =
|
||||
( { route = Routes.fromLocation url
|
||||
, previousRoute = Nothing
|
||||
, moduleStates =
|
||||
Dict.fromList
|
||||
(List.map (\example -> ( example.name, example )) Examples.all)
|
||||
@ -61,6 +64,7 @@ type Msg
|
||||
= UpdateModuleStates String Examples.Msg
|
||||
| OnUrlRequest Browser.UrlRequest
|
||||
| OnUrlChange Url
|
||||
| ChangeRoute Route
|
||||
| SkipToMainContent
|
||||
| NoOp
|
||||
|
||||
@ -95,7 +99,18 @@ update action model =
|
||||
( model, Browser.Navigation.load loc )
|
||||
|
||||
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 ->
|
||||
( model
|
||||
@ -125,69 +140,86 @@ view_ model =
|
||||
let
|
||||
examples filterBy =
|
||||
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
|
||||
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
|
||||
[ css
|
||||
[ displayFlex
|
||||
, withMedia [ mobile ] [ flexDirection column, alignItems stretch ]
|
||||
, alignItems flexStart
|
||||
, minHeight (vh 100)
|
||||
]
|
||||
]
|
||||
[ navigation model.route
|
||||
, Html.main_ [ css [ flexGrow (int 1), sectionStyles ] ]
|
||||
(case model.route of
|
||||
Routes.Doodad doodad ->
|
||||
case List.head (examples (\m -> m.name == doodad)) of
|
||||
Just example ->
|
||||
[ mainContentHeader ("Viewing " ++ doodad ++ " doodad only")
|
||||
, Html.div [ id (String.replace "." "-" example.name) ]
|
||||
[ Example.view example
|
||||
|> 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 []
|
||||
]
|
||||
)
|
||||
[ navigation currentRoute
|
||||
, Html.main_
|
||||
[ css
|
||||
[ flexGrow (int 1)
|
||||
, margin2 (px 40) zero
|
||||
, Css.minHeight (Css.vh 100)
|
||||
]
|
||||
]
|
||||
content
|
||||
]
|
||||
|
||||
|
||||
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 =
|
||||
let
|
||||
@ -200,31 +232,31 @@ navigation route =
|
||||
False
|
||||
|
||||
link active hash displayName =
|
||||
Html.a
|
||||
[ css
|
||||
[ backgroundColor transparent
|
||||
, borderStyle none
|
||||
, textDecoration none
|
||||
ClickableText.link displayName
|
||||
[ ClickableText.small
|
||||
, ClickableText.css
|
||||
[ Css.color Colors.navy
|
||||
, Css.display Css.block
|
||||
, Css.padding (Css.px 8)
|
||||
, Css.borderRadius (Css.px 8)
|
||||
, if active then
|
||||
color Colors.navy
|
||||
Css.backgroundColor Colors.glacier
|
||||
|
||||
else
|
||||
color Colors.azure
|
||||
, Fonts.baseFont
|
||||
Css.batch []
|
||||
]
|
||||
, Attributes.href hash
|
||||
, ClickableText.href hash
|
||||
]
|
||||
[ Html.text displayName ]
|
||||
|
||||
navLink category =
|
||||
link (isActive category)
|
||||
("#/category/" ++ Debug.toString category)
|
||||
(Routes.toString (Routes.Category category))
|
||||
(Category.forDisplay category)
|
||||
|
||||
toNavLi element =
|
||||
Html.li
|
||||
[ css
|
||||
[ margin2 (px 10) zero
|
||||
[ margin zero
|
||||
, listStyle none
|
||||
, textDecoration none
|
||||
]
|
||||
@ -269,18 +301,12 @@ navigation route =
|
||||
, id "skip"
|
||||
]
|
||||
[ Html.text "Skip to main content" ]
|
||||
, Heading.h4 [] [ Html.text "Categories" ]
|
||||
, (link (route == Routes.All) "#/" "All"
|
||||
:: List.map navLink Category.all
|
||||
)
|
||||
|> List.map toNavLi
|
||||
|> Html.ul
|
||||
[ css [ margin4 zero zero (px 40) zero, padding zero ]
|
||||
[ css [ margin zero, padding zero ]
|
||||
, id "categories"
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
sectionStyles : Css.Style
|
||||
sectionStyles =
|
||||
Css.batch [ margin2 (px 40) zero ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Routes exposing (Route(..), fromLocation)
|
||||
module Routes exposing (Route(..), fromLocation, toString)
|
||||
|
||||
import Browser.Navigation as Navigation
|
||||
import Category
|
||||
@ -12,6 +12,19 @@ type Route
|
||||
| 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.oneOf
|
||||
|
Loading…
Reference in New Issue
Block a user