-
-
-
-
+
+
+
+
+
`;
@@ -52,6 +62,13 @@ export const _Sizes: Story = {
},
render: () => ({
components: { Switch },
+ setup() {
+ const lg = ref(false);
+ const base = ref(false);
+ const sm = ref(false);
+ const xs = ref(false);
+ return { lg, base, sm, xs };
+ },
template: sizesCode,
}),
};
diff --git a/resources/js/stories/Table.stories.ts b/resources/js/stories/Table.stories.ts
index 1788607ee1e..cbef35a1baa 100644
--- a/resources/js/stories/Table.stories.ts
+++ b/resources/js/stories/Table.stories.ts
@@ -1,9 +1,16 @@
-import type { Meta, StoryObj } from '@storybook/vue3';
-import { Table, TableColumns, TableColumn, TableRows, TableRow, TableCell, Badge } from '@ui';
+import type {Meta, StoryObj} from '@storybook/vue3';
+import {Badge, Table, TableCell, TableColumn, TableColumns, TableRow, TableRows} from '@ui';
const meta = {
- title: 'Components/Table',
+ title: 'Layout/Table',
component: Table,
+ subcomponents: {
+ TableColumns,
+ TableColumn,
+ TableRows,
+ TableRow,
+ TableCell,
+ },
argTypes: {},
} satisfies Meta
;
diff --git a/resources/js/stories/Tabs.stories.ts b/resources/js/stories/Tabs.stories.ts
index e45a777982e..7b68239c332 100644
--- a/resources/js/stories/Tabs.stories.ts
+++ b/resources/js/stories/Tabs.stories.ts
@@ -1,11 +1,23 @@
-import type { Meta, StoryObj } from '@storybook/vue3';
-import { Tabs, TabList, TabTrigger, TabContent } from '@ui';
+import type {Meta, StoryObj} from '@storybook/vue3';
+import {TabContent, TabList, Tabs, TabTrigger} from '@ui';
+import {ref} from 'vue';
const meta = {
- title: 'Components/Tabs',
+ title: 'Layout/Tabs',
component: Tabs,
+ subcomponents: {
+ TabList,
+ TabTrigger,
+ TabContent,
+ },
argTypes: {
- defaultTab: { control: 'text' },
+ 'update:modelValue': {
+ description: 'Event handler called when the tab changes.',
+ table: {
+ category: 'events',
+ type: { summary: '(value: string) => void' }
+ }
+ }
},
} satisfies Meta;
@@ -13,20 +25,20 @@ export default meta;
type Story = StoryObj;
const defaultCode = `
-
+
-
-
-
+
+
+
-
- Tab 1 content
+
+ Content of Tab 1
-
- Tab 2 content
+
+ Content of Tab 2
-
- Tab 3 content
+
+ Content of Tab 3
`;
@@ -40,6 +52,10 @@ export const _DocsIntro: Story = {
},
render: () => ({
components: { Tabs, TabList, TabTrigger, TabContent },
+ setup() {
+ const activeTab = ref('tab1');
+ return { activeTab };
+ },
template: defaultCode,
}),
};
diff --git a/resources/js/stories/Textarea.stories.ts b/resources/js/stories/Textarea.stories.ts
index 1ce17d77698..e42297f0137 100644
--- a/resources/js/stories/Textarea.stories.ts
+++ b/resources/js/stories/Textarea.stories.ts
@@ -1,18 +1,20 @@
-import type { Meta, StoryObj } from '@storybook/vue3';
-import { Textarea } from '@ui';
+import type {Meta, StoryObj} from '@storybook/vue3';
+import {Textarea} from '@ui';
const meta = {
- title: 'Components/Textarea',
+ title: 'Forms/Textarea',
component: Textarea,
argTypes: {
- label: { control: 'text' },
- placeholder: { control: 'text' },
- disabled: { control: 'boolean' },
- elastic: { control: 'boolean' },
- rows: { control: 'number' },
resize: {
control: 'select',
- options: ['none', 'vertical', 'horizontal', 'both'],
+ options: ['both', 'horizontal', 'vertical', 'none'],
+ },
+ 'update:modelValue': {
+ description: 'Event handler called when the textarea is updated.',
+ table: {
+ category: 'events',
+ type: { summary: '(value: string) => void' }
+ }
},
},
} satisfies Meta;
diff --git a/resources/js/stories/TimePicker.stories.ts b/resources/js/stories/TimePicker.stories.ts
new file mode 100644
index 00000000000..56c029a3d2f
--- /dev/null
+++ b/resources/js/stories/TimePicker.stories.ts
@@ -0,0 +1,66 @@
+import type {Meta, StoryObj} from '@storybook/vue3';
+import {ref} from 'vue';
+import {TimePicker} from '@ui';
+
+const meta = {
+ title: 'Forms/TimePicker',
+ component: TimePicker,
+ argTypes: {
+ granularity: {
+ control: 'select',
+ options: ['hour', 'minute', 'second'],
+ },
+ 'update:modelValue': {
+ description: 'Event handler called when the time value changes.',
+ table: {
+ category: 'events',
+ type: { summary: '(value: TimeValue) => void' }
+ }
+ }
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+const defaultCode = `
+
+`;
+
+export const _DocsIntro: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: defaultCode }
+ }
+ },
+ render: () => ({
+ components: { TimePicker },
+ setup() {
+ const time = ref(null);
+ return { time };
+ },
+ template: defaultCode,
+ }),
+};
+
+const withSecondsCode = `
+
+`;
+
+export const _WithSeconds: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: withSecondsCode }
+ }
+ },
+ render: () => ({
+ components: { TimePicker },
+ setup() {
+ const time = ref(null);
+ return { preciseTime: time };
+ },
+ template: withSecondsCode,
+ }),
+};
diff --git a/resources/js/stories/Toggle.stories.ts b/resources/js/stories/Toggle.stories.ts
new file mode 100644
index 00000000000..d855c925a85
--- /dev/null
+++ b/resources/js/stories/Toggle.stories.ts
@@ -0,0 +1,320 @@
+import type {Meta, StoryObj} from '@storybook/vue3';
+import {ToggleGroup, ToggleItem} from '@ui';
+import {ref} from 'vue';
+
+const meta = {
+ title: 'Forms/Toggle',
+ component: ToggleGroup,
+ subcomponents: {
+ ToggleItem,
+ },
+ argTypes: {
+ size: {
+ control: 'select',
+ options: ['xs', 'sm', 'base'],
+ },
+ variant: {
+ control: 'select',
+ options: ['default', 'primary', 'filled', 'ghost'],
+ },
+ 'update:modelValue': {
+ description: 'Event handler called when the selected options change.',
+ table: {
+ category: 'events',
+ type: { summary: '(value: string | string[]) => void' }
+ }
+ }
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+const introCode = `
+
+
+
+
+
+`;
+
+export const _DocsIntro: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: introCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected = ref('list');
+ return { selected };
+ },
+ template: introCode,
+ }),
+};
+
+const defaultCode = `
+
+
+
+
+
+`;
+
+export const Default: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: defaultCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected = ref('option1');
+ return { selected };
+ },
+ template: defaultCode,
+ }),
+};
+
+const variantsCode = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+export const Variants: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: variantsCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected1 = ref('option1');
+ const selected2 = ref('option1');
+ const selected3 = ref('option1');
+ const selected4 = ref('option1');
+ return { selected1, selected2, selected3, selected4 };
+ },
+ template: `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+ }),
+};
+
+const sizesCode = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+export const Sizes: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: sizesCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected1 = ref('option1');
+ const selected2 = ref('option1');
+ const selected3 = ref('option1');
+ return { selected1, selected2, selected3 };
+ },
+ template: `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+ }),
+};
+
+const withIconsCode = `
+
+
+
+
+
+`;
+
+export const WithIcons: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: withIconsCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected = ref('tree');
+ return { selected };
+ },
+ template: withIconsCode,
+ }),
+};
+
+const iconOnlyCode = `
+
+
+
+
+
+`;
+
+export const IconOnly: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: iconOnlyCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected = ref('bold');
+ return { selected };
+ },
+ template: iconOnlyCode,
+ }),
+};
+
+const multipleCode = `
+
+
+
+
+
+`;
+
+export const Multiple: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: {
+ code: `${multipleCode}
+Selected: {{ selected.join(', ') || 'none' }}
`
+ },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected = ref(['bold', 'italic']);
+ return { selected };
+ },
+ template: `
+
+ ${multipleCode}
+
Selected: {{ selected.join(', ') || 'none' }}
+
+ `,
+ }),
+};
+
+const disabledCode = `
+
+
+
+
+
+`;
+
+export const Disabled: Story = {
+ tags: ['!dev'],
+ parameters: {
+ docs: {
+ source: { code: disabledCode },
+ },
+ },
+ render: () => ({
+ components: { ToggleGroup, ToggleItem },
+ setup() {
+ const selected = ref('option1');
+ return { selected };
+ },
+ template: disabledCode,
+ }),
+};
diff --git a/resources/js/stories/docs/Avatar.mdx b/resources/js/stories/docs/Avatar.mdx
new file mode 100644
index 00000000000..eb828575b37
--- /dev/null
+++ b/resources/js/stories/docs/Avatar.mdx
@@ -0,0 +1,14 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as AvatarStories from '../Avatar.stories';
+
+
+
+# Avatar
+Avatars display user profile images or generated initials with beautiful mesh gradient backgrounds.
+
+
+
+The `Avatar` component will use whatever information you pass via the `user` prop to display the user's avatar.
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Button.mdx b/resources/js/stories/docs/Button.mdx
index b9dca050713..23ef5910382 100644
--- a/resources/js/stories/docs/Button.mdx
+++ b/resources/js/stories/docs/Button.mdx
@@ -20,7 +20,7 @@ Automatically sized and styled icons are available for your buttons using the `i
## Round
-Round buttons have their place too — like Bard set pickers. Just set the `round` prop.
+Round buttons have their place too - like Bard set pickers. Just set the `round` prop.
## Loading
@@ -39,5 +39,9 @@ Buttons can be used as links by passing an `href` prop. They will use Inertia to
When using `ghost` or `subtle` button variants, you can use the `inset` prop to remove any invisible padding for better alignment.
+## Button Groups
+You can combine multiple buttons into a "button group".
+
+
## Arguments
diff --git a/resources/js/stories/docs/Calendar.mdx b/resources/js/stories/docs/Calendar.mdx
index 78c940f2a17..31a4cf7b85e 100644
--- a/resources/js/stories/docs/Calendar.mdx
+++ b/resources/js/stories/docs/Calendar.mdx
@@ -17,11 +17,5 @@ You can pass the `week-starts-on` prop to change the first day of the week.
The default is `0` (Sunday). Monday is `1`, Tuesday is `2`, etc.
-## Weekday Format
-You can pass the `weekday-format` prop to change the format of the weekday names.
-
-The default is `narrow`, `short` is `Mon`, `long` is `Monday`.
-
-
## Arguments
diff --git a/resources/js/stories/docs/CharacterCounter.mdx b/resources/js/stories/docs/CharacterCounter.mdx
new file mode 100644
index 00000000000..4cc6faa9bf2
--- /dev/null
+++ b/resources/js/stories/docs/CharacterCounter.mdx
@@ -0,0 +1,29 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as CharacterCounterStories from '../CharacterCounter.stories';
+
+
+
+# CharacterCounter
+A visual character counter that displays as a circular progress indicator. The counter changes color based on how close you are to the limit and shows a countdown when nearing the maximum. Typically used with text inputs and textareas.
+
+
+## With Input
+The CharacterCounter is automatically displayed when you set a `limit` prop on Input or Textarea components. No need to manually add the CharacterCounter component.
+
+
+## States
+The counter provides visual feedback with different colors based on character usage:
+- **Green**: Under 70% of the limit
+- **Amber**: Between 70-90% of the limit
+- **Red**: Between 90-100% of the limit
+- **Red with strike**: Over the limit
+
+Hover over the counter to see the exact character count.
+
+
+## Danger Zone
+Use the `danger-zone` prop to control when the remaining character countdown appears. By default, it shows when 20 or fewer characters remain.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Checkbox.mdx b/resources/js/stories/docs/Checkbox.mdx
new file mode 100644
index 00000000000..1a53d84c77f
--- /dev/null
+++ b/resources/js/stories/docs/Checkbox.mdx
@@ -0,0 +1,32 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as CheckboxStories from '../Checkbox.stories';
+
+
+
+# Checkbox
+A checkbox input component with label and description support. Can be used individually or as part of a checkbox group.
+
+
+## With Description
+
+
+## Sizes
+
+
+## Disabled
+
+
+## Solo Mode
+Use `solo` when the checkbox is used in a context where the label is provided elsewhere, like in a table cell. The label is still required for accessibility but won't be visually displayed:
+
+
+## Checkbox Group
+Group multiple checkboxes together with `CheckboxGroup`. The group manages the selected values as an array:
+
+
+## Inline Group
+Use the `inline` prop to display checkboxes horizontally:
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/CodeEditor.mdx b/resources/js/stories/docs/CodeEditor.mdx
new file mode 100644
index 00000000000..234de1c4b41
--- /dev/null
+++ b/resources/js/stories/docs/CodeEditor.mdx
@@ -0,0 +1,30 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as CodeEditorStories from '../CodeEditor.stories';
+
+
+
+# CodeEditor
+A powerful code editor component powered by CodeMirror. Supports syntax highlighting for multiple languages, line numbers, line wrapping, and keyboard shortcuts.
+
+Docs coming soon.
+
+{/* Todo
+
+
+
+## Modes
+The CodeEditor supports many programming languages and markup formats. Set the `mode` prop to enable syntax highlighting for different languages.
+
+
+## Mode Selection
+Disable the `allow-mode-selection` prop to prevent users from switching between modes.
+
+
+## Without Line Numbers
+Disable line numbers by setting the `line-numbers` prop to `false`. This can be useful for simpler code snippets or when embedding code in constrained spaces.
+
+
+## Arguments
+
+
+*/}
diff --git a/resources/js/stories/docs/Context.mdx b/resources/js/stories/docs/Context.mdx
new file mode 100644
index 00000000000..e912de517fd
--- /dev/null
+++ b/resources/js/stories/docs/Context.mdx
@@ -0,0 +1,33 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as ContextStories from '../Context.stories';
+
+
+
+# Context
+Displays a contextual menu triggered by right-clicking an element, with full keyboard navigation support.
+
+## Overview
+The context component has a `` slot to contain the element that will trigger the context menu on right-click.
+
+
+## Icons
+
+
+## Headers and Footers
+Headers and footers can be added to the context menu by using the `ContextHeader` and `ContextFooter` components.
+
+
+## Labels
+Labels can be used to group related items by using the `ContextLabel` component.
+
+
+## Links
+Items can be rendered as links by providing an `href` prop.
+
+
+## Disabled Items
+Items can be disabled by using the `disabled` prop.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/CreateForm.mdx b/resources/js/stories/docs/CreateForm.mdx
new file mode 100644
index 00000000000..7e36ad218aa
--- /dev/null
+++ b/resources/js/stories/docs/CreateForm.mdx
@@ -0,0 +1,24 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as CreateFormStories from '../CreateForm.stories';
+
+
+
+# CreateForm
+A pre-built form component for creating new resources with automatic slug generation. Includes title and handle fields with customizable instructions and automatic form submission.
+
+Docs coming soon.
+
+{/* Todo
+
+
+## Without Handle
+Use the `withoutHandle` prop to hide the handle field for resources that don't need slugs.
+
+
+## With Instructions
+Add helpful instructions to guide users when filling out the form.
+
+
+## Arguments
+
+*/}
diff --git a/resources/js/stories/docs/DatePicker.mdx b/resources/js/stories/docs/DatePicker.mdx
new file mode 100644
index 00000000000..f3fc909d17c
--- /dev/null
+++ b/resources/js/stories/docs/DatePicker.mdx
@@ -0,0 +1,27 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as DatePickerStories from '../DatePicker.stories';
+
+
+
+# DatePicker
+A date picker component with calendar popover for selecting dates and optionally times. Supports keyboard navigation and localization.
+
+
+## With Time
+Set the `granularity` prop to `minute` or `hour` to include time selection.
+
+
+## Min and Max Dates
+Restrict selectable dates using the `min` and `max` props.
+
+
+## Inline
+Display the calendar inline instead of in a popover.
+
+
+## Multiple Months
+Show multiple months side-by-side for easier date selection across month boundaries.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/DateRangePicker.mdx b/resources/js/stories/docs/DateRangePicker.mdx
new file mode 100644
index 00000000000..230fafeb32f
--- /dev/null
+++ b/resources/js/stories/docs/DateRangePicker.mdx
@@ -0,0 +1,19 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as DateRangePickerStories from '../DateRangePicker.stories';
+
+
+
+# DateRangePicker
+A date range picker component for selecting a start and end date. Perfect for campaigns, bookings, and time-based filters.
+
+
+## Min and Max Dates
+Restrict selectable dates using the `min` and `max` props.
+
+
+## Inline
+Display the calendar inline instead of in a popover.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Description.mdx b/resources/js/stories/docs/Description.mdx
new file mode 100644
index 00000000000..3b136129960
--- /dev/null
+++ b/resources/js/stories/docs/Description.mdx
@@ -0,0 +1,15 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as DescriptionStories from '../Description.stories';
+
+
+
+# Description
+Display helpful description text below form labels to provide additional context and guidance to users. Descriptions are styled with a subdued color to differentiate them from labels.
+
+
+## With Slot
+Use the default slot to include HTML content, links, or formatted text in your descriptions.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/DocsCallout.mdx b/resources/js/stories/docs/DocsCallout.mdx
new file mode 100644
index 00000000000..171143c9082
--- /dev/null
+++ b/resources/js/stories/docs/DocsCallout.mdx
@@ -0,0 +1,15 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as DocsCalloutStories from '../DocsCallout.stories';
+
+
+
+# DocsCallout
+A callout component linking to the Statamic Documentation. Displays as a badge encouraging users to learn more about a specific topic by visiting the relevant page on the docs.
+
+
+## Third-party documentation
+The `DocsCallout` component will prepend `https://statamic.dev/` when you provide a relative URL. You can link to your own documentation site by providing an absolute URL:
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/DragHandle.mdx b/resources/js/stories/docs/DragHandle.mdx
new file mode 100644
index 00000000000..2ae2c3c1b4b
--- /dev/null
+++ b/resources/js/stories/docs/DragHandle.mdx
@@ -0,0 +1,12 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as DragHandleStories from '../DragHandle.stories';
+
+
+
+# DragHandle
+
+A button component that displays a drag handle icon for reorderable lists. Uses the `data-drag-handle` attribute for integration with drag-and-drop libraries.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Dropdown.mdx b/resources/js/stories/docs/Dropdown.mdx
index 575b303fa88..15d60c4b07f 100644
--- a/resources/js/stories/docs/Dropdown.mdx
+++ b/resources/js/stories/docs/Dropdown.mdx
@@ -4,7 +4,7 @@ import * as DropdownStories from '../Dropdown.stories';
# Dropdown
-Displays a menu to the user—such as a set of actions or functions—triggered by a button, with full keyboard navigation support.
+Displays a menu to the user - such as a set of actions or functions - triggered by a button, with full keyboard navigation support.
## Overview
The dropdown component has a `` slot to contain the button that will trigger the dropdown.
diff --git a/resources/js/stories/docs/Editable.mdx b/resources/js/stories/docs/Editable.mdx
new file mode 100644
index 00000000000..feaec480d4c
--- /dev/null
+++ b/resources/js/stories/docs/Editable.mdx
@@ -0,0 +1,27 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as EditableStories from '../Editable.stories';
+
+
+
+# Editable
+An inline editable text component that allows users to click to edit text in place. Perfect for titles, labels, and other short text fields that need quick editing.
+
+
+## Start With Edit Mode
+Set `start-with-edit-mode` to `true` to automatically focus the input when the component mounts.
+
+
+## Submit Modes
+Control when edits are saved using the `submit-mode` prop. Choose from `blur` (save when clicking away), `enter` (save when pressing Enter), or `both`.
+
+
+## Events
+Listen to `@submit`, `@cancel`, and `@edit` events to respond to user interactions.
+
+
+## Custom Placeholder
+Provide helpful context with a custom placeholder that appears when the value is empty.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/EmptyState.mdx b/resources/js/stories/docs/EmptyState.mdx
new file mode 100644
index 00000000000..0b1c6a035f0
--- /dev/null
+++ b/resources/js/stories/docs/EmptyState.mdx
@@ -0,0 +1,27 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as EmptyStateStories from '../EmptyState.stories';
+
+
+
+# Empty State
+Display helpful options and actions when a section has no content yet. Empty states guide users toward creating their first items with descriptive cards that explain each option.
+
+
+We recommend using the empty state components alongside the `useArchitecturalBackground()` composable:
+
+```js
+import { useArchitecturalBackground } from '@statamic/cms/inertia';
+
+useArchitecturalBackground();
+```
+
+## With Slot
+Use the default slot in `EmptyStateItem` for custom content instead of the description prop.
+
+
+## No Links
+Items can be rendered as buttons instead of links by omitting the `href` prop. When using the default slot, items are rendered as non-interactive divs.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/ErrorMessage.mdx b/resources/js/stories/docs/ErrorMessage.mdx
new file mode 100644
index 00000000000..514c6c27915
--- /dev/null
+++ b/resources/js/stories/docs/ErrorMessage.mdx
@@ -0,0 +1,15 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as ErrorMessageStories from '../ErrorMessage.stories';
+
+
+
+# ErrorMessage
+Display validation errors and other error messages with consistent styling. Error messages are styled in red with proper text formatting and support for links.
+
+
+## With Slot
+Use the default slot to include HTML content, links, or formatted text in your error messages.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Field.mdx b/resources/js/stories/docs/Field.mdx
new file mode 100644
index 00000000000..c372266cd63
--- /dev/null
+++ b/resources/js/stories/docs/Field.mdx
@@ -0,0 +1,39 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as FieldStories from '../Field.stories';
+
+
+
+# Field
+A wrapper component for form controls that provides consistent labels, descriptions, error messaging, and layout options. The `Field` component handles all the common patterns for form inputs including required indicators, badges, and validation states.
+
+
+## Required
+Use the `required` prop to display a red asterisk indicating a required field.
+
+
+## With Badge
+Add a badge to the label to indicate special features, statuses, or plan requirements. (TODO don't like this example)
+
+
+## With Error
+Display validation errors below the field using the `error` prop for a single error or `errors` for multiple messages.
+
+
+## Inline Variant
+Use the `inline` variant to display the label and control side-by-side rather than stacked. (use diff example here too - maybe keep email or use a switch?)
+
+
+## Instructions Below
+Position instructions below the control instead of below the label for better visual flow with large inputs.
+
+
+## With Actions Slot
+Add action buttons or controls next to the label using the `actions` slot.
+
+
+## As Config
+Use the `asConfig` prop to style fields as configuration settings with a two-column layout. Use `fullWidthSetting` to override the two-column layout for specific fields.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Header.mdx b/resources/js/stories/docs/Header.mdx
new file mode 100644
index 00000000000..5eafe1ddd6c
--- /dev/null
+++ b/resources/js/stories/docs/Header.mdx
@@ -0,0 +1,19 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as HeaderStories from '../Header.stories';
+
+
+
+# Header
+Displays a page header with an optional icon, title, and action buttons. The Header component provides consistent styling and layout for page headers throughout the Control Panel.
+
+
+## With Actions
+Add action buttons to the right side of the header using the default slot.
+
+
+## With Title Slot
+Use the `title` slot for custom title content with custom formatting.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Heading.mdx b/resources/js/stories/docs/Heading.mdx
index fdf9dd247ef..ca4e7f9c77f 100644
--- a/resources/js/stories/docs/Heading.mdx
+++ b/resources/js/stories/docs/Heading.mdx
@@ -8,7 +8,7 @@ Clean and consistent headings and subheadings.
## Sizes
-Headings come in three sizes. If that feels too restrictive, that's okay — you'll get used to it. Less is more. Trust us.
+Headings come in three sizes. If that feels too restrictive, that's okay - you'll get used to it. Less is more. Trust us.
## Heading Level
diff --git a/resources/js/stories/docs/HoverCard.mdx b/resources/js/stories/docs/HoverCard.mdx
new file mode 100644
index 00000000000..adf6632db39
--- /dev/null
+++ b/resources/js/stories/docs/HoverCard.mdx
@@ -0,0 +1,26 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as HoverCardStories from '../HoverCard.stories';
+
+
+
+# Hover Card
+Displays rich content in a floating card when hovering over a trigger element. Hover Cards are perfect for showing additional context or user information without cluttering the interface.
+
+## Overview
+The hover card component has a `` slot to contain the element that will trigger the card on hover.
+
+
+## Direction
+Control which side of the trigger the card appears on.
+
+
+## No Arrow
+Remove the arrow pointer by setting `arrow` to `false`.
+
+
+## Custom Delay
+Adjust the delay before the card appears using the `delay` prop.
+
+
+## Arguments
+
diff --git a/resources/js/stories/docs/Label.mdx b/resources/js/stories/docs/Label.mdx
new file mode 100644
index 00000000000..c1ff9b009ca
--- /dev/null
+++ b/resources/js/stories/docs/Label.mdx
@@ -0,0 +1,27 @@
+import { Canvas, Meta, ArgTypes } from '@storybook/addon-docs/blocks';
+import * as LabelStories from '../Label.stories';
+
+
+
+# Label
+Display labels for form inputs with support for required indicators and badges. Labels are semantically correct `