noredink-ui/styleguide-app/Example.elm

215 lines
6.3 KiB
Elm
Raw Normal View History

module Example exposing (Example, preview, view, wrapMsg, wrapState)
2020-03-31 23:20:03 +03:00
import Category exposing (Category)
2020-03-31 23:33:05 +03:00
import Css exposing (..)
2020-10-02 07:08:41 +03:00
import Css.Global exposing (a, descendants)
2020-03-31 23:20:03 +03:00
import Html.Styled as Html exposing (Html)
2020-03-31 23:33:05 +03:00
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.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors exposing (..)
import Nri.Ui.Container.V2 as Container
2020-10-02 07:08:41 +03:00
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
2020-06-20 00:23:17 +03:00
import Nri.Ui.Html.Attributes.V2 as AttributeExtras exposing (targetBlank)
2020-03-31 23:20:03 +03:00
type alias Example state msg =
{ name : String
2020-09-09 21:43:10 +03:00
, version : Int
2020-03-31 23:20:03 +03:00
, state : state
, update : msg -> state -> ( state, Cmd msg )
, subscriptions : state -> Sub msg
2021-11-05 21:19:08 +03:00
, preview : List (Html Never)
2020-03-31 23:20:03 +03:00
, view : state -> List (Html msg)
, categories : List Category
, keyboardSupport : List KeyboardSupport
2020-03-31 23:20:03 +03:00
}
2020-03-31 23:33:05 +03:00
fullName : Example state msg -> String
fullName example =
"Nri.Ui." ++ example.name ++ ".V" ++ String.fromInt example.version
wrapMsg :
(msg -> msg2)
-> (msg2 -> Maybe msg)
2020-04-01 00:39:34 +03:00
-> Example state msg
-> Example state msg2
wrapMsg wrapMsg_ unwrapMsg example =
2020-04-01 00:39:34 +03:00
{ name = example.name
2020-09-09 21:43:10 +03:00
, version = example.version
, state = example.state
2020-04-01 00:39:34 +03:00
, update =
\msg2 state ->
case unwrapMsg msg2 of
Just msg ->
2020-04-01 00:39:34 +03:00
example.update msg state
|> Tuple.mapSecond (Cmd.map wrapMsg_)
Nothing ->
( state, Cmd.none )
, subscriptions = \state -> Sub.map wrapMsg_ (example.subscriptions state)
2021-11-05 21:48:09 +03:00
, preview = example.preview
, view = \state -> List.map (Html.map wrapMsg_) (example.view state)
, categories = example.categories
, keyboardSupport = example.keyboardSupport
}
wrapState :
(state -> state2)
-> (state2 -> Maybe state)
-> Example state msg
-> Example state2 msg
wrapState wrapState_ unwrapState example =
{ name = example.name
2020-09-09 21:43:10 +03:00
, version = example.version
, state = wrapState_ example.state
, update =
\msg state2 ->
case unwrapState state2 of
Just state ->
example.update msg state
|> Tuple.mapFirst wrapState_
2020-04-01 00:39:34 +03:00
Nothing ->
( state2, Cmd.none )
, subscriptions =
unwrapState
>> Maybe.map example.subscriptions
>> Maybe.withDefault Sub.none
2021-11-05 21:48:09 +03:00
, preview = example.preview
, view =
unwrapState
>> Maybe.map example.view
>> Maybe.withDefault []
2020-04-01 00:39:34 +03:00
, categories = example.categories
, keyboardSupport = example.keyboardSupport
2020-04-01 00:39:34 +03:00
}
preview : (String -> msg2) -> Example state msg -> Html msg2
preview navigate =
Lazy.lazy (preview_ navigate)
preview_ : (String -> 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 (exampleHref example)) ]
, Container.html
2021-11-05 21:19:08 +03:00
(ClickableText.link example.name
[ ClickableText.href (exampleHref example)
2021-11-05 21:59:39 +03:00
, ClickableText.css [ Css.marginBottom (Css.px 10) ]
]
2021-11-05 22:04:46 +03:00
:: [ Html.div
[ Attributes.css
[ Css.displayFlex
, Css.flexDirection Css.column
]
]
(List.map (Html.map never) example.preview)
]
2021-11-05 21:19:08 +03:00
)
]
view : Example state msg -> Html msg
view =
Lazy.lazy view_
view_ : Example state msg -> Html msg
view_ example =
2020-03-31 23:33:05 +03:00
Html.div
[ -- this class makes the axe accessibility checking output easier to parse
String.replace "." "-" example.name
|> (++) "module-example__"
|> Attributes.class
]
[ Html.div
[ Attributes.css
[ displayFlex
, alignItems center
, justifyContent flexStart
2020-04-01 00:39:34 +03:00
, flexWrap Css.wrap
2020-10-02 07:08:41 +03:00
, Fonts.baseFont
, descendants [ Css.Global.a [ textDecoration none ] ]
2020-03-31 23:33:05 +03:00
]
]
[ exampleLink example
, docsLink example
, srcLink example
2020-03-31 23:33:05 +03:00
]
, KeyboardSupport.view example.keyboardSupport
2020-10-02 07:08:41 +03:00
, 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)
]
]
(example.view example.state)
2020-03-31 23:33:05 +03:00
]
exampleHref : Example state msg -> String
exampleHref example =
"#/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"
]
]
]
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) ]
2020-03-31 23:33:05 +03:00
]