> Leaf UI 0.6.0 · Package: @ifhover/leaf-ui · Source: b30c3d3a8fa9c5e15d0d0522cebfbd33f60c6b06
> Browser documentation: https://ifhover.github.io/leaf-ui/v/0.6.0/en/components/config-provider.html

> 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.

# ConfigProvider

Set a shared theme, language and component defaults for an application or a local region.

Wrap the application to configure it globally, or nest providers to customize one region.

| Configure                                   | Prop                     |
| ------------------------------------------- | ------------------------ |
| Built-in text and custom languages          | `locale`, `translations` |
| Primary color, appearance, size and spacing | `theme`, `density`       |
| Shared component props                      | `components`             |

## Multilingual

`locale` changes built-in text in date panels, empty states and clear actions. Translate business headings, field labels and options in your application.

### Built-in languages

These translations are included without importing a language pack. The default is Simplified Chinese when `locale` is not configured.

| Language                   | `locale` |
| -------------------------- | -------- |
| 简体中文 (Simplified Chinese)  | `zh-CN`  |
| 繁體中文 (Traditional Chinese) | `zh-TW`  |
| English                    | `en-US`  |
| 日本語 (Japanese)             | `ja-JP`  |
| 한국어 (Korean)               | `ko-KR`  |

For another language, [provide translation resources](#add-your-own-language). A language tag alone does not translate built-in text. Missing entries ultimately fall back to English.

### Switch languages

Update `locale` to switch languages. Select a language from the dropdown, then open the date or empty-options control to compare built-in text in all five languages.


Date

Empty options

locale.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/locale.tsx"
import { ConfigProvider, DatePicker, Form, FormField, Select, Space } from '@ifhover/leaf-ui';

import { useState } from 'react';

export function ConfigProviderLocale() {
  const [locale, setLocale] = useState('en-US');
  return (
    <Space direction="vertical" align="stretch">
      <Select
        aria-label="Component language"
        value={locale}
        onChange={setLocale}
        options={[
          { value: 'zh-CN', label: '简体中文' },
          { value: 'zh-TW', label: '繁體中文' },
          { value: 'en-US', label: 'English' },
          { value: 'ja-JP', label: '日本語' },
          { value: 'ko-KR', label: '한국어' },
        ]}
      />
      <ConfigProvider locale={locale}>
        <Form>
          <FormField label="Date">
            <DatePicker />
          </FormField>
          <FormField label="Empty options">
            <Select options={[]} />
          </FormField>
        </Form>
      </ConfigProvider>
    </Space>
  );
}
```

Expand code

Nested regions inherit their parent language unless overridden. `direction` controls text direction; `weekStartsOn` sets the first day of the week. Popups inherit these settings too.

### Add your own language

Copy the [complete English JSON
](/leaf-ui/v/0.6.0/locales/en-US.json), translate it, and pass your imported file through `translations`
. Each key is a language tag. The JSON contains component groups and text only; do not repeat the language tag inside it. Partial resources are supported.
👽 A small Easter egg: this example uses [“Martian” text](https://en.wikipedia.org/wiki/Martian_language), a playful style of Chinese internet writing that mixes homophones, lookalike characters, and symbols.

Missing entries fall back to English. Application content such as field names and confirmation descriptions remains under your control.

It uses the private-use language tag `zh-CN-x-mars`, so dates and numbers retain Simplified Chinese regional formatting. This is a demonstration, not a built-in language.


Date

Empty options

共 24 條數據123

Open confirmation

translations.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/translations.tsx"
import { Button, ConfigProvider, DatePicker, Form, FormField, Pagination, Select, Space, useConfirm } from '@ifhover/leaf-ui';

import mars from '../../config-provider/zh-CN-x-mars.json';

const translations = { 'zh-CN-x-mars': mars };

function Controls() {
  const { confirm } = useConfirm();
  return (
    <Space direction="vertical" align="stretch">
      <Form>
        <FormField label="Date">
          <DatePicker />
        </FormField>
        <FormField label="Empty options">
          <Select options={[]} />
        </FormField>
      </Form>
      <Pagination total={24} showTotal />
      <Button
        variant="outline"
        onClick={() =>
          void confirm({
            title: 'Continue?',
            children:
              'Confirm and Cancel use Martian text. Missing translations fall back to English.',
          })
        }
      >
        Open confirmation
      </Button>
    </Space>
  );
}

export function ConfigProviderTranslations() {
  return (
    <ConfigProvider locale={['zh-CN-x-mars', 'en-US']} translations={translations}>
      <Controls />
    </ConfigProvider>
  );
}
```

Expand code

The imported `zh-CN-x-mars.json`:

```json file="../../../src/examples/config-provider/zh-CN-x-mars.json"
{
  "common": {
    "confirm": "確萣",
    "cancel": "筭ㄋ"
  },
  "select": {
    "placeholder": "挑①個唄",
    "empty": "暫蒔木洧選項"
  },
  "datePicker": {
    "placeholder": "選個ㄖ剘"
  },
  "pagination": {
    "total": "共 {total} 條數據"
  }
}

```

`locale={['zh-CN-x-mars', 'en-US']}` looks up each missing entry in order, with built-in English as the final fallback. The first tag always controls the current language and regional date and number formatting. A string equals a one-item array; empty arrays are invalid. No implicit `zh-CN-x-mars → zh-CN` or `fr-CA → fr` fallback is added.

Nested `translations` merge by language and entry. An omitted `locale` inherits the chain; an explicit value replaces it. Text supplied through component props or `components` takes precedence. See [Translation resources](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/translations.md) for types, JSON Schema and validation.

## Theme and appearance

### Regional themes

The theme applies to components and their popups. Usually a primary color or base radius is enough; related styles follow automatically.


Project name

Project type

Save settings

basic.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/basic.tsx"
import { Button, ConfigProvider, Form, FormField, Input, Select } from '@ifhover/leaf-ui';

export function ConfigProviderBasic() {
  return (
    <ConfigProvider theme={{ primaryColor: '#7654c6', borderRadius: 8 }}>
      <Form onSubmit={(event) => event.preventDefault()}>
        <FormField label="Project name">
          <Input defaultValue="Leaf UI" />
        </FormField>
        <FormField label="Project type">
          <Select
            defaultValue="website"
            options={[
              { value: 'website', label: 'Website' },
              { value: 'app', label: 'Application' },
            ]}
          />
        </FormField>
        <Button type="submit">Save settings</Button>
      </Form>
    </ConfigProvider>
  );
}
```

Expand code

### Regional density

`density="compact"` reduces control sizes and content spacing for information-heavy interfaces. The default is `comfortable`. Nested regions can choose their own density.


Comfortable

Project name

Owner

Reset

Compact

Project name

Owner

Reset

density.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/density.tsx"
import { Button, ConfigProvider, Form, FormField, Input, Select, Space, Text } from '@ifhover/leaf-ui';

export function ConfigProviderDensity() {
  return (
    <Space direction="vertical" align="stretch" size="lg">
      {(['comfortable', 'compact'] as const).map((density) => (
        <ConfigProvider key={density} density={density}>
          <Space direction="vertical" align="stretch">
            <Text tone="muted">{density === 'compact' ? 'Compact' : 'Comfortable'}</Text>
            <Form>
              <FormField label="Project name">
                <Input defaultValue="Leaf UI" />
              </FormField>
              <FormField label="Owner">
                <Select
                  options={[
                    { value: 'lin', label: 'Lin' },
                    { value: 'alex', label: 'Alex' },
                  ]}
                  defaultValue="lin"
                />
              </FormField>
              <Button type="reset" variant="outline">
                Reset
              </Button>
            </Form>
          </Space>
        </ConfigProvider>
      ))}
    </Space>
  );
}
```

Expand code

### Base height

Set `theme.controlHeight` to change the size baseline. Small and large controls derive their heights automatically, so individual buttons and inputs stay consistent.


Base height: 36px

SmallButton

DefaultButton

LargeButton

sizes.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/sizes.tsx"
import { Button, ConfigProvider, Form, FormField, Slider, Space, Text } from '@ifhover/leaf-ui';

import { useState } from 'react';

export function ConfigProviderSizes() {
  const [height, setHeight] = useState(36);
  return (
    <Space direction="vertical" align="stretch" size="lg">
      <Form>
        <FormField label={`Base height: ${height}px`}>
          <Slider min={28} max={44} value={height} onChange={setHeight} showValue={false} />
        </FormField>
      </Form>
      <ConfigProvider theme={{ controlHeight: height }}>
        <Space wrap align="end" size="lg">
          {(
            [
              ['sm', 'Small'],
              ['md', 'Default'],
              ['lg', 'Large'],
            ] as const
          ).map(([size, label]) => (
            <Space key={size} direction="vertical" size="sm">
              <Text tone="muted">{label}</Text>
              <Button size={size} variant="outline">
                Button
              </Button>
            </Space>
          ))}
        </Space>
      </ConfigProvider>
    </Space>
  );
}
```

Expand code

For further customization, see [Theming](https://ifhover.github.io/leaf-ui/v/0.6.0/en/guide/theming.md). `theme.components` changes local component styles; `components` below sets default component props. For server rendering, see [SSR](https://ifhover.github.io/leaf-ui/v/0.6.0/en/guide/ssr.md).

## Component defaults

**Set common props once instead of repeating them on every component.** Use `components` to share button styles, input hints and modal closing behavior. Change the configuration once when your conventions change.

Configure the app root to apply defaults throughout the app, or wrap a region to keep them local. Individual components can still override them with their own props.

### Consistent form defaults

This example shares placeholders, clear buttons and button styles. The end date and Save button override the shared defaults.


Project name

Start date

End date

ResetSave (instance override)

defaults.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/defaults.tsx"
import { Button, ConfigProvider, DatePicker, Form, FormField, Input, Space } from '@ifhover/leaf-ui';

export function ConfigProviderDefaults() {
  return (
    <ConfigProvider
      components={{
        Button: { variant: 'outline' },
        Input: { placeholder: 'Enter a project name', allowClear: true },
        DatePicker: { placeholder: 'Choose a project start date', allowClear: true },
      }}
    >
      <Form onSubmit={(event) => event.preventDefault()}>
        <FormField label="Project name">
          <Input />
        </FormField>
        <FormField label="Start date">
          <DatePicker />
        </FormField>
        <FormField label="End date">
          <DatePicker placeholder="Instance override: choose an end date" />
        </FormField>
        <Space wrap>
          <Button type="reset">Reset</Button>
          <Button type="submit" variant="solid">
            Save (instance override)
          </Button>
        </Space>
      </Form>
    </ConfigProvider>
  );
}
```

Expand code

### Prevent accidental dismissal from mask clicks

Keep an accidental mask click from interrupting an edit: set `Modal: { maskClosable: false }` once for every Modal in the region. The close button and Esc still work.


Open modal

modal-defaults.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/modal-defaults.tsx"
import { Button, ConfigProvider, Modal, Paragraph } from '@ifhover/leaf-ui';

import { useState } from 'react';

export function ConfigProviderModalDefaults() {
  const [open, setOpen] = useState(false);

  return (
    <ConfigProvider components={{ Modal: { maskClosable: false } }}>
      <Button onClick={() => setOpen(true)}>Open modal</Button>
      <Modal open={open} title="Mask clicks keep this open" onClose={() => setOpen(false)}>
        <Paragraph>
          Try clicking outside the modal. It stays open. The close button, footer actions and Esc
          still close it.
        </Paragraph>
      </Modal>
    </ConfigProvider>
  );
}
```

Expand code

### Inheritance and overrides

Shared defaults leave room for local changes: **instance props > inner configuration > outer configuration > built-in defaults**.


Outer scopeSmall · Outline

Inner size overrideLarge · Outline

Instance overrideDefault · Solid

inheritance.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/inheritance.tsx"
import { Button, ConfigProvider, Flex, Space, Text } from '@ifhover/leaf-ui';

export function ConfigProviderInheritance() {
  return (
    <ConfigProvider components={{ Button: { variant: 'outline', size: 'sm' } }}>
      <Space direction="vertical" align="stretch">
        <Flex justify="space-between" align="center" gap="md">
          <Text tone="muted">Outer scope</Text>
          <Button>Small · Outline</Button>
        </Flex>
        <ConfigProvider components={{ Button: { size: 'lg' } }}>
          <Space direction="vertical" align="stretch">
            <Flex justify="space-between" align="center" gap="md">
              <Text tone="muted">Inner size override</Text>
              <Button>Large · Outline</Button>
            </Flex>
            <Flex justify="space-between" align="center" gap="md">
              <Text tone="muted">Instance override</Text>
              <Button size="md" variant="solid">
                Default · Solid
              </Button>
            </Flex>
          </Space>
        </ConfigProvider>
      </Space>
    </ConfigProvider>
  );
}
```

Expand code

### Clearing inherited defaults

Set a component entry to `null` to restore its built-in defaults locally, for example `components={{ Input: null }}`.


Inherited defaults

Clear defaults in this region

reset.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/config-provider/reset.tsx"
import { ConfigProvider, Form, FormField, Input, type LeafComponentDefaults } from '@ifhover/leaf-ui';

const defaults = { Input: { readOnly: true } } satisfies LeafComponentDefaults;

export function ConfigProviderReset() {
  return (
    <ConfigProvider components={defaults}>
      <Form>
        <FormField label="Inherited defaults">
          <Input defaultValue="This input is read-only" />
        </FormField>
        <ConfigProvider components={{ Input: null }}>
          <FormField label="Clear defaults in this region">
            <Input defaultValue="Try editing this text" />
          </FormField>
        </ConfigProvider>
      </Form>
    </ConfigProvider>
  );
}
```

Expand code


Configuration keys, merging rules and usage advice

Use `LeafComponentDefaults` for type completion. See [the complete reference](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/component-defaults.md#leafcomponentdefaults) for configurable props.
- Keys match component names, such as `Input` and `Modal`. `Table.Cell` uses `TableCell`, and `Table.Root` uses `Table`. The aliases `FAB` and `ResizablePanels` use `FloatButton` and `Splitter`.
- Only `undefined` falls back to a default; `false`, `0`, empty strings and allowed `null` values are preserved. Objects, arrays, class names and callbacks are replaced as a whole.
- A `null` component entry clears inherited defaults; an empty object and `undefined` continue to inherit. Other components and the theme are unaffected.
- Keep instance data and events on the component, such as `Select.options`, `Modal.open` and `onChange`.
- Pass a new object when updating configuration; do not mutate the existing one.
- Configure internal actions through their owner, such as `Modal.confirmButtonProps`. They do not inherit shared `Button` defaults.

## API

### ConfigProvider API

| Property            | Type                                                                                                                                | Default         | Description                                                                                                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locale`            | `LeafLocale \| readonly LeafLocale[]`                                                                                               | `'zh-CN'`       | Current language and per-entry fallback order; inherited when omitted                                                                                                  |
| `translations`      | `Readonly<Record<string, `[`LeafTranslation`](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/translations.md#leaftranslation)`>>` | —               | JSON resources indexed by language tag; nested entries merge                                                                                                           |
| `theme`             | [`LeafTheme`](#leaftheme)                                                                                                           | —               | Regional settings; omitted fields inherit                                                                                                                              |
| `direction`         | `'ltr' \| 'rtl'`                                                                                                                    | —               | Text and interaction direction.                                                                                                                                        |
| `weekStartsOn`      | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6`                                                                                                   | —               | First day of the week; 0 is Sunday and 1 is Monday.                                                                                                                    |
| `getPopupContainer` | `() => Element \| DocumentFragment`                                                                                                 | —               | Return a popup container, including a ShadowRoot.                                                                                                                      |
| `maskBlur`          | `boolean`                                                                                                                           | `true`          | Enable mask blur for Modal, Drawer and Modal-based overlays such as confirmations and command palettes. Disable to reduce rendering cost; nested providers inherit it. |
| `density`           | `'comfortable' \| 'compact'`                                                                                                        | `'comfortable'` | Inherited controls, forms, menus, lists and overlay spacing; explicit sizes override the preset.                                                                       |
| `components`        | [`LeafComponentDefaults`](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/component-defaults.md#leafcomponentdefaults)             | —               | Regional component defaults, inherited by component and prop.                                                                                                          |

Native div props, `className` and `style` apply to the region wrapper. `maskBlur={false}` disables backdrop blur while preserving the translucent mask; this is independent of `theme.motion`.

### LeafTheme

Common theme options. Unspecified fields inherit from the outer region.

| Property        | Type                                                                                                                              | Default           | Description                                                                                                  |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------ |
| `primaryColor`  | `string`                                                                                                                          | `'#20834a'`       | Primary color with derived interaction states; dark appearance defaults to a lighter green                   |
| `borderRadius`  | `number \| string`                                                                                                                | `10`              | Base radius; small / medium / large radii use × 0.6 / 1.2 / 1.6                                              |
| `controlHeight` | `number \| string`                                                                                                                | `36`              | Base height; small / large heights use − / + 6px                                                             |
| `fontSize`      | `number \| string`                                                                                                                | `14`              | Base font; small font − 1px, large font + 2px                                                                |
| `fontFamily`    | `string`                                                                                                                          | System sans-serif | Font family                                                                                                  |
| `appearance`    | `'light' \| 'dark'`                                                                                                               | `'light'`         | Light or dark; inherits explicit ancestor settings                                                           |
| `motion`        | `boolean`                                                                                                                         | `true`            | Enable interaction motion in this region; reduced-motion preferences take precedence and portals inherit it. |
| `tokens`        | [`LeafThemeTokens`](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/theme-tokens.md#leafthemetokens)                             | —                 | Optional advanced overrides                                                                                  |
| `spacing`       | `number`                                                                                                                          | —                 | Base spacing; other spacing values are derived.                                                              |
| `lineHeight`    | `number`                                                                                                                          | —                 | Body line height.                                                                                            |
| `headingWeight` | `number`                                                                                                                          | —                 | Weight of Typography document headings; component titles use `tokens.fontWeight`.                            |
| `elevation`     | `'none' \| 'soft' \| 'medium'`                                                                                                    | —                 | Overall shadow strength.                                                                                     |
| `breakpoints`   | `Partial<Record<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl', number>>`                                                                   | —                 | Responsive thresholds used by useBreakpoint.                                                                 |
| `components`    | `Record<string, `[`LeafComponentTokens`](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/theme-tokens.md#leafcomponenttokens)`>` | —                 | Override local styles by component name.                                                                     |

### Types and complete reference

Import types when creating reusable configuration:

```ts
import type { ConfigProviderProps, LeafComponentDefaults, LeafTheme } from '@ifhover/leaf-ui';
```

- [LeafComponentDefaults](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/component-defaults.md#leafcomponentdefaults): component keys and configurable props.
- [LeafThemeTokens](https://ifhover.github.io/leaf-ui/v/0.6.0/en/api/theme-tokens.md#leafthemetokens): advanced theme overrides.
