Skip to main content

Overview

The KuzenboProvider is the root configuration context for all Kuzenbo components. It provides global defaults for sizing, theming, motion preferences, and component-specific configurations.

Installation

npm install @kuzenbo/core @kuzenbo/theme

Basic Usage

import { KuzenboProvider } from "@kuzenbo/core/provider";

export default function App({ children }) {
  return (
    <KuzenboProvider
      defaultSize="md"
      defaultRadius="0.625rem"
      reducedMotion={false}
    >
      {children}
    </KuzenboProvider>
  );
}

KuzenboProvider

The root provider component that establishes global configuration context.

Props

children
ReactNode
required
The application tree to wrap with Kuzenbo context.
defaultSize
UISize
Global default size for all size-aware components. Valid values: "xs", "sm", "md", "lg", "xl". Defaults to "md".
<KuzenboProvider defaultSize="lg">
  <Button>Large by default</Button>
</KuzenboProvider>
defaultRadius
number | string
Global border radius applied via CSS variable --kb-radius. Accepts pixel values (number) or CSS strings.
<KuzenboProvider defaultRadius="0.75rem">
  {children}
</KuzenboProvider>
reducedMotion
boolean
default:"false"
Enable reduced motion mode globally. Sets data-kb-motion="reduce" on the provider wrapper.
env
KuzenboEnv
default:"default"
Environment mode. Valid values: "default" or "test". Sets data-kb-env attribute.
inherit
boolean
default:"true"
Whether to inherit configuration from parent KuzenboProvider instances. Enables nested provider composition.
components
KuzenboComponentsConfig
Component-specific default props. Allows overriding defaults for individual component families.
<KuzenboProvider
  components={{
    Input: {
      defaultProps: {
        size: "sm",
        variant: "outline",
      },
    },
    Button: {
      defaultProps: {
        size: "lg",
      },
    },
  }}
>
  {children}
</KuzenboProvider>

Hooks

useKuzenboContext

Access the full Kuzenbo context. Throws an error if called outside KuzenboProvider.
import { useKuzenboContext } from "@kuzenbo/core/provider";

function MyComponent() {
  const context = useKuzenboContext();
  // context.defaultSize, context.defaultRadius, etc.
}
Returns: KuzenboContextValue
defaultSize
UISize | undefined
The global default size setting.
defaultRadius
number | string | undefined
The global default border radius.
reducedMotion
boolean
Whether reduced motion mode is enabled.
env
KuzenboEnv
The current environment mode.
components
KuzenboComponentsConfig
Component-specific configuration map.

useOptionalKuzenboContext

Safely access Kuzenbo context. Returns null if called outside provider instead of throwing.
import { useOptionalKuzenboContext } from "@kuzenbo/core/provider";

function MyComponent() {
  const context = useOptionalKuzenboContext();
  if (!context) {
    return <div>No provider found</div>;
  }
  return <div>Size: {context.defaultSize}</div>;
}
Returns: KuzenboContextValue | null

useGlobalUISize

Get the global default size from the provider.
import { useGlobalUISize } from "@kuzenbo/core/provider";

function MyComponent() {
  const globalSize = useGlobalUISize();
  return <div>Global size: {globalSize ?? "not set"}</div>;
}
Returns: UISize | undefined

useComponentSize

Resolve the effective size for a component using the size precedence chain.
import { useComponentSize } from "@kuzenbo/core/provider";

function MyButton({ size }: { size?: UISize }) {
  // Resolves: explicit size → global size → "md"
  const resolvedSize = useComponentSize(size);
  return <button data-size={resolvedSize}>Button</button>;
}
Parameters:
  • ...candidates: Variable number of size candidates (UISize | undefined | null)
Returns: UISize (always resolves to a valid size) Precedence: First non-null/undefined candidate → global provider size → "md"

useKuzenboEnv

