Skip to content
lab components / Context

Fancy Themes

This guide will show you how to use Fancy Themes.

This is a Lab component!

That means it doesn't satisfy our definition of done and may be changed or even deleted. For an exact status, please reach out to the Fancy team through the dev_fancy or ux_fancy channels.

import { ThemeProvider } from "@siteimprove/fancylab";

#Examples

Themes serve as a powerful tool to transform the appearance and experience of components within an application. They are implemented through the use of the ThemeProvider component. Each theme distinguishes itself by configuring a unique set of values for our design tokens, altering the visual characteristics of components. To explore all the available design tokens, refer to the Design Tokens page.

For a component to be adaptable to various themes, it needs to rely on design tokens dynamically rather than static values. This implies that the component's CSS should be crafted to allow for theming by utilizing var(--design-token-name) declarations, which is known as "CSS custom properties" or "CSS variables". Consider the following example, showcasing how a component's CSS might be structured:

.box { background-color: var(--color--background--static--secondary); border: 1px solid var(--color--border--separator); color: var(--color--text--static--body); }

The ThemeProvider supplies the values for these design tokens, thereby influencing the appearance of components. In cases where no specific theme is provided, the system resorts to using the default theme.

Default Theme
Dark Theme
const boxStyle = { width: "200px", height: "100px", display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "var(--color--background--static--secondary)", border: "1px solid var(--color--border--separator)", color: "var(--color--text--static--body)", }; return ( <Content flexDirection="row" gap="medium"> <ThemeProvider theme="default"> <div style={boxStyle}>Default Theme</div> </ThemeProvider> <ThemeProvider theme="dark"> <div style={boxStyle}>Dark Theme</div> </ThemeProvider> </Content> );

Note: The ThemeProvider component must be placed at the root of your application to ensure that all components have access to the active theme. The associated stylesheets of each theme are automatically injected into the document by the global.css file (see Fancy Context page). However, if our global CSS file introduces conflicts with your existing styles, you can import only the themes.css file, which contains the design-tokens styles for all themes.

@import "@siteimprove/fancylib/themes.css";

Alternativelly, you can manually import the associated stylesheet for each theme, as shown below:

@import "@siteimprove/fancylib/design-tokens/themes/default.css"; @import "@siteimprove/fancylib/design-tokens/themes/dark.css";

#Accessing the active theme

You can also use the useTheme hook to access the current theme in your components. This is useful if you want to conditionally render components based on the active theme.

Default Theme
Dark Theme
const ThemedContent = () => { const activeTheme = useTheme(); return <div>{activeTheme === "dark" ? "Dark Theme" : "Default Theme"}</div>; }; return ( <> <ThemeProvider theme="default"> <ThemedContent /> </ThemeProvider> <ThemeProvider theme="dark"> <ThemedContent /> </ThemeProvider> </> );

#Using design tokens programmatically

You can use the useDesignTokens hook to access the current theme's design tokens. This is useful if you want to use the design tokens in your own components keeping your components in sync with the theme.

Default Theme
Dark Theme
const ThemedText = ({ children }: { children: React.ReactNode }) => { const { ColorTextStaticBody } = useDesignToken(); return <span style={{ color: ColorTextStaticBody }}>{children}</span>; }; return ( <> <ThemeProvider theme="default"> <ThemedText>Default Theme</ThemedText> </ThemeProvider> <ThemeProvider theme="dark"> <ThemedText>Dark Theme</ThemedText> </ThemeProvider> </> );