Skip to content
Vy logo
Guides

How to add color mode

A guide to add color mode to your application using the SporProvider and other hooks and components.

Changing Color Mode

To manage color mode in your app, Spor exports Chakra UI's useColorMode and useColorModeValue hooks.

useColorMode

To get the current color mode and to toggle the color mode, you can use the React hook useColorMode.

import { useColorMode } from '@vygruppen/spor-react'
() => {
  const { colorMode, toggleColorMode } = useColorMode()
  return (
    <Box>
      <Button onClick={toggleColorMode}>
        Change to {colorMode === 'light' ? 'dark' : 'light'}
      </Button>
    </Box>
  )
}

useColorModeValue

useColorModeValue will change any color depending on the color mode that is active. It takes in 2 arguments: light color value, and dark color value.

import { useColorModeValue } from '@vygruppen/spor-react'
const colorValues = useColorModeValue(lightValue, darkValue)

Example of usage together

() => {
  const { toggleColorMode } = useColorMode()
  const bg = useColorModeValue('brand.surface.default.light', 'brand.surface.default.dark')
  const color = useColorModeValue('text.inverted.light', 'text.inverted.dark')
  return (
    <>
      <Box marginBottom={4} padding={3} borderRadius="md" bg={bg} color={color}>
        This Box will change style based on the color mode.
      </Box>
      <Box>
        <Button onClick={toggleColorMode}>
          Toggle Color Mode
        </Button>
      </Box>
    </>
  )
}

Using the color tokens, the colors will update depending on what color mode is active in your app.

Forcing a specific mode

In some cases, you might want to force a specific color mode. For example if the component has the same style in both modes, and you don't want to add extra styling to support this.

For this occasion, you can wrap your component in either LightMode or DarkMode. These will override the global settings of the active color mode.

import { LightMode, DarkMode } from '@vygruppen/spor-react'

Example of usage

In this example, we will use the Tabs component to show how the component does not update it's color after the color mode has changed.

() => {
  const { toggleColorMode, colorMode } = useColorMode()
  return (
    <Stack gap={3}>
      <LightMode>
        <Tabs variant="accent" isFitted={true}>
          <TabList>
            <Tab>This</Tab>
            <Tab>will not</Tab>
            <Tab>change</Tab>
          </TabList>
        </Tabs>
      </LightMode>
      <DarkMode>
        <Tabs variant="accent" isFitted={true}>
          <TabList>
            <Tab>This</Tab>
            <Tab>will not</Tab>
            <Tab>change</Tab>
          </TabList>
        </Tabs>
      </DarkMode>
      
      <Box>
        <Button onClick={toggleColorMode}>
          Toggle Color Mode
        </Button>
      </Box>
    </Stack>
  )
}

Adding useColorModeManager (optional, for SSR)

For server-side rendered applications, such as those built with Next.js or Remix, it can be helpful to determine a user's color preference upfront. This avoids rendering the default color mode initially and then switching it during hydration, which can cause a noticeable flash.

If you're not using SSR or don't prioritize this, there's no need to take additional steps. By default, Chakra UI uses the localStorageManager.

Follow the steps and implementation from Chakra's documentation. Remember to swap out ChakraProvider with SporProvider.