Mosmox UI
Current version
GitHubnpmjs.com

ConfigProvider

Global theme tokens, typography, component configuration, and scoped customization API

ConfigProvider is the framework-level configuration boundary. It wraps a subtree of Mosmox UI components and provides three kinds of customization:

  • theme changes shared design tokens through CSS custom properties;
  • components changes component-specific defaults where a component has an explicit configuration API;
  • locale sets the default language for localized components such as Calendar and Pagination.

The provider does not add styles to unrelated DOM outside its subtree, and it does not change component behavior unless a component-specific setting explicitly supports that behavior.

Basic usage

import { Button, CodeBlock, ConfigProvider, Input, List, Select, Skeleton, Tabs } from '@mosmox/ui';

<ConfigProvider
  theme={{
    colors: {
      primary: '#123b38',
      primaryHover: '#1b5752',
      controlBorder: '#b8c8c2',
      controlIcon: '#52665f',
      focus: '#4f46e5',
    },
    radius: '6px',
    typography: {
      fontFamily: 'Inter, ui-sans-serif, system-ui, sans-serif',
      fontWeightNormal: 400,
      fontWeightMedium: 600,
    },
  }}
>
  <Button>Save</Button>
  <Input label="Name" />
  <Select label="Team" options={teamOptions} />
</ConfigProvider>

Every supported value is optional. Unspecified values keep the defaults from tokens.css.

Global locale

locale accepts en, uk, de or fr, and defaults to en. Calendar and Pagination read this value automatically. A component-level locale prop can override the provider for one instance.

<ConfigProvider locale="uk">
  <Calendar />
  <Pagination totalPages={12} showQuickJumper />
</ConfigProvider>

<ConfigProvider locale="de">
  <Calendar locale="fr" /> {/* local override */}
</ConfigProvider>

The provider locale is used as a fallback for built-in interface labels. It does not translate content that you pass yourself. Supported locales are en (English, the default), uk (Ukrainian), de (German), and fr (French). For a component that needs a different language, set its local locale prop. The precedence is: explicit component prop, nearest ConfigProvider, then en.

Theme tokens

theme.colors contains semantic values rather than component-specific selectors. The same token can affect several controls, which keeps Button, Input, Input OTP, Select, Checkbox, Radio, Switch, Textarea, and Switch Card visually consistent.

Color tokens

Theme propertyCSS variableDefaultUsed for
text--mm-color-text#0c1518Primary text and control content.
primary--mm-color-primary#003231Primary actions, selected states, active controls, and focus borders.
primaryHover--mm-color-primary-hover#004846Hover state of primary actions.
secondary--mm-color-secondary#47634cSecondary actions and supporting emphasis.
secondaryHover--mm-color-secondary-hover#58775dHover state of secondary actions.
surface--mm-color-surface#ffffffInput surfaces, cards, menus, and control backgrounds.
surfaceHover--mm-color-surface-hover#f8fafcHover and active surface state for controls and Select options.
controlBorder--mm-color-control-border#d0d5ddInput, Select, Textarea, Radio, Checkbox, menu, and divider borders.
controlFilled--mm-color-control-filled#eef1f2Filled controls, selected chips, selected options, and muted control surfaces.
controlSelected--mm-color-control-selectedlightBackgroundLight active and selected options in Select and AutoComplete menus.
overlay--mm-color-overlayrgb(12 21 24 / 14%)Modal backdrop color.
controlIcon--mm-color-control-icon#667085Icons inside controls, password actions, Select actions, and adornments.
mutedText--mm-color-muted-text#667085Descriptions, supporting text, secondary labels, and status text.
placeholder--mm-color-placeholder#98a2b3Input, Select, Textarea, and OTP placeholders.
focus--mm-color-focus#6366f1Keyboard focus rings.
link--mm-color-link#1d4ed8Default color for the Link component and other link-style actions. An individual Link color="..." prop overrides it.
lightBackground--mm-color-light-background#f6f6f7Neutral light surface for buttons, sections, and low-emphasis backgrounds.
lightHover--mm-color-light-hover#e8dfd1Hover state for light actions.
dangerBackground--mm-color-danger-background#fdececDestructive Button background and danger surfaces.
danger--mm-color-danger#dc2626Destructive active states and progress treatments.
dangerHover--mm-color-danger-hover#b91c1cHover state for danger actions.
dangerText--mm-color-danger-text#b42318Error messages, invalid borders, and danger text.
success--mm-color-success#059669Success actions and positive Switch tones.
successHover--mm-color-success-hover#047857Hover state for success actions.
warning--mm-color-warning#d97706Warning Switch tones and warning indicators.
warningHover--mm-color-warning-hover#b45309Hover state for warning actions.
warningText--mm-color-warning-text#b54708Warning status text and messages.

