Before using a Theme you need to create one! Thankfully it is really easy to do so:
fromList : List ( String, String ) -> Theme
Creates a theme based on a list of CSS variables names and their values.
lightTheme : Theme
lightTheme =
Theme.fromList
[ ( "background", "white"
, ( "base", "black" )
, ( "accent", "blue" )
]
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.
provider : Theme -> List (Html.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 [] [ .. ]
]
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:
Defines the dark mode strategy.
SystemStrategy
uses the user system settings.ClassStrategy
uses the presence of a CSS class to determine dark mode.globalProviderWithDarkMode : { 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.
providerWithDarkMode : { light : Theme, dark : Theme, strategy : DarkModeStrategy } -> List (Html.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
}
[] [ .. ]
]
If you're heavily using theme providers across your application, you're probably reusing the same themes over and over.
For those scenarios, otimized themes can be used to decouple the styles from the provider element so styles are only inserted once, even if the provider is being used at various locations.
optimizedTheme : Theme -> OptimizedTheme msg
optimizedTheme =
optimizedTheme theme
body []
[ myTheme.styles
, myTheme.provider []
[ ... ]
]
optimizedThemeWithDarkMode : { light : Theme, dark : Theme, strategy : DarkModeStrategy } -> OptimizedTheme msg
{ styles : Html msg
, provider : List (Html.Attribute msg) -> List (Html msg) -> Html msg
}