For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/en/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/en/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/v/0.6.0/en/guide/theming.md.
  • English
  • Theming

    Set colors, corner radii and dark mode through ConfigProvider's theme. A few settings are usually enough; related styles update automatically.

    Change colors and corners

    Wrap your application in ConfigProvider. This example uses a purple primary color and an 8px base radius:

    basic.tsx
    import { Button, ConfigProvider } from '@ifhover/leaf-ui';
    
    export function ThemeBasic() {
      return (
        <ConfigProvider theme={{ primaryColor: '#7654c6', borderRadius: 8 }}>
          <Button>Save changes</Button>
        </ConfigProvider>
      );
    }
    

    Replace Button with your application content. Buttons, fields, selectors and popups share the theme. Hover, pressed and focus colors derive automatically.

    borderRadius sets the base radius. Cards, dialogs and other surfaces derive radii for their own level, so you do not need to configure each component. Numbers represent pixels; CSS lengths such as '0.5rem' also work.

    Common settings

    These fields all belong inside theme. Set only what you want to change.

    SettingExamplePurpose
    primaryColor'#7654c6'Set the primary color and derive related interaction colors.
    borderRadius8Set the base radius; use 0 for square corners.
    appearance'light' / 'dark'Choose light or dark appearance.
    controlHeight40Set the base single-line control height; small and large sizes follow.
    fontSize14Set the base component font size.
    fontFamily'Inter, sans-serif'Set the font family; your application loads the font files.
    motionfalseDisable regional animations while keeping interactions available.

    Unspecified fields inherit the outer configuration. Defaults are light appearance, a 10px base radius, 36px base control height and 14px font size.

    See LeafTheme for all theme fields. For individual text colors, backgrounds or sizes, use LeafThemeTokens.

    Use dark mode

    Set appearance: 'dark'. Use 'light' to switch back:

    <ConfigProvider theme={{ appearance: 'dark' }}>
      <App />
    </ConfigProvider>

    Component text, backgrounds and borders change together. An explicit primaryColor keeps its value; otherwise, the appearance supplies its default primary color.

    ConfigProvider styles the components in its region. It does not add a background to the page's body. To update your own page backgrounds and text, use the CSS variables below.

    Add an appearance switch

    Theme settings are ordinary React props, so state can update them. Toggle the switch below to change the card, button and text together:

    appearance.tsx
    import { Button, Card, ConfigProvider, Flex, Switch } from '@ifhover/leaf-ui';
    
    import { useState } from 'react';
    
    export function ThemeAppearance() {
      const [dark, setDark] = useState(false);
    
      return (
        <ConfigProvider theme={{ appearance: dark ? 'dark' : 'light' }}>
          <Card>
            <Flex direction="column" gap="md" align="start">
              <Switch checked={dark} onChange={(event) => setDark(event.target.checked)}>
                Dark mode
              </Switch>
              <Button>Save changes</Button>
            </Flex>
          </Card>
        </ConfigProvider>
      );
    }
    

    Follow the system

    Use useSystemAppearance and pass its result to theme.appearance to follow the operating system:

    import { ConfigProvider, useSystemAppearance } from '@ifhover/leaf-ui';
    
    export function AppTheme() {
      const appearance = useSystemAppearance('light');
    
      return (
        <ConfigProvider theme={{ appearance }}>
          <App />
        </ConfigProvider>
      );
    }

    The 'light' argument is the initial appearance. After mounting, the hook reads and watches system preferences. Your application stores manual choices and decides when to keep following the system.

    Theme one region

    Nest another ConfigProvider to theme a specific area. The inner provider overrides only the supplied fields and inherits the rest:

    scoped.tsx
    import { Button, ConfigProvider, Flex } from '@ifhover/leaf-ui';
    
    export function ThemeScoped() {
      return (
        <ConfigProvider theme={{ primaryColor: '#1677ff', borderRadius: 8 }}>
          <Flex direction="column" gap="md" align="start">
            <Button>Global blue</Button>
            <ConfigProvider theme={{ primaryColor: '#7654c6' }}>
              <Button>Local purple</Button>
            </ConfigProvider>
          </Flex>
        </ConfigProvider>
      );
    }
    

    Both buttons use an 8px base radius. The inner provider changes only the primary color to purple. Select popups, Modal, and feedback created with useConfirm or useMessage also use their calling region's theme.

    Adjust control size and density

    For one control, prefer its size="sm" or size="lg" prop. To make an entire region more compact, set ConfigProvider's density:

    <ConfigProvider density="compact">
      <App />
    </ConfigProvider>

    density is a sibling of theme. It defaults to 'comfortable'. The 'compact' preset tightens control, form and popup spacing and changes the base control height from 36px to 30px without reducing text size.

    Set theme.controlHeight when you need an explicit height; it overrides the density preset. For example, controlHeight: 40 produces 34px / 40px / 46px controls. See ConfigProvider for a size comparison.

    Advanced customization

    Use the settings below when your design needs more specific overrides. For colors, corners and appearance, the basic settings above are sufficient.

    Override individual colors or sizes

    Use theme.tokens for specific styles beyond the basic settings. This example adjusts the success color, large radius and animation duration:

    import type { LeafTheme } from '@ifhover/leaf-ui';
    
    const theme = {
      primaryColor: '#7654c6',
      borderRadius: 8,
      tokens: {
        successColor: '#20834a',
        borderRadiusLg: 18,
        motionDuration: 160,
      },
    } satisfies LeafTheme;

    Pass this object to <ConfigProvider theme={theme}>. Here, borderRadiusLg overrides the derived large radius, and numeric motionDuration values are milliseconds. See LeafThemeTokens for the complete reference.

    For a very light primary color, use tokens.onPrimaryColor to set the text color on solid primary buttons. Check readability in normal, hovered and disabled states after changing your palette. motion: false disables regional animations; system reduced-motion preferences always take precedence.

    Style one component type

    theme.components assigns styles by component name. For example, use 4px button corners and change card padding:

    <ConfigProvider theme={{
      components: {
        Button: { borderRadius: 4 },
        Card: { padding: 24 },
      },
    }}>
      <App />
    </ConfigProvider>

    See LeafComponentTokens for style fields, and each component's documentation for the fields it supports.

    theme.components changes styles. To set default button size, variant or other component props, use ConfigProvider's separate components prop; see Component defaults.

    Use the theme in application CSS

    ConfigProvider exposes --leaf-* CSS variables within its region. Your own content can read them to follow color and appearance changes:

    <ConfigProvider theme={{ appearance: 'dark' }}>
      <section className="app-panel">Application content</section>
    </ConfigProvider>
    .app-panel {
      padding: 16px;
      color: var(--leaf-color-text);
      background: var(--leaf-color-surface);
      border: 1px solid var(--leaf-color-border);
      border-radius: var(--leaf-radius);
    }
    Common variablePurpose
    --leaf-color-primaryCurrent primary color.
    --leaf-color-on-primaryText on a solid primary background.
    --leaf-color-text / --leaf-color-text-mutedPrimary and secondary text.
    --leaf-color-surface / --leaf-color-surface-mutedContent and supporting backgrounds.
    --leaf-color-borderBorder color.
    --leaf-radiusBase radius.

    Configure Leaf UI component themes through ConfigProvider and read the results from application CSS. Changing a single base CSS variable does not regenerate the full set of interaction colors.

    For Tailwind CSS, import the package configuration to reuse the theme through utilities such as bg-leaf-surface and text-leaf-primary. See Tailwind CSS for Tailwind 3 / 4 setup.

    Server rendering

    Use the same appearance for the server and the client's initial render. To remember a user's choice, read a cookie on the server and supply that initial value. System appearance updates after mounting.

    Prefer concrete HEX, RGB or HSL colors. A color such as var(--brand-color) resolves after mounting in the browser and cannot guarantee matching derived colors in the server's first frame.

    See Installation & quick start for setup, server-side rendering for frameworks such as Next.js, and Browser compatibility for support targets.