uncover-co/elm-theme-provider/1.0.1

NOTE: the latest version is 2.0.0

ThemeProvider

Creating a Theme

Before using a Theme you need to create one! Thankfully it is really easy to do so:

fromList : String -> List ( String, String ) -> Theme

Creates a theme based on a namespace and a list of CSS variables names and their values.

lightTheme : Theme
lightTheme =
    Theme.fromList "my-theme"
        [ ( "background", "white"
        , ( "base", "black" )
        , ( "accent", "blue" )
        ]

A Theme is just a set of scoped CSS variables so the namespace attribute can be used to avoid name-clashing with other variables already in scope.

type Theme

Propagating Themes

After creating one or more themes, you can use them in a few different ways.

globalProvider : Theme -> Html msg

Used to provide a Theme globally. It will be applied to your body element and it will be available for use anywhere in your application.

main : Html msg
main =
    div []
        [ ThemeProvider.globalProvider lightTheme
        , p [ style "color" "var(--my-theme-accent)" ]
            [ text "I have the `accent` color" ]
        ]

Note: You are still able to overwrite this Theme locally.

Now… say you have a marketing website and each section of your website can use one of a number of available themes. It would be really useful to create things using CSS variables and then just apply the theme you want when you want, right?

provider : Theme -> List (Attribute msg) -> List (Html msg) -> Html msg

Used to propagate themes to an specific scope.

main : Html msg
main =
    div []
        [ ThemeProvider.globalProvider defaultTheme


        -- section using the default theme
        , section [] [ .. ]


        -- section using the orange theme
        , ThemeProvider.provider orangeTheme [] [ .. ]
        ]

Themes and Dark Mode

You can also use two similar functions as the ones above for specifying themes that automatically switch to a dark mode based on a defined strategy. The first thing to do then is decide which dark mode strategy will be the right one for your use case:

= SystemStrategy
| ClassStrategy String

Defines the dark mode strategy.

  • SystemStrategy uses the user system settings.
  • ClassStrategy uses the presence of a CSS class to determine dark mode.
{ light : Theme
, dark : Theme
, strategy : DarkModeStrategy
}
-> Html msg

Used to provide a Theme globally with a dark mode alternative. Themes will automatically switch based on the strategy condition.

main : Html msg
main =
    div []
        [ ThemeProvider.globalProviderWithDarkMode
            { light = lightTheme
            , dark = darkTheme
            , strategy = ThemeProvider.SystemStrategy
            }
        , p [ style "color" "var(--my-theme-accent)" ]
            [ text "I have the `accent` color" ]
        ]

Note: You are still able to overwrite this Theme locally.

{ light : Theme
, dark : Theme
, strategy : DarkModeStrategy
}
-> List (Attribute msg)
-> List (Html msg)
-> Html msg

Used to propagate themes to an specific scope with a dark mode alternative. Themes will automatically switch based on the strategy condition.

main : Html msg
main =
    div []
        [ ThemeProvider.globalProviderWithDarkMode
            { light = lightTheme
            , dark = darkTheme
            , strategy = ThemeProvider.SystemStrategy
            }


        -- section using the default light or dark theme
        , section [] [ .. ]


        -- section using the orange light and dark themes
        , ThemeProvider.providerWithDarkMode
            { light = lightOrange
            , dark = darkOrange
            , strategy = ThemeProvider.SystemStrategy
            }
            [] [ .. ]
        ]