Merge pull request #2 from NoRedInk/add-styleguide

add mini styleguide for ui components
This commit is contained in:
Jasper Woudenberg 2018-02-21 15:50:41 +01:00 committed by GitHub
commit 9987d5f738
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 766 additions and 0 deletions

View File

@ -0,0 +1,49 @@
module Nri.Ui.Css.VendorPrefixed exposing (complexProperty, property, value)
{-| Vendor prefixed css properties.
@docs property, value, complexProperty
-}
import Css
{-| Css vendor prefixes
-}
prefixes : List String
prefixes =
[ "-webkit-", "-moz-", "-o-", "-ms-", "" ]
{-| Same as Css.property but vendor prefixed.
-}
property : String -> String -> Css.Style
property prop value =
prefixes
|> List.map
(\prefix ->
Css.property (prefix ++ prop) value
)
|> Css.batch
{-| Same as Css.property but vendor prefixed.
-}
value : String -> String -> Css.Style
value prop value =
prefixes
|> List.map
(\prefix ->
Css.property prop (prefix ++ value)
)
|> Css.batch
{-| Used to build more complex Css styles
-}
complexProperty : (String -> Css.Style) -> Css.Style
complexProperty buildProp =
prefixes
|> List.map buildProp
|> Css.batch

1
styleguide-app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
elm.js

View File

@ -0,0 +1,34 @@
module Examples.Text exposing (example)
{- \
@docs example
-}
import Html
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample)
import Nri.Ui.Text.V1 as Text
{-| -}
example : ModuleExample msg
example =
{ filename = "Nri.Ui.Text.V1.elm"
, category = Text
, content =
let
longerBody =
"""Be on the lookout for a new and improved assignment
creation form! Soon, you'll be able to easily see a summary
of the content you're assigning, as well as an estimate for
how long the assignment will take.
"""
in
[ Text.heading [ Html.text "This is the main page heading." ]
, Text.tagline [ Html.text "This is a tagline" ]
, Text.subHeading [ Html.text "This is a subHeading" ]
, Text.mediumBody [ Html.text <| "This is a mediumBody. " ++ longerBody ]
, Text.smallBody [ Html.text <| "This is a smallBody. " ++ longerBody ]
, Text.smallBodyGray [ Html.text <| "This is a smallBodyGray. " ++ longerBody ]
, Text.caption [ Html.text <| "This is a caption. " ++ longerBody ]
]
}

28
styleguide-app/Main.elm Normal file
View File

@ -0,0 +1,28 @@
module Main exposing (..)
import Model exposing (..)
import Navigation
import NriModules as NriModules
import Routes as Routes exposing (Route(..))
import Update exposing (Msg(..), subscriptions, update)
import View exposing (view)
main : Program Never Model Msg
main =
Navigation.program
(Routes.fromLocation >> UrlChanged)
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
init : Navigation.Location -> ( Model, Cmd Msg )
init location =
( { route = Routes.fromLocation location
, moduleStates = NriModules.init
}
, Cmd.none
)

11
styleguide-app/Model.elm Normal file
View File

@ -0,0 +1,11 @@
module Model exposing (..)
import NriModules exposing (ModuleStates)
import Routes exposing (Route)
type alias Model =
{ -- Global UI
route : Route
, moduleStates : ModuleStates
}

View File

