kalutheo/elm-ui-explorer/5.0.0

NOTE: the latest version is 9.1.0

UIExplorer

Anatomy of the UI Explorer

  • The Explorer is devided into a list of UICategory (ex: Buttons, Icons)
  • Each Category contains some UI items (ex: the Buttons Category can contain ToggleButton, ButtonWithImage, SubmitButton etc...)
  • Each UI item defines states (ex: Loaded, Disabled etc..) that we usually call stories

How to explore my UI ?

explore : Config a b c -> List (UI a b c) -> UIExplorerProgram a b c

Launches a UI Explorer Applicaton given a list of UI. This is the simplest way to initialize the UI Explorer app.

Here we have an example of a Button that we want to explore:

import UIExplorer exposing (UIExplorerProgram, defaultConfig, explore, storiesOf)


button : String -> String -> Html.Html msg
button label bgColor =
    Html.button
        [ style "background-color" bgColor ]
        [ Html.text label ]


main : UIExplorerProgram {} () {}
main =
    explore
        defaultConfig
        [ storiesOf
            "Button"
            [ ( "SignIn", \_ -> button "Sign In" "pink", {} )
            , ( "SignOut", \_ -> button "Sign Out" "cyan", {} )
            , ( "Loading", \_ -> button "Loading please wait..." "white", {} )
            ]
        ]
exploreWithCategories : Config a b c -> List (UICategory a b c) -> UIExplorerProgram a b c

Explore with Categories

Launches a UI Explorer Applicaton given a list of UI Categories. This is a more advanced way to initialize the UI Explorer app. It can be usefull if you want to organize your UI by family.

main : UIExplorerProgram {} () {}
main =
    exploreWithCategories
        defaultConfig
        (createCategories
            |> category "Getting Started"
                [ storiesOf
                    "About"
                    [ ( "About", \_ -> Docs.toMarkdown Docs.about, { hasMenu = False } ) ]
                ]
            |> category
                "Guidelines"
                [ storiesOf
                    "Principles"
                    [ ( "Principles", \_ -> Docs.toMarkdown Docs.principles, { hasMenu = False } ) ]
                ]
            |> category
                "Styles"
                [ storiesOf
                    "Colors"
                    [ ( "Brand", \_ -> ColorGuide.viewBrandColors, { hasMenu = True } )
                    , ( "Neutral", \_ -> ColorGuide.viewNeutralColors, { hasMenu = True } )
                    ]
                , storiesOf
                    "Typography"
                    [ ( "Typography", \_ -> TypographyGuide.view, { hasMenu = False } )
                    ]
                ]
        )
        defaultConfig
defaultConfig : Config {} b c

Sensible default configuration to initialize the explorer.

Types

type UI a b c

A UI represents a view and lists a set of stories. For Example : A Button with following stories (Loading, Disabled)

type UICategory a b c

Represents a family of related views. For example using Atomic Design, we can have the following categories : Atoms, Molecules etc..

type alias Model a b c =
{ categories : List (UICategory a b c)
, selectedUIId : Maybe String
, selectedStoryId : Maybe String
, selectedCategory : Maybe String
, url : Url
, key : Key
, customModel : a
}

Model of the UI Explorer. You should not interact with this Type unless you are trying to achieve more advanced stuff such as Plugin Creation.

type Msg a
= ExternalMsg a
| SelectStory String
| UrlChange Url
| LinkClicked UrlRequest
| NoOp

Messages of the UI Explorer. You should not interact with this Type unless you are trying to achieve more advanced stuff such as Plugin Creation.

type alias UIExplorerProgram a b c =
Program () (Model a b c) (Msg b)

The Elm Program created by the UI Explorer.

The three argument should only be changed when using Plugins. Default values are sufficent most of the time.

  • a : Custom Model entry that can be used to store data related to Plugins
  • b : Message Type emitted by the UIExporer main view
  • c : Data related to Plugins and used by your Stories

Advanced

Elm UI Explorer can be extended with Plugins. The package comes with core plugins and you can obviously create your own. Theses plugins allow to customize the appearance of the UI Explorer. Functions listed below are related to that.

type alias Config a b c =
{ customModel : a
, customHeader : Maybe (CustomHeader b)
, update : b -> Model a b c -> ( Model a b c, Cmd b )
, viewEnhancer : ViewEnhancer a b c
, menuViewEnhancer : MenuViewEnhancer a b c
}

Configuration Type used to extend the UI Explorer appearance and behaviour.

type alias CustomHeader b =
{ title : String
, logo : Logo b
, titleColor : Maybe String
, bgColor : Maybe String
}

Use this type to customize the appearance of the header

config =
    { defaultConfig
        | customHeader =
            Just
                { title = "This is my Design System"
                , logo = UIExplorer.logoFromUrl "/some-fancy-logo.png"
                , titleColor = Just "#FF6E00"
                , bgColor = Just "#FFFFFF"
                }
    }
type alias ViewEnhancer a b c =
Model a b c -> Html (Msg b) -> Html (Msg b)

Gives a chance to Plugins to add features to the main view canvas. For example, the Notes plugin allows to add markdown notes for each stories:

main : UIExplorerProgram {} () PluginOption
main =
    explore
        { defaultConfig | viewEnhancer = ExplorerNotesPlugin.viewEnhancer }
        [ storiesOf
            "Button"
            [ ( "Primary", \_ -> Button.view "Submit" defaultButtonConfig (), {notes: "This is the primary style :-)"} )
            , ( "Secondary", \_ -> Button.view "Submit" { defaultButtonConfig | appearance = Secondary } (), {notes: "This is the secondary style"} )
        ]
getCurrentSelectedStory : Model a b c -> Maybe (Story a b c)

Get the Current Selected Story. Usefull to retrieve the current selected story. It can be used with MenuViewEnhancer or ViewEnhancer to hide/display contextual content.

Helpers

String
-> List (UI a b c)
-> List (UICategory a b c)
-> List (UICategory a b c)

Adds a UI Category to a list of categories. Convenient for running a UI Explorer devided into categories

   createCategories
        |> category "A Great Category"
            [ storiesOf
                "GreatUI"
                [ ( "SomeState", \_ -> GreatUI.view , {} ) ]
            ]
storiesOf : String -> Stories a b c -> UI a b c

Create a UI given an ID and stories

storiesOf
    "GreatUI"
    [ ( "Default", \_ -> GreatUI.view, {} )
    , ( "Loading", \_ -> GreatUI.viewLoading, {} )
    , ( "Failure", \_ -> GreatUI.viewFailure, {} )
    ]

Creates an empty list of UI Categories

logoFromHtml : Html (Msg b) -> Logo b

Create a logo from a html element

Use this function to set the logo in the CustomHeader

logoFromUrl : String -> Logo b

Create a logo from a string

Use this function to set the logo in the CustomHeader