A fast and lightweight React component development environment for building and sharing components.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive configuration system with TypeScript types for stories, arguments, metadata, and global configuration. Provides type safety and extensive customization options.
Ladle configuration is defined in .ladle/config.mjs using ES module syntax.
/**
* User configuration interface with all optional properties
*/
interface UserConfig extends RecursivePartial<Config> {
/** Glob pattern for story files */
stories?: string;
/** Default story ID to load on startup */
defaultStory?: string;
/** Function to customize story ordering in sidebar */
storyOrder?: (stories: string[]) => string[];
/** Development server port */
port?: number;
/** Preview server port */
previewPort?: number;
/** Build output directory */
outDir?: string;
/** Whether to expand story tree by default */
expandStoryTree?: boolean;
/** Keyboard shortcuts configuration */
hotkeys?: HotkeyConfig;
/** Built-in addons configuration */
addons?: AddonConfig;
}
interface HotkeyConfig {
search?: string[];
nextStory?: string[];
previousStory?: string[];
nextComponent?: string[];
previousComponent?: string[];
toggleSidebar?: string[];
toggleMode?: string[];
toggleTheme?: string[];
toggleRtl?: string[];
toggleSource?: string[];
toggleControls?: string[];
toggleA11y?: string[];
toggleActions?: string[];
toggleWidth?: string[];
fullscreen?: string[];
}
interface AddonConfig {
control?: { enabled?: boolean };
theme?: { enabled?: boolean };
mode?: { enabled?: boolean };
rtl?: { enabled?: boolean };
source?: { enabled?: boolean };
a11y?: { enabled?: boolean };
msw?: { enabled?: boolean };
action?: { enabled?: boolean };
ladle?: { enabled?: boolean };
width?: { enabled?: boolean };
}Configuration Example:
// .ladle/config.mjs
export default {
stories: "src/**/*.stories.{js,jsx,ts,tsx,mdx}",
defaultStory: "components-button--primary",
port: 3000,
previewPort: 8080,
outDir: "component-docs",
expandStoryTree: true,
storyOrder: (stories) => {
// Custom ordering logic
return stories.sort((a, b) => a.localeCompare(b));
},
hotkeys: {
toggleTheme: ["alt+t"],
toggleMode: ["alt+m"]
},
addons: {
a11y: { enabled: true },
msw: { enabled: true },
source: { enabled: false }
}
};TypeScript interfaces for defining stories, their arguments, and metadata.
/**
* Default export interface for story files containing shared configuration
*/
interface StoryDefault<P = {}> {
/** Default arguments for all stories in the file */
args?: Args<P>;
/** Argument type definitions for controls */
argTypes?: ArgTypes<P>;
/** Decorators applied to all stories in the file */
decorators?: StoryDecorator<P>[];
/** Story metadata */
meta?: Meta;
/** Story group title */
title?: string;
/** MSW request handlers for API mocking */
msw?: import("msw").RequestHandler[];
/** Additional parameters */
parameters?: { [key: string]: any };
}
/**
* Named export interface for individual stories
*/
interface Story<P = {}> extends React.FC<P> {
/** Story-specific arguments */
args?: Args<P>;
/** Story-specific argument types */
argTypes?: ArgTypes<P>;
/** Story-specific decorators */
decorators?: StoryDecorator<P>[];
/** Story metadata */
meta?: Meta;
/** Custom story name (overrides function name) */
storyName?: string;
/** MSW handlers for this story */
msw?: import("msw").RequestHandler[];
/** Story-specific parameters */
parameters?: { [key: string]: any };
}
/**
* Story arguments type
*/
type Args<P = { [key: string]: any }> = Partial<P>;
/**
* Story decorator function type
*/
type StoryDecorator<P = {}> = (
Story: React.FC<Partial<P>>,
context: StoryProps
) => React.ReactElement;Story Configuration Examples:
import type { StoryDefault, Story } from "@ladle/react";
// Default export with shared configuration
export default {
title: "Components/Button",
args: {
children: "Button",
variant: "primary"
},
argTypes: {
variant: {
control: { type: "select" },
options: ["primary", "secondary", "danger"]
}
},
decorators: [
(Story) => (
<div style={{ padding: "20px" }}>
<Story />
</div>
)
]
} satisfies StoryDefault;
// Individual story
export const Primary: Story = (args) => <Button {...args} />;
Primary.args = {
variant: "primary"
};
Primary.argTypes = {
onClick: { action: "clicked" }
};Detailed configuration for story controls and argument handling.
/**
* Argument types definition for story controls
*/
type ArgTypes<P = { [key: string]: any }> = {
[K in keyof P]?: ArgType<P[K]>;
};
/**
* Individual argument type configuration
*/
interface ArgType<K = any> {
/** Control configuration for the argument */
control?: {
/** Control type name */
type: ControlType;
/** Labels for options in select/radio controls */
labels?: { [key: string]: string };
/** Minimum value for number/range controls */
min?: number;
/** Maximum value for number/range controls */
max?: number;
/** Step value for number/range controls */
step?: number;
/** Additional control-specific options */
[key: string]: any;
};
/** Value mapping for complex controls */
mapping?: { [key: string | number]: any };
/** Available options for select controls */
options?: K[] | unknown;
/** Default value for the argument */
defaultValue?: K;
/** Description text for the argument */
description?: string;
/** Display name for the argument */
name?: string;
/** Action name for event handlers */
action?: string;
/** Additional argument configuration */
[key: string]: any;
}
/**
* Available control types for arguments
*/
type ControlType =
| "select" // Dropdown select
| "multi-select" // Multiple selection
| "radio" // Radio buttons (vertical)
| "inline-radio" // Radio buttons (horizontal)
| "check" // Checkboxes (vertical)
| "inline-check" // Checkboxes (horizontal)
| "background" // Background color picker
| "color" // Color picker
| "date" // Date picker
| "number" // Number input
| "text" // Text input
| "boolean" // Boolean toggle
| "range"; // Range sliderArgument Types Examples:
export default {
argTypes: {
// Select control with options
size: {
control: { type: "select" },
options: ["small", "medium", "large"],
defaultValue: "medium",
description: "Button size variant"
},
// Number control with range
width: {
control: {
type: "number",
min: 100,
max: 500,
step: 10
},
defaultValue: 200
},
// Boolean toggle
disabled: {
control: { type: "boolean" },
defaultValue: false
},
// Color picker
backgroundColor: {
control: { type: "color" },
defaultValue: "#ffffff"
},
// Action logging
onClick: {
action: "button-clicked"
},
// Complex mapping
theme: {
control: { type: "radio" },
options: ["light", "dark"],
mapping: {
light: { background: "#fff", color: "#000" },
dark: { background: "#000", color: "#fff" }
}
}
}
} satisfies StoryDefault;Story and global metadata configuration interfaces.
/**
* Story metadata interface
*/
interface Meta extends KnownMeta {
[key: string]: any;
}
interface KnownMeta {
/** Story title override */
title?: string;
/** Story description */
description?: string;
/** Story tags for organization */
tags?: string[];
/** Story parameters */
parameters?: { [key: string]: any };
}
/**
* JSON metadata structure for build output
*/
interface MetaJson extends BaseMetaJson<Meta> {
stories: { [key: string]: MetaJsonStory };
}
/**
* Individual story metadata in JSON format
*/
interface MetaJsonStory extends BaseMetaJsonStory<Meta> {
id: string;
name: string;
title: string;
args: { [key: string]: any };
argTypes: { [key: string]: ArgType };
}TypeScript definitions for Ladle's internal state management.
/**
* Global state interface for Ladle application
*/
interface GlobalState {
/** Display mode: full interface or preview only */
mode: ModeState;
/** Theme state: light, dark, or auto */
theme: ThemeState;
/** Action panel state */
action: ActionState;
/** Current story identifier */
story: string;
/** Right-to-left text direction enabled */
rtl: boolean;
/** Source code panel visibility */
source: boolean;
/** Controls panel state */
control: ControlState;
/** Whether controls have been initialized */
controlInitialized: boolean;
/** Current viewport width */
width: number;
/** Whether keyboard shortcuts are enabled */
hotkeys: boolean;
}
/**
* Global action types for state updates
*/
type GlobalAction =
| { type: "UpdateAll"; payload: Partial<GlobalState> }
| { type: "UpdateMode"; payload: ModeState }
| { type: "UpdateTheme"; payload: ThemeState }
| { type: "UpdateAction"; payload: ActionState }
| { type: "UpdateStory"; payload: string }
| { type: "UpdateRtl"; payload: boolean }
| { type: "UpdateSource"; payload: boolean }
| { type: "UpdateControl"; payload: ControlState }
| { type: "UpdateControlInitialized"; payload: boolean }
| { type: "UpdateWidth"; payload: number }
| { type: "UpdateHotkeys"; payload: boolean };
/**
* Enum types for state values
*/
type ThemeState = "light" | "dark" | "auto";
type ModeState = "full" | "preview";
/**
* Global provider component for Ladle context
*/
interface GlobalProvider extends React.FC<{
globalState: GlobalState;
dispatch: React.Dispatch<GlobalAction>;
config: Config;
children: React.ReactNode;
storyMeta?: Meta;
}> {}Extended configuration options for complex setups and integrations.
/**
* Complete configuration interface (internal)
*/
interface Config extends UserConfig {
// All UserConfig properties are required internally
stories: string;
defaultStory: string;
storyOrder: (stories: string[]) => string[];
port: number;
previewPort: number;
outDir: string;
expandStoryTree: boolean;
hotkeys: Required<HotkeyConfig>;
addons: Required<AddonConfig>;
}
/**
* Utility type for making all properties recursively partial
*/
type RecursivePartial<T> = {
[P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P];
};