noredink-ui/styleguide-app/Example.elm

248 lines
7.6 KiB
Elm
Raw Normal View History

module Example exposing (Example, fullName, preview, view, wrapMsg, wrapState)
2020-03-31 23:20:03 +03:00
2022-03-25 23:55:26 +03:00
import Accessibility.Styled.Aria as Aria
2022-03-29 00:52:25 +03:00
import Accessibility.Styled.Widget as Widget
2020-03-31 23:20:03 +03:00
import Category exposing (Category)
2020-03-31 23:33:05 +03:00
import Css exposing (..)
import EllieLink
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.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.ClickableText.V3 as ClickableText
2022-03-15 21:06:13 +03:00
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Container.V2 as Container
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.UiIcon.V1 as UiIcon
import Routes exposing (Route)
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)
, view : EllieLink.Config -> state -> List (Html msg)
2020-03-31 23:20:03 +03:00
, categories : List Category
, keyboardSupport : List KeyboardSupport
2020-03-31 23:20:03 +03:00
}
2020-03-31 23:33:05 +03:00
fullName : { example | version : Int, name : String } -> 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 =
\ellieLinkConfig state ->
List.map (Html.map wrapMsg_)
(example.view ellieLinkConfig 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 =
\ellieLinkConfig state ->
Maybe.map (example.view ellieLinkConfig) (unwrapState state)
|> 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 : (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
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) ]
2022-01-22 03:49:18 +03:00
, ClickableText.nriDescription "doodad-link"
]
2021-11-05 22:04:46 +03:00
:: [ Html.div
[ Attributes.css
[ Css.displayFlex
, Css.flexDirection Css.column
]
, Widget.hidden True
2021-11-05 22:04:46 +03:00
]
(List.map (Html.map never) example.preview)
]
2021-11-05 21:19:08 +03:00
)
]
view : Maybe Route -> EllieLink.Config -> Example state msg -> Html msg
view previousRoute ellieLinkConfig example =
2021-11-06 01:24:00 +03:00
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 (view_ previousRoute ellieLinkConfig example)
2022-03-29 00:52:25 +03:00
, Container.custom [ Attributes.id (String.replace "." "-" example.name) ]
2021-11-06 01:24:00 +03:00
]
view_ : Maybe Route -> EllieLink.Config -> Example state msg -> List (Html msg)
view_ previousRoute ellieLinkConfig example =
2022-03-25 23:55:26 +03:00
let
navMenu items =
2022-03-29 00:52:25 +03:00
Html.nav [ Widget.label "Example" ]
2022-03-25 23:55:26 +03:00
[ Html.ul
[ Attributes.css
[ margin zero
, padding zero
, displayFlex
, alignItems center
, justifyContent flexStart
, flexWrap Css.wrap
]
]
(List.map
(\i ->
Html.li
[ Attributes.css
[ Css.listStyle Css.none ]
]
[ i ]
)
items
)
2020-03-31 23:33:05 +03:00
]
2022-03-25 23:55:26 +03:00
in
2022-03-25 23:41:02 +03:00
[ Html.header
[ Attributes.css
2022-03-25 23:55:26 +03:00
[ Css.paddingBottom (Css.px 10)
2022-03-25 23:41:02 +03:00
, Css.marginBottom (Css.px 20)
2022-03-25 23:55:26 +03:00
, Css.borderBottom3 (Css.px 1) Css.solid Colors.gray92
2020-03-31 23:33:05 +03:00
]
2022-03-25 23:41:02 +03:00
]
2022-03-25 23:55:26 +03:00
[ navMenu
2022-03-29 00:49:32 +03:00
[ Heading.h1
[ Heading.custom [ Aria.currentPage ] ]
[ Html.text (fullName example)
2022-03-25 23:55:26 +03:00
]
, docsLink example
, srcLink example
2022-03-25 23:55:26 +03:00
, closeExample previousRoute example
]
2022-03-25 23:41:02 +03:00
]
, KeyboardSupport.view example.keyboardSupport
, Html.main_ [] (example.view ellieLinkConfig example.state)
2022-03-25 23:41:02 +03:00
]
closeExample : Maybe Route -> Example state msg -> Html msg
closeExample previousRoute example =
ClickableSvg.link ("Close " ++ example.name ++ " example")
UiIcon.x
[ ClickableSvg.href
(Maybe.withDefault Routes.All previousRoute
|> Routes.toString
)
, ClickableSvg.exactSize 20
, ClickableSvg.css
[ Css.position Css.absolute
, Css.top (Css.px 15)
, Css.right (Css.px 15)
2020-03-31 23:33:05 +03:00
]
]
exampleHref : Example state msg -> String
exampleHref example =
Routes.toString (Routes.Doodad example.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
]