@ -0,0 +1,209 @@
module ModuleExample
exposing
( Category(..)
, ModuleExample
, ModuleMessages
, categoryForDisplay
, categoryFromString
, styles
, view
)
import Css exposing (..)
import Css.Namespace
import Html exposing (Html, img)
import Html.Attributes
import Html.CssHelpers
import Nri.Colors exposing (..)
type alias ModuleExample msg =
{ filename : String
, content : List (Html msg)
, category : Category
}
{-| -}
type alias ModuleMessages moduleMsg parentMsg =
{ noOp : parentMsg
, showItWorked : String -> parentMsg
, wrapper : moduleMsg -> parentMsg
}
type Category
= Layout
| Inputs
| Buttons
| Icons
| Behaviors
| Messaging
| Modals
| Writing
| NotesToDeveloper
| Colors
| Text
| DynamicSymbols
| Pages
| QuestionTypes
{-| Used for route changes
-}
categoryFromString : String -> Result String Category
categoryFromString string =
case string of
"Layout" ->
Ok Layout
"Inputs" ->
Ok Inputs
"Behaviors" ->
Ok Behaviors
"Buttons" ->
Ok Buttons
"Icons" ->
Ok Icons
"Messaging" ->
Ok Messaging
"Modals" ->
Ok Modals
"Writing" ->
Ok Writing
"NotesToDeveloper" ->
Ok NotesToDeveloper
"Colors" ->
Ok Colors
"Text" ->
Ok Text
"DynamicSymbols" ->
Ok DynamicSymbols
"Pages" ->
Ok Pages
"QuestionTypes" ->
Ok QuestionTypes
_ ->
Err "Invalid String"
categoryForDisplay : Category -> String
categoryForDisplay category =
case category of
Layout ->
"Layout"
Inputs ->
"Inputs"
Behaviors ->
"Behaviors"
Buttons ->
"Buttons"
Icons ->
"Icons"
Messaging ->
"Messaging"
Modals ->
"Modals"
Writing ->
"Writing"
NotesToDeveloper ->
"NotesToDeveloper"
Colors ->
"Colors"
Text ->
"Text"
DynamicSymbols ->
"Dynamic Symbols"
Pages ->
"Pages"
QuestionTypes ->
"Question types / Quiz UI"
view : Bool -> ModuleExample msg -> Html msg
view showFocusLink { filename, content } =
Html.div [ class [ Module ] ]
[ Html.div [ class [ ModuleHeader ] ]
[ Html.h2
[ class [ ModuleName ] ]
[ Html.text filename
, Html.text " "
, if showFocusLink then
Html.a
[ Html.Attributes.href <| "#doodad/" ++ filename ]
[ Html.text "(see only this)" ]
else
Html.text ""
]
]
, Html.div [ class [ ModuleBody ] ] content
]
type Classes
= Module
| ModuleHeader
| ModuleName
| ModuleImporting
| ModuleBody
viewStyles : List Css.Snippet
viewStyles =
[ Css.class ModuleHeader
[ display block
, backgroundColor glacier
, padding (px 20)
, marginTop (px 20)
]
, Css.class ModuleImporting
[ display block
, padding (px 20)
, margin2 (px 20) zero
]
, Css.class ModuleBody
[ padding2 (px 20) zero ]
, Css.class ModuleName
[ color gray20
, fontFamilies [ qt "Source Code Pro", "Consolas", "Courier", "monospace" ]
, fontSize (px 20)
]
]
styles : Css.Stylesheet
styles =
List.concat
[ viewStyles
]
|> (Css.stylesheet << Css.Namespace.namespace "Page-StyleGuide-ModuleExample-")
{ id, class, classList } =
Html.CssHelpers.withNamespace "Page-StyleGuide-ModuleExample-"

View File

@ -0,0 +1,87 @@
module NriModules exposing (ModuleStates, Msg, init, nriThemedModules, styles, subscriptions, update)
import Css exposing (..)
import Examples.Text as TextExample
import Html exposing (Html, img)
import Html.Attributes exposing (..)
import ModuleExample exposing (Category(..), ModuleExample)
import Navigation
import Nri.Ui.Text.V1 as Text
import String.Extra
type alias ModuleStates =
{}
init : ModuleStates
init =
{}
type Msg
= ShowItWorked String String
| NoOp
update : Msg -> ModuleStates -> ( ModuleStates, Cmd Msg )
update msg moduleStates =
case msg of
ShowItWorked group message ->
let
_ =
Debug.log group message
in
( moduleStates, Cmd.none )
NoOp ->
( moduleStates, Cmd.none )
subscriptions : ModuleStates -> Sub Msg
subscriptions moduleStates =
Sub.batch
[]
{-| A container with a visually-apparent size for demonstrating how style guide components
fill their parents.
-}
container : Int -> List (Html msg) -> Html msg
container width children =
Html.div
[ Html.Attributes.class "demo-container"
, style [ ( "width", toString width ++ "px" ) ]
]
children
nriThemedModules : ModuleStates -> List (ModuleExample Msg)
nriThemedModules model =
[ TextExample.example
]
exampleMessages : (msg -> Msg) -> String -> ModuleExample.ModuleMessages msg Msg
exampleMessages exampleMessageWrapper exampleName =
{ noOp = NoOp
, showItWorked = ShowItWorked exampleName
, wrapper = exampleMessageWrapper
}
route : Navigation.Location -> Maybe String
route location =
location.hash
|> String.dropLeft 1
|> String.Extra.nonEmpty
styles : List Stylesheet
styles =
List.concat
[ -- NOTE: these will go away as the modules' styles are integrated with Nri.Css.Site.elm
[ ModuleExample.styles
]
, (Text.styles |> .css) ()
]