Example of a complete semantic color override:

import { Plus } from '@mosmox-ui/icons';

<ConfigProvider
  theme={{
    colors: {
      text: '#17211f',
      primary: '#0f766e',
      primaryHover: '#115e59',
      secondary: '#4d7c0f',
      secondaryHover: '#3f6212',
      surface: '#ffffff',
      surfaceHover: '#f0fdfa',
      controlBorder: '#99f6e4',
      controlFilled: '#f0fdfa',
      controlIcon: '#0f766e',
      mutedText: '#64748b',
      placeholder: '#94a3b8',
      focus: '#14b8a6',
      link: '#2563eb',
      success: '#16a34a',
      successHover: '#15803d',
      warning: '#d97706',
      warningHover: '#b45309',
      warningText: '#b45309',
      dangerBackground: '#fef2f2',
      danger: '#dc2626',
      dangerHover: '#b91c1c',
      dangerText: '#b91c1c',
    },
  }}
>
  {children}
</ConfigProvider>

Radius

theme.radius maps to --mm-radius-control and is the shared radius for form controls, buttons, cards, menus, and other component surfaces that use the common control shape.

<ConfigProvider theme={{ radius: '10px' }}>
  <Input label="Rounded control" />
</ConfigProvider>

Use a CSS length such as 0, 4px, 6px, or 999px. Individual components can still define an internal shape for sub-elements such as chips, icon buttons, or circular controls.

Typography

theme.typography controls the shared typography tokens:

PropertyCSS variableDefaultDescription
fontFamily--mm-font-family-sans'Google Sans Flex', ui-sans-serif, system-ui, sans-serifFont stack used by controls and labels.
fontWeightNormal--mm-font-weight-normal400Normal control and body text.
fontWeightMedium--mm-font-weight-medium500Labels and emphasized control text.
fontWeightLight--mm-font-weight-light300Compact and lightweight control text.
<ConfigProvider
  theme={{
    typography: {
      fontFamily: 'Manrope, ui-sans-serif, sans-serif',
      fontWeightLight: 400,
      fontWeightNormal: 500,
      fontWeightMedium: 700,
    },
  }}
>
  {children}
</ConfigProvider>

Component-specific configuration

The components object is intentionally separate from global tokens. It is used for geometry or behavior that should affect one component family without changing every control.

Button

components.button currently supports:

PropertyTypeDefaultDescription
gapstringshared control gapGap between Button content and icons.
iconSizestringcomponent defaultWidth and height applied to Button icons.
radiusstringshared control radiusButton-only radius override.
import { Plus } from '@mosmox-ui/icons';

<ConfigProvider
  components={{
    button: {
      gap: '10px',
      iconSize: '18px',
      radius: '999px',
    },
  }}
>
  <Button iconLeft={<Plus />}>Create</Button>
</ConfigProvider>

The Button configuration does not change Input, Select, or other controls. Component-specific configuration is only available where the component exposes a typed configuration entry; passing arbitrary keys is not part of the supported API.

Skeleton

components.skeleton sets loading-placeholder defaults for all Skeleton descendants:

PropertyTypeDefaultDescription
animationpulse | wave | nonepulseDefault Skeleton animation.
baseColorstringtheme control fillPlaceholder base color.
highlightColorstringtranslucent surfaceWave highlight color.
radiusstringshared control radiusDefault shape radius.
<ConfigProvider
  components={{
    skeleton: {
      animation: 'wave',
      baseColor: '#dbeafe',
      highlightColor: '#eff6ff',
      radius: '12px',
    },
  }}
