Skip to main content

useTheme

useTheme is a hook that reads and changes themes and color modes, such as switching brands or adding a dark-mode toggle.

Import

import { useTheme } from '@vortexlabs/vortex';

Other links

Current theme: vortexdocs
Root theme: vortexdocs
Color mode: dark
"use client";

import { Stack, Text, useTheme } from "@vortexlabs/vortex";

export const ThemeStatus = () => {
  const { theme, rootTheme, colorMode } = useTheme();
  const showName = (value: string | string[]) =>
    Array.isArray(value) ? value.join(", ") : value;

  return (
    <Stack gap={2}>
      <Text>Current theme: {showName(theme)}</Text>
      <Text>Root theme: {showName(rootTheme)}</Text>
      <Text>Color mode: {colorMode}</Text>
    </Stack>
  );
};

Features

  • Reads the nearest theme and color mode.
  • Selects a theme locally or at the root.
  • Sets or toggles the provider’s color mode.

Call useTheme() inside VortexProvider. It takes no arguments; theme and colorMode describe the nearest scope, while rootTheme identifies its root theme.

Changing Color Mode

Call setColorMode with light or dark, or pass invertColorMode directly to a button. This example uses a scoped provider so its controls change only the preview.

Color mode: light
"use client";

import { Button, Stack, Text, VortexProvider, useTheme } from "@vortexlabs/vortex";

const ModeActions = () => {
  const { colorMode, setColorMode, invertColorMode } = useTheme();

  return (
    <Stack gap={3} padding={4} backgroundColor="surface" borderRadius="sm">
      <Text>Color mode: {colorMode}</Text>
      <Stack direction="row" gap={2} wrap>
        <Button variant="secondary" onClick={() => setColorMode("light")}>
          Light
        </Button>
        <Button variant="secondary" onClick={() => setColorMode("dark")}>
          Dark
        </Button>
        <Button onClick={invertColorMode}>Toggle mode</Button>
      </Stack>
    </Stack>
  );
};

export const ColorModeControls = () => {
  const { theme } = useTheme();

  return (
    <VortexProvider theme={theme} defaultColorMode="light" scoped>
      <ModeActions />
    </VortexProvider>
  );
};

Selecting a Theme

Load theme CSS before calling setTheme. Use defaultName for a scope whose theme the hook can change.

Selected theme: vortex
"use client";

import { Button, Stack, Text, ThemeScope, useTheme } from "@vortexlabs/vortex";
import "@vortexlabs/vortex-themes/themes/vortex/theme.css";
import "@vortexlabs/vortex-themes/themes/awen/theme.css";
import "@vortexlabs/vortex-themes/themes/sleek/theme.css";

const ThemeOptions = () => {
  const { theme, setTheme } = useTheme();

  return (
    <Stack gap={3} padding={4} backgroundColor="surface" borderRadius="sm">
      <Text>Selected theme: {Array.isArray(theme) ? theme.join(", ") : theme}</Text>
      <Stack direction="row" gap={2} wrap>
        <Button onClick={() => setTheme("vortex")}>Vortex</Button>
        <Button onClick={() => setTheme("awen")}>Awen</Button>
        <Button onClick={() => setTheme("sleek")}>Sleek</Button>
      </Stack>
    </Stack>
  );
};

export const ThemeSelection = () => {
  return (
    <ThemeScope defaultName="vortex">
      <ThemeOptions />
    </ThemeScope>
  );
};

Use setRootTheme to change the root theme. Controlled name or theme props take precedence; update them in their owner.

Controlled Color Mode

To manage color mode in your own state, pass colorMode and onColorModeChange. This example reuses ModeActions from above.

"use client";

import React from "react";
import { VortexProvider, useTheme } from "@vortexlabs/vortex";

export const ControlledColorMode = () => {
  const [colorMode, setColorMode] = React.useState<"light" | "dark">("light");
  const { theme } = useTheme();

  return (
    <VortexProvider
      theme={theme}
      colorMode={colorMode}
      onColorModeChange={setColorMode}
      scoped
    >
      <ModeActions />
    </VortexProvider>
  );
};

Color-mode actions target the provider. A ThemeScope with colorMode="dark" stays dark even when the provider changes.

Save theme preferences in your app if they should persist.