17
styleguide-app/README.md Normal file
View File

@ -0,0 +1,17 @@
# NoRedInk style guide
A helper app to test out new styles while working with the package.
## Running this app
Generate the elm code:
```elm
elm-make Main.elm --output elm.js
```
Open `index.html` in a browser:
```
open index.html
```

31
styleguide-app/Routes.elm Normal file
View File

@ -0,0 +1,31 @@
module Routes exposing (Route(..), fromLocation)
import ModuleExample exposing (categoryFromString)
import Navigation
import UrlParser as Url exposing ((</>), custom, s, string, top)
type Route
= Doodad String
| Category ModuleExample.Category
| All
route : Url.Parser (Route -> a) a
route =
Url.oneOf
[ Url.map Category (s "category" </> category)
, Url.map Doodad (s "doodad" </> s "Nri" </> string)
, Url.map All top
]
category : Url.Parser (ModuleExample.Category -> a) a
category =
custom "category" categoryFromString
fromLocation : Navigation.Location -> Route
fromLocation location =
Url.parseHash route location
|> Maybe.withDefault All

37
styleguide-app/Update.elm Normal file
View File

@ -0,0 +1,37 @@
module Update exposing (Msg(..), subscriptions, update)
import Model exposing (..)
import NriModules as NriModules
import Routes as Routes exposing (Route)
type Msg
= UpdateModuleStates NriModules.Msg
| UrlChanged Route
| NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update action model =
case action of
UpdateModuleStates msg ->
let
( moduleStates, cmd ) =
NriModules.update msg model.moduleStates
in
( { model | moduleStates = moduleStates }
, Cmd.map UpdateModuleStates cmd
)
UrlChanged route ->
( { model | route = route }
, Cmd.none
)
NoOp ->
( model, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.map UpdateModuleStates (NriModules.subscriptions model.moduleStates)

221
styleguide-app/View.elm Normal file
View File

@ -0,0 +1,221 @@
module View exposing (view)
import Css exposing (..)
import Css.Namespace
import Html exposing (Html, img)
import Html.Attributes exposing (..)
import Html.CssHelpers
import Model exposing (..)
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample, categoryForDisplay)
import Nri.Colors as Colors
import Nri.Fonts as Fonts
import Nri.Ui.Css.VendorPrefixed as VendorPrefixed
import NriModules as NriModules exposing (nriThemedModules)
import Routes as Routes exposing (Route)
import Update exposing (..)
view : Model -> Html Msg
view model =
Html.div []
[ attachElmCssStyles
, Html.div [ class [ StyleGuideLayout ] ]
[ navigation model.route
, Html.div [ class [ StyleGuideContent ] ]
(case model.route of
Routes.Doodad doodad ->
[ Html.h2 []
[ Html.a [ Html.Attributes.href "#" ] [ Html.text "(see all)" ] ]
, nriThemedModules model.moduleStates
|> List.filter (\m -> m.filename == ("Nri/" ++ doodad))
|> List.map (ModuleExample.view True)
|> Html.div []
|> Html.map UpdateModuleStates
]
Routes.Category category ->
[ Html.section [ class [ Section ] ]
[ newComponentsLink
, Html.h2 [] [ Html.text (toString category) ]
, nriThemedModules model.moduleStates
|> List.filter (\doodad -> category == doodad.category)
|> List.map (ModuleExample.view True)
|> Html.div []
|> Html.map UpdateModuleStates
]
]
Routes.All ->
[ Html.section [ class [ Section ] ]
[ newComponentsLink
, Html.h2 [] [ Html.text "NRI-Themed Modules" ]
, Html.h3 [] [ Html.text "All Categories" ]
, nriThemedModules model.moduleStates
|> List.map (ModuleExample.view True)
|> Html.div []
|> Html.map UpdateModuleStates
]
]
)
]
]
newComponentsLink : Html Msg
newComponentsLink =
Html.div []
[ Html.h2 [] [ Html.text "New Styleguide Components" ]
, Html.div []
[ Html.text "Future styleguide components can be found in "
, Html.a [ href "https://app.zeplin.io/project/5973fb495395bdc871ebb055" ] [ Html.text "this Zepplin" ]
, Html.text "."
]
]
navigation : Route -> Html Msg
navigation route =
let
isActive category =
case route of
Routes.Category routeCategory ->
category == routeCategory
_ ->
False
navLink category =
Html.li []
[ Html.a
[ classList
[ ( ActiveCategory, isActive category )
, ( NavLink, True )
]
, Html.Attributes.href <| "#category/" ++ toString category
]
[ Html.text (categoryForDisplay category) ]
]
in
Html.div [ class [ CategoryMenu ] ]
[ Html.h4 []
[ Html.text "Categories" ]
, Html.ul [ class [ CategoryLinks ] ] <|
Html.li []
[ Html.a
[ Html.Attributes.href "#"
, classList
[ ( ActiveCategory, route == Routes.All )
, ( NavLink, True )
]
]
[ Html.text "All" ]
]
:: List.map
navLink
[ Text
, Colors
, Layout
, Inputs
, Buttons
, Icons
, Behaviors
, Messaging
, Modals
, Writing
, DynamicSymbols
, Pages
, QuestionTypes
]
]
type Classes
= Section
| StyleGuideLayout
| StyleGuideContent
| CategoryMenu
| CategoryLinks
| ActiveCategory
| NavLink
layoutFixer : List Css.Snippet
layoutFixer =
-- TODO: remove when universal header seizes power
[ Css.selector "#header-menu"
[ Css.property "float" "none"
]
, Css.selector "#page-container"
[ maxWidth (px 1400)
]
, Css.selector ".anonymous .log-in-button"
[ Css.property "float" "none"
, right zero
, top zero
]
, Css.selector ".l-inline-blocks"
[ textAlign right
]
, Css.everything
[ Fonts.baseFont
]
]
styles : Css.Stylesheet
styles =
(Css.stylesheet << Css.Namespace.namespace "Page-StyleGuide-") <|
List.concat
[ [ Css.class Section
[ margin2 (px 40) zero
]
, Css.class StyleGuideLayout
[ displayFlex
, alignItems flexStart
]
, Css.class StyleGuideContent
[ flexGrow (int 1)
]
, Css.class CategoryMenu
[ flexBasis (px 300)
, backgroundColor Colors.gray92
, marginRight (px 40)
, padding (px 25)
, VendorPrefixed.value "position" "sticky"
, top (px 150)
, flexShrink zero
]
, Css.class CategoryLinks
[ margin4 zero zero (px 40) zero
, Css.children
[ Css.selector "li"
[ margin2 (px 10) zero
]
]
]
, Css.class NavLink
[ backgroundColor transparent
, borderStyle none
, color Colors.azure
]
, Css.class ActiveCategory
[ color Colors.navy
]
]
, layoutFixer
]
{ id, class, classList } =
Html.CssHelpers.withNamespace "Page-StyleGuide-"
attachElmCssStyles : Html msg
attachElmCssStyles =
Html.CssHelpers.style <|
.css <|
Css.compile <|
List.concat
[ [ styles ]
, NriModules.styles
]