>
  <Skeleton variant="rectangular" height={120} />
</ConfigProvider>

An individual Skeleton can override these values with its own animation or radius prop. See the complete Skeleton documentation for all component props and variants.

CodeBlock

components.codeBlock configures defaults for the CodeBlock code viewer:

PropertyTypeDefaultDescription
copyablebooleantrueWhether code blocks show a copy action.
fontSizestringcomponent defaultBase code font size.
radiusstring8pxDefault block radius.
themelight | darkdarkDefault color theme.
<ConfigProvider components={{ codeBlock: { theme: 'light', fontSize: '14px', radius: '12px' } }}>
  <CodeBlock code="const configured = true;" language="tsx" />
</ConfigProvider>

See the complete CodeBlock documentation for all props and examples.

List

components.list sets default density, variant, and spacing for List descendants:

PropertyTypeDefaultDescription
gapstring8pxSpacing between list sections.
sizesm | default | lgdefaultDefault row density.
variantplain | divided | bordered | cardplainDefault visual treatment.
<ConfigProvider components={{ list: { variant: 'card', size: 'sm', gap: '12px' } }}>
  <List items={items} />
</ConfigProvider>

See the complete List documentation for selection, links, loading, custom rendering, and all item fields.

Tabs

components.tabs configures default tab orientation, density, and width:

PropertyTypeDefaultDescription
fullWidthbooleanfalseStretches tabs across the available width.
orientationhorizontal | verticalhorizontalTab list direction.
sizesm | default | lgdefaultTab density.
<ConfigProvider components={{ tabs: { size: 'sm', fullWidth: true } }}>
  <Tabs items={items} />
</ConfigProvider>

See the complete Tabs documentation for keyboard behavior, lazy panels, and all props.

Empty

components.empty provides defaults for the Empty state presentation:

PropertyTypeDefaultDescription
borderedbooleancomponent defaultWhether the Empty state has a border.
sizesm | defaultdefaultCompact or regular Empty layout.
<ConfigProvider components={{ empty: { size: 'sm', bordered: false } }}>
  <Empty />
</ConfigProvider>

The Empty component's own props take precedence over provider defaults. Its fallback title and description use the provider locale when they are not supplied explicitly.

CookieBanner

components.cookieBanner centralizes consent-banner presentation and layout:

PropertyTypeDefaultDescription
layoutinline | stackedcomponent defaultOne-row or vertical content layout.
presentationbar | cardcomponent defaultFull-width bar or contained card.
positionfixed | sticky | staticcomponent defaultHow the banner participates in page layout.
placementtop | bottomcomponent defaultEdge placement for positioned banners.
radiusnumber | stringcomponent defaultBanner corner radius.
sizesm | defaultdefaultCompact or regular spacing.
surfaceColorstringcomponent defaultBanner surface color.
textColorstringcomponent defaultMain text color.
borderColorstringcomponent defaultBorder color.
variantdefault | soft | contrastcomponent defaultPreset contrast treatment.
showPreferencesbooleancomponent defaultShows or hides the preferences action.
<ConfigProvider
  locale="uk"
  components={{
    cookieBanner: {
      presentation: 'card',
      position: 'fixed',
      placement: 'bottom',
      layout: 'stacked',
      variant: 'soft',
      showPreferences: true,
      radius: 16,
    },
  }}
>
  <CookieBanner
    title="Ми використовуємо cookies"
    description="Це допомагає нам покращувати роботу сайту."
  />
</ConfigProvider>

Cookie content and consent state remain the responsibility of the application. The provider supplies presentation defaults only.

PricingTable

components.pricingTable defines the default layout for nested pricing tables:

PropertyTypeDefaultDescription
columnsnumbercomponent defaultNumber of pricing columns.
sizesm | default | lgdefaultDensity of the pricing table.
variantcards | bordered | flat | spotlight | compactcardsVisual treatment of plans.
<ConfigProvider
  components={{
    pricingTable: {
      columns: 3,
      size: 'default',
      variant: 'spotlight',
    },
  }}
