Skip to main content

useTheme()

import { type ThemeI, useTheme } from '@dr.pogodin/react-themes';

function useTheme<
ComponentTheme extends ThemeI,
DefaultTheme extends ComponentTheme = ComponentTheme,
>(
componentName: string,
defaultTheme?: DefaultTheme,
adHocTheme?: ComponentTheme,
options?: UseThemeOptions,
): ComponentTheme;

// Where UseThemeOptionsT is

type UseThemeOptions = {
composeAdhocTheme?: COMPOSE;
composeContextTheme?: COMPOSE;
themePriority?: PRIORITY;

// For backward compatibility with plain JavaScript code,
// not intended for TypeScript use case.
adhocTag?: 'ad.hoc';
contextTag?: 'context';
};

The useTheme() hook composes provided ad hoc, default, and context themes for the component of given name, and returns the resulting composed theme. It replaces the old way to write themeable components using now deprecated themed() function.

Migration from themed() to useTheme()

Consider this basic example of a themeable component written the old way, using themed() function.

import type { FunctionComponent, ReactNode } from 'react';

import themed, { type Theme } from '@dr.pogodin/react-themes';

import defaultTheme from './default.module.scss';

type PropsT = {
children?: ReactNode;
theme: Theme<'component'>;
};

const BasicExample: FunctionComponent<PropsT>
= ({ children, theme }) => <div className={theme.component}>{children}</div>;

export default themed(BasicExample, 'BasicExample', defaultTheme);

It is straightforward to rewrite it using the new useTheme() hook:

import type { FunctionComponent, ReactNode } from 'react';

import { type Theme, useTheme } from '@dr.pogodin/react-themes';

import defaultTheme from './default.module.scss';

type PropsT = {
children?: ReactNode;

// This prop now corresponds to the ad hoc theme of the themed component.
theme?: Theme<'component'>;
};

// NOTE: In the old code BasicExample was the base component, which was wrapped
// by themed() function to become themeable; with the new approach BasicExample
// itself is the themeable component, which internally uses useTheme() hook
// to compose the ad hoc theme (if any) it gets via props, with the context
// (retrieved from the context by its name passed into the hook) and default
// themes.
const BasicExample: FunctionComponent<PropsT> = ({ children, theme }) => {
const composed = useTheme('BasicExample', defaultTheme, theme);

<div className={composed.component}>{children}</div>;
};

export default BasicExample;

If you use custom theme composition and priority props on instances of your themed component — just add corresponding props to the component, and pass them down the useTheme() hook.

Generic Parameter

  • ComponentTheme — extends ThemeI — Valid theme type, use Theme generic to create one from the union of valid theme key names.

  • DefaultTheme — extends, and defaults ComponentTheme — The type of defaultTheme (it is expected to be auto-deduced by TypeScript).

Arguments

  • componentNamestring — Component name, it use used to retrieve the component's context theme from the parent ThemeProvider.

  • defaultThemeDefaultTheme | undefined — Optional. Default theme for the component.

  • adHocThemeComponentTheme | undefined — Optional. Ad hoc theme for the component.

  • options — Optional. An object with additional settings:

    • composeAdhocThemeCOMPOSE | undefined — Optional. Composition mode for the ad hoc theme. Defaults COMPOSE.DEEP.

    • composeContextThemeCOMPOSE | undefined — Optional. Composition mode for the context theme. Defaults COMPOSE.DEEP.

    • themePriorityPRIORITY | undefined — Optional. Priority of context and default themes. Defaults PRIORITY.ADHOC_CONTEXT_DEFAULT.

    note

    The following two options are inherited from the original JavaScript implementation; they still work, but they do not fit well with TypeScript restrictions, thus, at least for now, we assume they are always set to their default values.

    • .adhocTag"ad.hoc" — Overrides "ad.hoc" theme key. Defaults "ad.hoc".

    • .contextTag"context" — Overrides context theme key. Defaults "context".

Result

useTheme() returns ComponentTheme — the composed theme.