theme-wrapper
Props
| Prop name | Type | Default | Description |
|---|---|---|---|
theme | "flix" | "kamil" | "neptune" | "high-contrast" | undefined | flix | The current theme name. |
themes | ThemeWithTokens[] | undefined | [themeFlix] | Array of themes with tokens. "Flix" theme is included by default.
Theme are exported as `theme |
dark | boolean | "user-preference" | undefined | false | Enables dark mode. since v. 16.0.0 |
tvm | boolean | undefined | false | Enables tvm mode. since v. 16.0.0 |
applyToRoot | boolean | undefined | false | Applies theme CSS classes to the root (``) element and makes it the main theme provider on the page. This is required if you need to use "tvm" or other scaled themes, that change the base font sizes on the page. Only use this if your project doesn't require nested ThemeWrappers. since v. 11.2.0 |
onUserPreferenceDarkModeChange | ((isDark: boolean) => void) | undefined | Callback function that is called in user-preference mode to notify about "actual" mode changes since v. 16.0.0 |
ThemeWrapper component makes it possible to apply one of themes Honeycomb has on board to your
components or apps. As the best practice we recommend wrapping the whole application with this
component.
Please refer to MainWrapper docs for code examples and usage in context with other layout components.
Theme files
Honeycomb exports theme files that contain the theme name and a collection of design tokens associated to that respective theme.
They are available for import in a same fashion as components:
import { themeFlix, themeKamil, themeNeptune, themeHighContrast } from '@flixbus/honeycomb-react';
The theme files can be passed to the ThemeWrapper via themes prop in an array:
const themesForMyApp = [themeFlix, themeKamil, themeNeptune]; <ThemeWrapper themes={themesForMyApp}>
Themes
The "Flix" theme is included by default, so if you don't pass any props you will get Flix theme:
import { Header, HeaderBrand, Box, Button, Text, ThemeWrapper } from '@flixbus/honeycomb-react'; <ThemeWrapper> <Header brand={( <HeaderBrand alt="Honeycomb logo" href="https://styleguide.hive.flix.tech/" src="https://honeycomb.flixbus.com/dist/13.4.1/img/logos/svg/honeycomb-white.svg" appearance="square" width="36" height="36" /> )} /> <Box> <Text> Hi, I'm your Flix theme wrapper! </Text> <Button appearance="primary">Click me!</Button> </Box> </ThemeWrapper>
You can apply different themes provided on the themes prop by changing the theme name.
The themes need to be included once, and you can use multiple ThemeWrappers to create sections
using different themes inside of the app.
For example:
import { ThemeWrapper, Grid, GridCol, Header, HeaderBrand, Box, Text, Button, themeFlix, themeNeptune } from '@flixbus/honeycomb-react'; <ThemeWrapper theme="flix" themes={[themeFlix, themeNeptune]}> <Header brand={( <HeaderBrand alt="Flix logo" href="/" src="https://honeycomb-assets.hive.flixbus.com/honeycomb-logos-static/1.0.2/svg/flix-white.svg" appearance="tall" width="107" height="36" /> )} /> <Box> <Text>This is a Flix app with lots of Flix related components.</Text> <Button appearance="primary">Call to action!</Button> </Box> <Grid> <GridCol> <ThemeWrapper theme="neptune"> <Box> <Text>This box is for Neptune things.</Text> <Button appearance="primary">Call to action!</Button> </Box> </ThemeWrapper> </GridCol> <GridCol> <ThemeWrapper dark> <Box> <Text>This box uses dark colors for dramatic effect.</Text> <Button appearance="primary">Call to action!</Button> </Box> </ThemeWrapper> </GridCol> </Grid> </ThemeWrapper>
Dark mode
The dark mode is available for Flix, Kamil and Neptune themes.
import { Header, HeaderBrand, Box, Button, Text, ThemeWrapper, themeKamil } from '@flixbus/honeycomb-react'; <ThemeWrapper theme="kamil" dark themes={[ themeKamil ]}> <Header brand={( <HeaderBrand alt="Honeycomb logo" href="https://styleguide.hive.flix.tech/" src="https://honeycomb.flixbus.com/dist/13.4.1/img/logos/svg/honeycomb-white.svg" appearance="square" width="36" height="36" /> )} /> <Box> <Text> I like "Kamil" theme colors </Text> <Button appearance="primary">Click me!</Button> </Box> </ThemeWrapper>
The dark mode also accepts user-preference value, which will detect if the user prefers dark color
scheme by matching the media query: (prefers-color-scheme: dark).
If you need your application to respond to mode changes when user-preference setting is used, we provide a handy callback onUserPreferenceDarkModeChange that receives a boolean isDark param as an input.
When user-preference setting is used, the callback is being invoked every time ThemeWrapper re-renders, as well as when the matching media query changes.
Tip: You can emulate the browser color scheme preference on the DevTools "Rendering" tool.
import { Blockquote, Box, Grid, GridCol, Header, HeaderBrand, IconFrame, SelectGroup, Text, ThemeWrapper } from '@flixbus/honeycomb-react'; import { IconSun, IconNight } from '@flixbus/honeycomb-icons-react'; // Stores color scheme setting const [colorSchemeSetting, setColorSchemeSetting] = React.useState('user-preference'); // Stores the actual color scheme applied, even when "user-preference" setting is used const [colorScheme, setColorScheme] = React.useState('light'); // Synchronizes color scheme setting with the color scheme applied to the page React.useEffect(() => { if (colorSchemeSetting !== 'user-preference') { setColorScheme(colorSchemeSetting); } }, [colorSchemeSetting]) const options = [ { value: 'user-preference', label: 'System settings' }, { value: 'light', label: 'Light' }, { value: 'dark', label: 'Dark' }, ]; const darkValue = () => { switch (colorSchemeSetting) { case 'light': return false; case 'dark': return true; default: return 'user-preference'; } } <ThemeWrapper dark={darkValue()} onUserPreferenceDarkModeChange={(isDark) => setColorScheme((isDark) ? 'dark' : 'light')} > <Header brand={( <HeaderBrand alt="Honeycomb logo" href="https://styleguide.hive.flix.tech/" src="https://honeycomb.flixbus.com/dist/13.4.1/img/logos/svg/honeycomb-white.svg" appearance="square" width="36" height="36" /> )}/> <Box> <SelectGroup label="Select color scheme" options={options.map(({ value, label }) => ({ id: value, name: 'color-scheme', checked: colorSchemeSetting === value, value, label, onChange: (event) => { setColorSchemeSetting(event.target.value) } }))} id="color-scheme" /> </Box> <Box> <Grid align="center"> <GridCol> <Blockquote> {(colorScheme === 'dark') ? 'Darkness is my muse, and I am its vessel.' : 'However vast the darkness, we must supply our own light.'} </Blockquote> <Text small>{(colorScheme === 'dark') ? 'King Diamond' : 'Stanley Kubrick'}</Text> </GridCol> <GridCol inline> <IconFrame InlineIcon={(colorScheme === 'dark') ? IconNight : IconSun} title="Image of the Sun or the Moon" appearance="dimmed" /> </GridCol> </Grid> </Box> </ThemeWrapper>
TVM mode
The tvm mode is available for Flix, Kamil and Neptune themes.
When using TVM mode you should also use applyToRoot prop to add the theme class names to the HTML
element, this ensures the relative font sizes to work correctly based on the body font size.
Note: We did not use applyToRoot in this example because it would mess up with the documentation window as it is not contained to the component only.
import { Header, HeaderBrand, Box, Button, Text, ThemeWrapper, themeFlix } from '@flixbus/honeycomb-react'; <ThemeWrapper theme="flix" tvm themes={[themeFlix]}> <Header brand={( <HeaderBrand alt="Honeycomb logo" href="https://styleguide.hive.flix.tech/" src="https://honeycomb.flixbus.com/dist/13.4.1/img/logos/svg/honeycomb-white.svg" appearance="square" width="36" height="36" /> )} /> <Box> <Text> Themes for TVMs. </Text> <Button appearance="primary">Click me!</Button> </Box> </ThemeWrapper>