noredink-ui/styleguide-app/Debug/Control/View.elm

144 lines
4.6 KiB
Elm
Raw Normal View History

2022-03-04 22:21:34 +03:00
module Debug.Control.View exposing (codeFromList, view)
import Css exposing (..)
import Css.Media exposing (withMedia)
2022-03-04 22:21:34 +03:00
import Debug.Control as Control exposing (Control)
import Example
2022-03-04 22:21:34 +03:00
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.ClickableText.V3 as ClickableText
2022-03-04 22:21:34 +03:00
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.MediaQuery.V1 exposing (mobile)
import Url.Builder
2022-03-04 22:21:34 +03:00
{-| -}
view :
{ name : String
, version : Int
, update : Control a -> msg
2022-03-04 22:21:34 +03:00
, settings : Control a
, toExampleCode : a -> List { sectionName : String, code : String }
}
-> Html msg
view config =
let
value =
Control.currentValue config.settings
in
div
[ css
[ displayFlex
, Css.flexWrap Css.wrap
, Css.property "gap" "10px"
, withMedia [ mobile ] [ flexDirection column, alignItems stretch ]
]
]
[ viewSection "Settings" <|
[ fromUnstyled (Control.view config.update config.settings) ]
, viewExampleCode config (config.toExampleCode value)
2022-03-04 22:21:34 +03:00
]
viewExampleCode :
2022-03-24 02:20:37 +03:00
{ component | name : String, version : Int }
-> List { sectionName : String, code : String }
-> Html msg
2022-03-24 02:20:37 +03:00
viewExampleCode component values =
viewSection "Generated Code" <|
List.concatMap
2022-03-24 02:20:37 +03:00
(\example ->
[ details
[]
[ summary []
[ Heading.h4
[ Heading.css [ Css.display Css.inline ]
]
2022-03-24 02:20:37 +03:00
[ text example.sectionName ]
]
2022-03-24 02:20:37 +03:00
, ClickableText.link ("View " ++ example.sectionName ++ " example on Ellie")
[ ClickableText.linkExternal (generateEllieLink component example)
, ClickableText.small
]
2022-03-24 02:20:37 +03:00
, code
[ css
[ display block
, whiteSpace preWrap
, Css.marginTop (px 8)
]
]
2022-03-24 02:20:37 +03:00
[ text example.code ]
2022-03-04 22:21:34 +03:00
]
]
)
values
2022-03-24 02:20:37 +03:00
generateEllieLink : { component | name : String, version : Int } -> { sectionName : String, code : String } -> String
generateEllieLink component { sectionName, code } =
Url.Builder.crossOrigin "https://ellie-app.com/a/example/v1"
[]
2022-03-24 02:20:37 +03:00
[ Url.Builder.string "title" (component.name ++ " | " ++ sectionName)
, Url.Builder.string "elmcode" (generateElmExampleModule component code)
, Url.Builder.string "htmlcode" ellieHtmlSetup
2022-03-24 02:17:19 +03:00
, -- At some point, a system of some kind will be required to keep these values
-- in line with the allowed elm json values.
-- I think in most cases, the API to use a noredink-ui component should require _only_ the following
-- packages. Feel free to add packages if it seems necessary!
Url.Builder.string "packages" "elm/core@1.0.5"
, Url.Builder.string "packages" "elm/html@1.0.0"
, Url.Builder.string "packages" "rtfeldman/elm-css@17.0.5"
, Url.Builder.string "packages" "NoRedInk/noredink-ui@15.8.1"
2022-03-24 02:17:19 +03:00
, Url.Builder.string "packages" "pablohirafuji/elm-markdown@2.0.5"
, Url.Builder.string "elmversion" "0.19.1"
]
2022-03-24 02:20:37 +03:00
generateElmExampleModule : { component | name : String, version : Int } -> String -> String
generateElmExampleModule component code =
[ "module Main exposing (main)"
, ""
, "import Css exposing (Style)"
, "import Html as RootHtml"
, "import Html.Styled exposing (..)"
2022-03-24 02:19:38 +03:00
, "import Nri.Ui.Colors.V1 as Colors"
, "import Nri.Ui.UiIcon.V1 as UiIcon"
2022-03-24 02:20:37 +03:00
, "import " ++ Example.fullName component ++ " as " ++ component.name
, ""
, "main : RootHtml.Html msg"
, "main ="
, " " ++ code
, " |> toUnstyled"
]
|> String.join "\n"
|> String.replace "\t" " "
ellieHtmlSetup : String
ellieHtmlSetup =
"""
<html> <head></head>
<body>
<main></main>
<script>
var app = Elm.Main.init({ node: document.querySelector('main') })
</script>
</body>
</html>
"""
viewSection : String -> List (Html msg) -> Html msg
viewSection name children =
section [ css [ flex (int 1) ] ]
(Heading.h3 [] [ text name ]
:: children
2022-03-04 22:21:34 +03:00
)
codeFromList : List ( String, a ) -> String
codeFromList list =
"\n\t[ "
++ String.join "\n\t, " (List.map Tuple.first list)
++ "\n\t] "