Get the current environment mode.
import { useKuzenboEnv } from "@kuzenbo/core/provider";

function MyComponent() {
  const env = useKuzenboEnv();
  if (env === "test") {
    return <div>Test mode active</div>;
  }
  return <div>Production mode</div>;
}
Returns: KuzenboEnv ("default" or "test")

useKuzenboReducedMotion

Check if reduced motion mode is enabled.
import { useKuzenboReducedMotion } from "@kuzenbo/core/provider";

function AnimatedComponent() {
  const reducedMotion = useKuzenboReducedMotion();
  const duration = reducedMotion ? 0 : 300;
  return <div style={{ transitionDuration: `${duration}ms` }}>Content</div>;
}
Returns: boolean

useKuzenboComponentDefaults

Access component-specific default props from the provider configuration.
import { useKuzenboComponentDefaults } from "@kuzenbo/core/provider";

function MyButton(props: ButtonProps) {
  const defaults = useKuzenboComponentDefaults<ButtonProps>("Button");
  // Merge with provided props
  const finalProps = { ...defaults, ...props };
  return <button {...finalProps} />;
}
Parameters:
  • componentName: string - The component identifier
Returns: Partial<T> - Component-specific defaults

useComponentDefaultProps

Merge component defaults with actual props using proper precedence.
import { useComponentDefaultProps } from "@kuzenbo/core/provider";

function MyInput(props: InputProps) {
  const mergedProps = useComponentDefaultProps(
    "Input",
    { size: "md", variant: "outline" }, // component defaults
    props // actual props
  );
  // Precedence: props > provider config > component defaults
  return <input {...mergedProps} />;
}
Parameters:
  • componentName: string - Component identifier
  • defaultProps: Partial<T> - Built-in component defaults
  • props: T - Actual props passed to component
Returns: T - Merged props with correct precedence Precedence: props > provider components[name].defaultProps > defaultProps

TypeScript Interfaces

KuzenboProviderProps

interface KuzenboProviderProps {
  children: ReactNode;
  components?: KuzenboComponentsConfig;
  defaultRadius?: number | string;
  defaultSize?: UISize;
  env?: KuzenboEnv;
  inherit?: boolean;
  reducedMotion?: boolean;
}

KuzenboContextValue

interface KuzenboContextValue {
  components: KuzenboComponentsConfig;
  defaultRadius?: number | string;
  defaultSize?: UISize;
  env: KuzenboEnv;
  reducedMotion: boolean;
}

KuzenboComponentsConfig

type KuzenboComponentsConfig = Record<
  string,
  KuzenboComponentConfig | undefined
>;

interface KuzenboComponentConfig {
  defaultProps?: Record<string, unknown>;
}

KuzenboEnv

type KuzenboEnv = "default" | "test";

Complete Example

import { KuzenboProvider } from "@kuzenbo/core/provider";
import { Button } from "@kuzenbo/core/ui/button";
import { Input } from "@kuzenbo/core/ui/input";

export default function App() {
  return (
    <KuzenboProvider
      defaultSize="lg"
      defaultRadius="0.75rem"
      reducedMotion={false}
      components={{
        Input: {
          defaultProps: {
            size: "sm",
          },
        },
      }}
    >
      {/* Inherits lg size */}
      <Button>Submit</Button>
      
      {/* Uses sm from component config */}
      <Input placeholder="Email" />
      
      {/* Explicit override wins */}
      <Input size="xl" placeholder="Large input" />
    </KuzenboProvider>
  );
}

Error Handling

If you use Kuzenbo hooks outside of a KuzenboProvider, you’ll get a descriptive error:
[@kuzenbo/core] KuzenboProvider was not found in tree. Wrap app root with <KuzenboProvider>.
Exception: In test environments, you can set the global flag to allow missing provider:
// In test setup
globalThis.__KUZENBO_ALLOW_MISSING_PROVIDER__ = true;

Build docs developers (and LLMs) love