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
The application tree to wrap with Kuzenbo context.
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>
Global border radius applied via CSS variable --kb-radius. Accepts pixel values (number) or CSS strings.<KuzenboProvider defaultRadius="0.75rem">
{children}
</KuzenboProvider>
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.
Whether to inherit configuration from parent KuzenboProvider instances. Enables nested provider composition.
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
The global default size setting.
defaultRadius
number | string | undefined
The global default border radius.
Whether reduced motion mode is enabled.
The current environment mode.
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;