Honeycomb

theme-wrapper

Props

Prop nameTypeDefaultDescription
theme"flix" | "kamil" | "neptune" | "high-contrast" | undefinedflix

The current theme name.

themesThemeWithTokens[] | undefined[themeFlix]

Array of themes with tokens. "Flix" theme is included by default. Theme are exported as `theme` from Honeycomb React. E.g.: `themeFlix`, `themeKamil`, `themeNeptune`, `themeHighContrast`.

darkboolean | "user-preference" | undefinedfalse

Enables dark mode.

since v. 16.0.0
tvmboolean | undefinedfalse

Enables tvm mode.

since v. 16.0.0
applyToRootboolean | undefinedfalse

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>