View File

@ -0,0 +1,27 @@
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
".",
"../src"
],
"exposed-modules": [],
"dependencies": {
"NoRedInk/nri-elm-css": "5.0.0 <= v <= 5.0.0",
"NoRedInk/view-extra": "2.0.0 <= v < 3.0.0",
"elm-community/string-extra": "1.4.0 <= v < 2.0.0",
"elm-lang/core": "5.1.1 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0",
"elm-lang/navigation": "2.1.0 <= v < 3.0.0",
"evancz/url-parser": "2.0.1 <= v < 3.0.0",
"pablohirafuji/elm-markdown": "2.0.4 <= v < 3.0.0",
"rtfeldman/elm-css": "11.2.0 <= v < 12.0.0",
"rtfeldman/elm-css-helpers": "2.1.0 <= v < 3.0.0",
"rtfeldman/elm-css-util": "1.0.2 <= v < 2.0.0",
"tesk9/accessible-html": "3.0.0 <= v < 4.0.0",
"wernerdegroot/listzipper": "3.0.0 <= v < 4.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}

14
styleguide-app/index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>NoRedInk style guide</title>
<link href="https://fonts.googleapis.com/css?family=Muli:400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
</head>
<body>
<script src="elm.js"></script>
<script>
const app = Elm.Main.fullscreen();
</script>
</body>
</html>