>
  <PricingTable plans={plans} />
</ConfigProvider>

An individual PricingTable prop overrides the corresponding provider value.

Provider scope and nesting

All theme CSS variables are written to the provider wrapper, so they apply to descendants and inherit through nested DOM elements. Components outside the provider keep the root defaults.

Providers can be nested to create local themes:

<ConfigProvider theme={{ colors: { primary: '#003231' } }}>
  <AppShell />

  <ConfigProvider
    theme={{
      colors: { primary: '#7c3aed', primaryHover: '#6d28d9' },
      radius: '12px',
    }}
  >
    <BillingPanel />
  </ConfigProvider>
</ConfigProvider>

The nested provider overrides the CSS variables for its subtree. Unspecified nested values inherit from the outer provider or the root token defaults. Component configuration is scoped to the provider's React subtree.

Defaults that are not ThemeConfig properties

The theme token file also contains foundational values such as --mm-color-white, --mm-color-outline-border, --mm-color-muted-hover, --mm-size-icon, --mm-space-control-gap, and --mm-space-control-icon-gap. These are currently internal foundation tokens and are not accepted by ThemeConfig as public properties. They remain consistent across the framework unless the framework API is extended.

API Reference

PropertyTypeDefaultDescription
childrenReactNode—Component subtree receiving the configuration.
themeThemeConfig{}Global color, radius, and typography overrides.
componentsComponentConfig{}Typed component-specific configuration.
localeen | uk | de | frenDefault language for localized components.

ThemeConfig contains optional colors, radius, and typography groups. ComponentConfig contains button, skeleton, codeBlock, list, tabs, empty, cookieBanner, and pricingTable. The useConfig() hook exposes the component configuration context for framework components and custom integrations.

Configuration precedence

When the same setting is supplied at more than one level, use this order:

  1. An explicit prop on the component instance.
  2. The closest (nested) ConfigProvider.
  3. An outer ConfigProvider.
  4. The framework default from tokens.css or the component implementation.

This lets you define a product-wide baseline and create isolated exceptions without changing the rest of the application.

<ConfigProvider theme={{ colors: { primary: '#003231' }, radius: '6px' }}>
  <Button>Uses the global primary color</Button>

  <ConfigProvider theme={{ colors: { primary: '#7c3aed' }, radius: '12px' }}>
    <Button>Uses the nested theme</Button>
    <Button variant="danger">Its explicit variant still wins</Button>
  </ConfigProvider>
</ConfigProvider>

Using useConfig() in an integration

useConfig() reads the nearest provider context and returns the configured component defaults and locale. It is primarily intended for Mosmox UI components and custom integrations that need to follow the same provider boundary.

import { useConfig } from '@mosmox/ui';

function LocaleBadge() {
  const { locale } = useConfig();

  return <span>Current locale: {locale}</span>;
}

When no provider is present, useConfig() returns an empty component configuration and the default en locale. Theme variables are not exposed by this hook; read them through CSS inheritance so custom integrations stay compatible with the token system.

Application-level setup

Place one provider near the root of a client-side application when the whole product should share a theme and locale. Keep nested providers close to the feature that needs a different visual context.

import { ConfigProvider } from '@mosmox/ui';

export function App() {
  return (
    <ConfigProvider
      locale="uk"
      theme={{
        colors: {
          primary: '#d90b2c',
          primaryHover: '#b90825',
          focus: '#d90b2c',
        },
        radius: '8px',
      }}
    >
      <Router />
    </ConfigProvider>
  );
}

Import ConfigProvider from the public @mosmox/ui entry point. Avoid importing its internal implementation path, since internal paths are not part of the public API.

CSS variable mapping

Theme values are translated to CSS custom properties at runtime. This means the values work with the existing component styles, inherit naturally, and can be inspected in browser DevTools on .mm-config-provider. Components should consume these tokens rather than hard-coding theme colors.