The scroll lock was mine, and it broke every page carrying a Drawer or Modal. Making dialog visibility testable, I replaced a size check with a data-show check -- but a Drawer animates open, so its panel cannot be hidden with data-show at all: display:none is not transitionable. Every closed Drawer therefore looked open, took the body scroll lock and never released it, and the page could not be scrolled. Both components publish data-open, which is the signal that actually means open, and that is what is read now. Stepper gains the wizard surface: showPanel renders each step body and shows only the active one, the same contract Tabs uses, and controls adds Back, Skip and Next, which becomes Finish on the last step. nextDisabled lets a form hold the step; the component never validates anything itself, since the page owns the form. Stepper also gets a single root. The panels and controls were siblings of the list, so the component had several roots and anything scoped to data-ui-component missed most of it. Tabs panels now slide in the direction of travel rather than fading upward. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
536 lines
34 KiB
Plaintext
536 lines
34 KiB
Plaintext
// Generated by scripts/generate-showcase.mjs. Do not edit directly.
|
|
page StepperDetail {
|
|
layout = "showcase"
|
|
state playground_color = ctx.url.searchParams.get("pg_color") ?? "primary"
|
|
state playground_size = ctx.url.searchParams.get("pg_size") ?? "default"
|
|
state playground_steps = JSON.parse(ctx.url.searchParams.get("pg_steps") ?? "[{\"id\":\"stepper-0-1\",\"key\":\"stepper-0-1\",\"value\":\"primary\",\"label\":\"Primary workflow\",\"title\":\"Primary workflow\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"A configurable sample message.\",\"href\":\"#stepper-demo\",\"actionHref\":\"#stepper-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":true,\"selected\":true,\"checked\":true,\"disabled\":false,\"outgoing\":false,\"open\":true,\"number\":1,\"count\":16,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 1\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]},{\"id\":\"stepper-0-2\",\"key\":\"stepper-0-2\",\"value\":\"secondary\",\"label\":\"Additional option\",\"title\":\"Supporting example\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"Another configurable message.\",\"href\":\"#stepper-demo\",\"actionHref\":\"#stepper-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":false,\"selected\":false,\"checked\":false,\"disabled\":false,\"outgoing\":true,\"open\":true,\"number\":2,\"count\":32,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 2\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]}]")
|
|
state playground_active = Number(ctx.url.searchParams.get("pg_active") ?? "0")
|
|
state playground_orientation = ctx.url.searchParams.get("pg_orientation") ?? "horizontal"
|
|
state playground_clickable = (ctx.url.searchParams.get("pg_clickable") ?? "false") === "true"
|
|
state playground_label = ctx.url.searchParams.get("pg_label") ?? "Stepper"
|
|
state playground_showPanel = (ctx.url.searchParams.get("pg_showPanel") ?? "true") === "true"
|
|
state playground_controls = (ctx.url.searchParams.get("pg_controls") ?? "false") === "true"
|
|
state playground_allowSkip = (ctx.url.searchParams.get("pg_allowSkip") ?? "false") === "true"
|
|
state playground_nextDisabled = (ctx.url.searchParams.get("pg_nextDisabled") ?? "false") === "true"
|
|
state playground_backLabel = ctx.url.searchParams.get("pg_backLabel") ?? "Stepper"
|
|
state playground_nextLabel = ctx.url.searchParams.get("pg_nextLabel") ?? "Stepper"
|
|
state playground_skipLabel = ctx.url.searchParams.get("pg_skipLabel") ?? "Stepper"
|
|
state playground_finishLabel = ctx.url.searchParams.get("pg_finishLabel") ?? "Stepper"
|
|
state playground_class = ctx.url.searchParams.get("pg_class") ?? "showcase-instance showcase-instance--1"
|
|
seo {
|
|
title = "Stepper"
|
|
description = "Theme-aware, responsive stepper component."
|
|
}
|
|
view {
|
|
<nav class="docs-breadcrumbs" aria-label="Breadcrumb">
|
|
<a href="/">Components</a><span aria-hidden="true">/</span><a href="/navigation">Navigation</a><span aria-hidden="true">/</span><span>Stepper</span>
|
|
</nav>
|
|
<header class="detail-hero">
|
|
<div class="detail-hero-copy">
|
|
<span class="showcase-eyebrow">Navigation component</span>
|
|
<h1>Stepper</h1>
|
|
<p>Theme-aware, responsive stepper component.</p>
|
|
<div class="detail-badges"><span>16 props</span><span>3 slots</span><span>5 outputs</span><span>Theme ready</span><span>Responsive</span></div>
|
|
</div>
|
|
<div class="detail-hero-icon"><span class="icon-[lucide--component] size-10" aria-hidden="true"></span></div>
|
|
</header>
|
|
<section id="playground" class="detail-section playground-section" data-playground data-playground-component="Stepper" data-playground-public-tag="true" data-playground-has-slot="true" data-playground-events="change,back,next,skip,finish">
|
|
<div class="detail-section-heading"><span>Interactive playground</span><h2>Configure Stepper</h2><p>Change any prop and inspect the server-rendered component immediately.</p></div>
|
|
<div class="playground-workbench">
|
|
<div class="playground-preview">
|
|
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
|
|
<div class="playground-preview-source" data-playground-preview><Stepper color='{playground_color}' size='{playground_size}' steps='{playground_steps}' active='{playground_active}' orientation='{playground_orientation}' clickable='{playground_clickable}' label='{playground_label}' showPanel='{playground_showPanel}' controls='{playground_controls}' allowSkip='{playground_allowSkip}' nextDisabled='{playground_nextDisabled}' backLabel='{playground_backLabel}' nextLabel='{playground_nextLabel}' skipLabel='{playground_skipLabel}' finishLabel='{playground_finishLabel}' class='{playground_class}' /></div>
|
|
<section class="playground-code" aria-label="Current component code">
|
|
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component code</span><button type="button" data-playground-copy><span class="icon-[lucide--copy] size-4" aria-hidden="true"></span>Copy</button></header>
|
|
<pre><code data-playground-code><Stepper
|
|
steps='[
|
|
<span>{</span>
|
|
"id": "stepper-0-1",
|
|
"key": "stepper-0-1",
|
|
"value": "primary",
|
|
"label": "Primary workflow",
|
|
"title": "Primary workflow",
|
|
"description": "A clean default configuration for everyday product interfaces.",
|
|
"text": "A configurable sample message.",
|
|
"href": "#stepper-demo",
|
|
"actionHref": "#stepper-demo",
|
|
"actionLabel": "View details",
|
|
"icon": "icon-[lucide--sparkles]",
|
|
"iconClass": "icon-[lucide--sparkles]",
|
|
"variant": "primary",
|
|
"status": "Active",
|
|
"time": "09:30",
|
|
"current": true,
|
|
"selected": true,
|
|
"checked": true,
|
|
"disabled": false,
|
|
"outgoing": false,
|
|
"open": true,
|
|
"number": 1,
|
|
"count": 16,
|
|
"percentage": 72,
|
|
"color": "#7c3aed",
|
|
"target": "_self",
|
|
"ariaLabel": "Open primary workflow 1",
|
|
"items": [
|
|
<span>{</span>
|
|
"label": "Nested option A",
|
|
"value": "nested-a"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Nested option B",
|
|
"value": "nested-b"
|
|
<span>}</span>
|
|
],
|
|
"links": [
|
|
<span>{</span>
|
|
"label": "Documentation",
|
|
"href": "#documentation"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "API reference",
|
|
"href": "#api-reference"
|
|
<span>}</span>
|
|
],
|
|
"values": [
|
|
"Included",
|
|
"Standard"
|
|
]
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"id": "stepper-0-2",
|
|
"key": "stepper-0-2",
|
|
"value": "secondary",
|
|
"label": "Additional option",
|
|
"title": "Supporting example",
|
|
"description": "A clean default configuration for everyday product interfaces.",
|
|
"text": "Another configurable message.",
|
|
"href": "#stepper-demo",
|
|
"actionHref": "#stepper-demo",
|
|
"actionLabel": "View details",
|
|
"icon": "icon-[lucide--sparkles]",
|
|
"iconClass": "icon-[lucide--sparkles]",
|
|
"variant": "primary",
|
|
"status": "Active",
|
|
"time": "09:30",
|
|
"current": false,
|
|
"selected": false,
|
|
"checked": false,
|
|
"disabled": false,
|
|
"outgoing": true,
|
|
"open": true,
|
|
"number": 2,
|
|
"count": 32,
|
|
"percentage": 72,
|
|
"color": "#7c3aed",
|
|
"target": "_self",
|
|
"ariaLabel": "Open primary workflow 2",
|
|
"items": [
|
|
<span>{</span>
|
|
"label": "Nested option A",
|
|
"value": "nested-a"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Nested option B",
|
|
"value": "nested-b"
|
|
<span>}</span>
|
|
],
|
|
"links": [
|
|
<span>{</span>
|
|
"label": "Documentation",
|
|
"href": "#documentation"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "API reference",
|
|
"href": "#api-reference"
|
|
<span>}</span>
|
|
],
|
|
"values": [
|
|
"Included",
|
|
"Standard"
|
|
]
|
|
<span>}</span>
|
|
]'
|
|
label="Stepper"
|
|
showPanel="true"
|
|
backLabel="Stepper"
|
|
nextLabel="Stepper"
|
|
skipLabel="Stepper"
|
|
finishLabel="Stepper">
|
|
<div data-slot="step-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">step-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
<div data-slot="panel-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">panel-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
</Stepper></code></pre>
|
|
</section>
|
|
<div class="playground-status" data-playground-status aria-live="polite"></div>
|
|
<div class="playground-event-log" data-playground-event-log aria-live="polite"><strong>Event output</strong><span>Interact with the preview to inspect the typed <code>payload</code>.</span></div>
|
|
</div>
|
|
<form class="playground-controls" data-playground-form>
|
|
<header><div><span>Component props</span><strong>16 controls</strong></div><button type="reset"><span class="icon-[lucide--rotate-ccw] size-4" aria-hidden="true"></span>Reset</button></header>
|
|
<div class="playground-fields"><label class="playground-field" for="playground-stepper-color"><span><strong>color</strong><small>string</small></span><select id="playground-stepper-color" name="pg_color"><option value="primary" selected>primary</option><option value="secondary">secondary</option><option value="success">success</option><option value="warning">warning</option><option value="danger">danger</option><option value="info">info</option></select></label><label class="playground-field" for="playground-stepper-size"><span><strong>size</strong><small>string</small></span><select id="playground-stepper-size" name="pg_size"><option value="default" selected>default</option><option value="xs">xs</option><option value="sm">sm</option><option value="md">md</option><option value="lg">lg</option><option value="xl">xl</option><option value="icon">icon</option><option value="icon-xs">icon-xs</option><option value="icon-sm">icon-sm</option><option value="icon-lg">icon-lg</option></select></label><label class="playground-field" for="playground-stepper-steps"><span><strong>steps</strong><small>unknown[]</small></span><textarea id="playground-stepper-steps" name="pg_steps" rows="5" spellcheck="false" data-playground-json>[
|
|
{
|
|
"id": "stepper-0-1",
|
|
"key": "stepper-0-1",
|
|
"value": "primary",
|
|
"label": "Primary workflow",
|
|
"title": "Primary workflow",
|
|
"description": "A clean default configuration for everyday product interfaces.",
|
|
"text": "A configurable sample message.",
|
|
"href": "#stepper-demo",
|
|
"actionHref": "#stepper-demo",
|
|
"actionLabel": "View details",
|
|
"icon": "icon-[lucide--sparkles]",
|
|
"iconClass": "icon-[lucide--sparkles]",
|
|
"variant": "primary",
|
|
"status": "Active",
|
|
"time": "09:30",
|
|
"current": true,
|
|
"selected": true,
|
|
"checked": true,
|
|
"disabled": false,
|
|
"outgoing": false,
|
|
"open": true,
|
|
"number": 1,
|
|
"count": 16,
|
|
"percentage": 72,
|
|
"color": "#7c3aed",
|
|
"target": "_self",
|
|
"ariaLabel": "Open primary workflow 1",
|
|
"items": [
|
|
{
|
|
"label": "Nested option A",
|
|
"value": "nested-a"
|
|
},
|
|
{
|
|
"label": "Nested option B",
|
|
"value": "nested-b"
|
|
}
|
|
],
|
|
"links": [
|
|
{
|
|
"label": "Documentation",
|
|
"href": "#documentation"
|
|
},
|
|
{
|
|
"label": "API reference",
|
|
"href": "#api-reference"
|
|
}
|
|
],
|
|
"values": [
|
|
"Included",
|
|
"Standard"
|
|
]
|
|
},
|
|
{
|
|
"id": "stepper-0-2",
|
|
"key": "stepper-0-2",
|
|
"value": "secondary",
|
|
"label": "Additional option",
|
|
"title": "Supporting example",
|
|
"description": "A clean default configuration for everyday product interfaces.",
|
|
"text": "Another configurable message.",
|
|
"href": "#stepper-demo",
|
|
"actionHref": "#stepper-demo",
|
|
"actionLabel": "View details",
|
|
"icon": "icon-[lucide--sparkles]",
|
|
"iconClass": "icon-[lucide--sparkles]",
|
|
"variant": "primary",
|
|
"status": "Active",
|
|
"time": "09:30",
|
|
"current": false,
|
|
"selected": false,
|
|
"checked": false,
|
|
"disabled": false,
|
|
"outgoing": true,
|
|
"open": true,
|
|
"number": 2,
|
|
"count": 32,
|
|
"percentage": 72,
|
|
"color": "#7c3aed",
|
|
"target": "_self",
|
|
"ariaLabel": "Open primary workflow 2",
|
|
"items": [
|
|
{
|
|
"label": "Nested option A",
|
|
"value": "nested-a"
|
|
},
|
|
{
|
|
"label": "Nested option B",
|
|
"value": "nested-b"
|
|
}
|
|
],
|
|
"links": [
|
|
{
|
|
"label": "Documentation",
|
|
"href": "#documentation"
|
|
},
|
|
{
|
|
"label": "API reference",
|
|
"href": "#api-reference"
|
|
}
|
|
],
|
|
"values": [
|
|
"Included",
|
|
"Standard"
|
|
]
|
|
}
|
|
]</textarea><em data-playground-error></em></label><label class="playground-field" for="playground-stepper-active"><span><strong>active</strong><small>number</small></span><input id="playground-stepper-active" name="pg_active" type="number" value="0" /></label><label class="playground-field" for="playground-stepper-orientation"><span><strong>orientation</strong><small>string</small></span><select id="playground-stepper-orientation" name="pg_orientation"><option value="horizontal" selected>horizontal</option><option value="vertical">vertical</option></select></label><label class="playground-toggle" for="playground-stepper-clickable"><span><strong>clickable</strong><small>boolean</small></span><input id="playground-stepper-clickable" name="pg_clickable" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-field" for="playground-stepper-label"><span><strong>label</strong><small>string</small></span><input id="playground-stepper-label" name="pg_label" type="text" value="Stepper" /></label><label class="playground-toggle" for="playground-stepper-showPanel"><span><strong>show Panel</strong><small>boolean</small></span><input id="playground-stepper-showPanel" name="pg_showPanel" type="checkbox" value="true" checked data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-stepper-controls"><span><strong>controls</strong><small>boolean</small></span><input id="playground-stepper-controls" name="pg_controls" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-stepper-allowSkip"><span><strong>allow Skip</strong><small>boolean</small></span><input id="playground-stepper-allowSkip" name="pg_allowSkip" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-stepper-nextDisabled"><span><strong>next Disabled</strong><small>boolean</small></span><input id="playground-stepper-nextDisabled" name="pg_nextDisabled" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-field" for="playground-stepper-backLabel"><span><strong>back Label</strong><small>string</small></span><input id="playground-stepper-backLabel" name="pg_backLabel" type="text" value="Stepper" /></label><label class="playground-field" for="playground-stepper-nextLabel"><span><strong>next Label</strong><small>string</small></span><input id="playground-stepper-nextLabel" name="pg_nextLabel" type="text" value="Stepper" /></label><label class="playground-field" for="playground-stepper-skipLabel"><span><strong>skip Label</strong><small>string</small></span><input id="playground-stepper-skipLabel" name="pg_skipLabel" type="text" value="Stepper" /></label><label class="playground-field" for="playground-stepper-finishLabel"><span><strong>finish Label</strong><small>string</small></span><input id="playground-stepper-finishLabel" name="pg_finishLabel" type="text" value="Stepper" /></label><label class="playground-field" for="playground-stepper-class"><span><strong>class</strong><small>string</small></span><input id="playground-stepper-class" name="pg_class" type="text" value="showcase-instance showcase-instance--1" /></label></div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
<div class="detail-layout">
|
|
<main class="detail-content">
|
|
<section class="detail-section"><div class="detail-section-heading"><span>Live examples</span><h2>Designed for real product surfaces</h2><p>Compare configurations and resize the browser to check responsive behavior.</p></div><div class="demo-list">
|
|
<article class="demo-case">
|
|
<header class="demo-case-header">
|
|
<div><span class="demo-case-eyebrow">Recommended</span><h2>Horizontal progress</h2><p>Steps before the active one read as complete, the active one is highlighted, and the rest are muted.</p></div>
|
|
<span class="demo-case-number">01</span>
|
|
</header>
|
|
<div class="demo-workbench">
|
|
<div id="stepper-demo-1" class="demo-canvas demo-canvas--1">
|
|
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
|
|
|
|
<div class="demo-render"><Stepper size="default" steps='[{"label":"Account","description":"Your details"},{"label":"Billing","description":"Payment method"},{"label":"Confirm","description":"Review and submit"}]' active="1" clickable="false" label="Stepper" showPanel="false" controls="false" allowSkip="false" nextDisabled="false" backLabel="Back" nextLabel="Next" skipLabel="Skip" finishLabel="Finish" class="showcase-instance showcase-instance--1" /></div>
|
|
</div>
|
|
<section class="demo-code" aria-label="Horizontal progress usage">
|
|
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
|
|
<pre><code><Stepper
|
|
steps='[
|
|
<span>{</span>
|
|
"label": "Account",
|
|
"description": "Your details"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Billing",
|
|
"description": "Payment method"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Confirm",
|
|
"description": "Review and submit"
|
|
<span>}</span>
|
|
]'
|
|
active="1"
|
|
label="Stepper">
|
|
<div data-slot="step-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">step-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
<div data-slot="panel-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">panel-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
</Stepper></code></pre>
|
|
</section>
|
|
</div>
|
|
</article>
|
|
<article class="demo-case">
|
|
<header class="demo-case-header">
|
|
<div><span class="demo-case-eyebrow">Recommended</span><h2>Vertical with icons</h2><p>Vertical orientation suits a sidebar or a narrow column. Any step may carry an iconify class instead of its number.</p></div>
|
|
<span class="demo-case-number">02</span>
|
|
</header>
|
|
<div class="demo-workbench">
|
|
<div id="stepper-demo-2" class="demo-canvas demo-canvas--2">
|
|
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
|
|
|
|
<div class="demo-render"><Stepper size="sm" steps='[{"label":"Cloned","icon":"icon-[lucide--git-branch]"},{"label":"Built","icon":"icon-[lucide--hammer]"},{"label":"Deployed","icon":"icon-[lucide--rocket]"}]' active="2" orientation="vertical" clickable="false" label="Compact example" showPanel="false" controls="false" allowSkip="false" nextDisabled="false" backLabel="Back" nextLabel="Next" skipLabel="Skip" finishLabel="Finish" class="showcase-instance showcase-instance--2" /></div>
|
|
</div>
|
|
<section class="demo-code" aria-label="Vertical with icons usage">
|
|
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
|
|
<pre><code><Stepper
|
|
size="sm"
|
|
steps='[
|
|
<span>{</span>
|
|
"label": "Cloned",
|
|
"icon": "icon-[lucide--git-branch]"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Built",
|
|
"icon": "icon-[lucide--hammer]"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Deployed",
|
|
"icon": "icon-[lucide--rocket]"
|
|
<span>}</span>
|
|
]'
|
|
active="2"
|
|
orientation="vertical"
|
|
label="Compact example">
|
|
<div data-slot="step-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">step-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
<div data-slot="panel-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">panel-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
</Stepper></code></pre>
|
|
</section>
|
|
</div>
|
|
</article>
|
|
<article class="demo-case">
|
|
<header class="demo-case-header">
|
|
<div><span class="demo-case-eyebrow">Advanced</span><h2>Wizard with content and controls</h2><p>showPanel renders each step body and shows only the active one, the same contract Tabs uses. controls adds Back, Skip and Next, which becomes Finish on the last step. nextDisabled is how a form holds the step: the component never validates anything itself, so the page sets it while the step is incomplete and clears it once the step passes.</p></div>
|
|
<span class="demo-case-number">03</span>
|
|
</header>
|
|
<div class="demo-workbench">
|
|
<div id="stepper-demo-3" class="demo-canvas demo-canvas--3">
|
|
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
|
|
|
|
<div class="demo-render"><Stepper size="lg" steps='[{"label":"Account","title":"Your details","content":"Name, email and a password."},{"label":"Billing","title":"How you pay","content":"Card or invoice, plus a billing address."},{"label":"Confirm","title":"Review","content":"Check everything before submitting."}]' active="1" clickable="false" label="Advanced example" showPanel="true" controls="true" allowSkip="true" nextDisabled="false" backLabel="Back" nextLabel="Next" skipLabel="Skip" finishLabel="Finish" class="showcase-instance showcase-instance--3" /></div>
|
|
</div>
|
|
<section class="demo-code" aria-label="Wizard with content and controls usage">
|
|
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
|
|
<pre><code><Stepper
|
|
size="lg"
|
|
steps='[
|
|
<span>{</span>
|
|
"label": "Account",
|
|
"title": "Your details",
|
|
"content": "Name, email and a password."
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Billing",
|
|
"title": "How you pay",
|
|
"content": "Card or invoice, plus a billing address."
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Confirm",
|
|
"title": "Review",
|
|
"content": "Check everything before submitting."
|
|
<span>}</span>
|
|
]'
|
|
active="1"
|
|
label="Advanced example"
|
|
showPanel="true"
|
|
controls="true"
|
|
allowSkip="true">
|
|
<div data-slot="step-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">step-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
<div data-slot="panel-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">panel-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
</Stepper></code></pre>
|
|
</section>
|
|
</div>
|
|
</article>
|
|
<article class="demo-case">
|
|
<header class="demo-case-header">
|
|
<div><span class="demo-case-eyebrow">Advanced</span><h2>Held until the step is valid</h2><p>The same wizard with nextDisabled set. Next stays held, so a form can keep the reader on the step until it validates.</p></div>
|
|
<span class="demo-case-number">04</span>
|
|
</header>
|
|
<div class="demo-workbench">
|
|
<div id="stepper-demo-4" class="demo-canvas demo-canvas--4">
|
|
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
|
|
|
|
<div class="demo-render"><Stepper size="lg" steps='[{"label":"Account","title":"Your details","content":"This step has not been completed yet."},{"label":"Billing","title":"How you pay","content":"Card or invoice."}]' active="0" clickable="false" label="Advanced example" showPanel="true" controls="true" allowSkip="false" nextDisabled="true" backLabel="Back" nextLabel="Next" skipLabel="Skip" finishLabel="Finish" class="showcase-instance showcase-instance--4" /></div>
|
|
</div>
|
|
<section class="demo-code" aria-label="Held until the step is valid usage">
|
|
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
|
|
<pre><code><Stepper
|
|
size="lg"
|
|
steps='[
|
|
<span>{</span>
|
|
"label": "Account",
|
|
"title": "Your details",
|
|
"content": "This step has not been completed yet."
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Billing",
|
|
"title": "How you pay",
|
|
"content": "Card or invoice."
|
|
<span>}</span>
|
|
]'
|
|
label="Advanced example"
|
|
showPanel="true"
|
|
controls="true"
|
|
nextDisabled="true">
|
|
<div data-slot="step-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">step-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
<div data-slot="panel-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">panel-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
</Stepper></code></pre>
|
|
</section>
|
|
</div>
|
|
</article>
|
|
<article class="demo-case">
|
|
<header class="demo-case-header">
|
|
<div><span class="demo-case-eyebrow">Advanced</span><h2>Clickable steps</h2><p>With clickable the steps emit a change output and take arrow-key roving focus. Without it the stepper is read-only and stays out of the tab order.</p></div>
|
|
<span class="demo-case-number">05</span>
|
|
</header>
|
|
<div class="demo-workbench">
|
|
<div id="stepper-demo-5" class="demo-canvas demo-canvas--5">
|
|
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
|
|
|
|
<div class="demo-render"><Stepper size="lg" steps='[{"label":"One"},{"label":"Two"},{"label":"Three"}]' active="0" clickable="true" label="Advanced example" showPanel="false" controls="false" allowSkip="false" nextDisabled="false" backLabel="Back" nextLabel="Next" skipLabel="Skip" finishLabel="Finish" class="showcase-instance showcase-instance--5" /></div>
|
|
</div>
|
|
<section class="demo-code" aria-label="Clickable steps usage">
|
|
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
|
|
<pre><code><Stepper
|
|
size="lg"
|
|
steps='[
|
|
<span>{</span>
|
|
"label": "One"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Two"
|
|
<span>}</span>,
|
|
<span>{</span>
|
|
"label": "Three"
|
|
<span>}</span>
|
|
]'
|
|
clickable="true"
|
|
label="Advanced example">
|
|
<div data-slot="step-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">step-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
<div data-slot="panel-<span>{</span>index<span>}</span>">
|
|
<div class="showcase-slot">panel-<span>{</span>index<span>}</span> slot</div>
|
|
</div>
|
|
</Stepper></code></pre>
|
|
</section>
|
|
</div>
|
|
</article></div></section>
|
|
<section id="events" class="detail-section"><div class="detail-section-heading"><span>Component outputs</span><h2>Receive every typed component output</h2><p>Use declarative output handlers in <code>.wrn</code> files or register a direct output handler from JavaScript. The canonical API exposes <code>payload</code> and does not require <code>event.detail</code>.</p></div><div class="detail-events-grid"><div class="detail-events-list"><div><code>@change</code><span>Fires when the component's committed value or selection changes.</span></div><div><code>@back</code><span>Fires when the component emits the back event.</span></div><div><code>@next</code><span>Fires when the component emits the next event.</span></div><div><code>@skip</code><span>Fires when the component emits the skip event.</span></div><div><code>@finish</code><span>Fires when the component emits the finish event.</span></div></div><div class="detail-event-examples"><section class="demo-code"><header><span><span class="icon-[lucide--braces] size-4" aria-hidden="true"></span>Declarative handlers</span><small>.wrn</small></header><pre><code><Stepper
|
|
@change='console.log(payload)'
|
|
@back='console.log(payload)'
|
|
@next='console.log(payload)'
|
|
@skip='console.log(payload)'
|
|
@finish='console.log(payload)'
|
|
/></code></pre></section><section class="demo-code"><header><span><span class="icon-[lucide--radio] size-4" aria-hidden="true"></span>Direct output handlers</span><small>.js</small></header><pre><code>import <span>{</span> registerOutputHandler <span>}</span> from "@wrnexus/csr/outputs"
|
|
|
|
const component = document.querySelector("[data-ui-component=\"Stepper\"], [data-component=\"Stepper\"]")
|
|
|
|
if (component) registerOutputHandler(component, "change", (payload) => <span>{</span>
|
|
console.log("change", payload)
|
|
<span>}</span>)
|
|
|
|
if (component) registerOutputHandler(component, "back", (payload) => <span>{</span>
|
|
console.log("back", payload)
|
|
<span>}</span>)
|
|
|
|
if (component) registerOutputHandler(component, "next", (payload) => <span>{</span>
|
|
console.log("next", payload)
|
|
<span>}</span>)
|
|
|
|
if (component) registerOutputHandler(component, "skip", (payload) => <span>{</span>
|
|
console.log("skip", payload)
|
|
<span>}</span>)
|
|
|
|
if (component) registerOutputHandler(component, "finish", (payload) => <span>{</span>
|
|
console.log("finish", payload)
|
|
<span>}</span>)</code></pre></section></div></div></section>
|
|
<section id="api" class="detail-section"><div class="detail-section-heading"><span>Component API</span><h2>Props and configuration</h2><p>All content and behavior shown above is supplied through these props and slots.</p></div><div class="docs-table-wrap"><table class="docs-table"><thead><tr><th>Prop</th><th>Type</th><th>Default</th><th>Required</th></tr></thead><tbody><tr><td><code>color</code></td><td>string</td><td><code>"primary"</code></td><td>No</td></tr><tr><td><code>size</code></td><td>string</td><td><code>"default"</code></td><td>No</td></tr><tr><td><code>steps</code></td><td>unknown[]</td><td><code>[]</code></td><td>No</td></tr><tr><td><code>active</code></td><td>number</td><td><code>0</code></td><td>No</td></tr><tr><td><code>orientation</code></td><td>string</td><td><code>"horizontal"</code></td><td>No</td></tr><tr><td><code>clickable</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>label</code></td><td>string</td><td><code>"Progress"</code></td><td>No</td></tr><tr><td><code>showPanel</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>controls</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>allowSkip</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>nextDisabled</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>backLabel</code></td><td>string</td><td><code>"Back"</code></td><td>No</td></tr><tr><td><code>nextLabel</code></td><td>string</td><td><code>"Next"</code></td><td>No</td></tr><tr><td><code>skipLabel</code></td><td>string</td><td><code>"Skip"</code></td><td>No</td></tr><tr><td><code>finishLabel</code></td><td>string</td><td><code>"Finish"</code></td><td>No</td></tr><tr><td><code>class</code></td><td>string</td><td><code>""</code></td><td>No</td></tr></tbody></table></div></section>
|
|
</main>
|
|
<aside class="detail-aside">
|
|
<div class="detail-toc"><strong>On this page</strong><a href="#playground">Playground</a><a href="#stepper-demo-1">Horizontal progress</a><a href="#stepper-demo-2">Vertical with icons</a><a href="#stepper-demo-3">Wizard with content and controls</a><a href="#stepper-demo-4">Held until the step is valid</a><a href="#stepper-demo-5">Clickable steps</a><a href="#events">Outputs</a><a href="#api">Props API</a></div>
|
|
</aside>
|
|
</div>
|
|
<nav class="detail-pagination">
|
|
<a href="/components/sidebar"><small>Previous</small><strong>← Sidebar</strong></a>
|
|
<a href="/components/tabs"><small>Next</small><strong>Tabs →</strong></a>
|
|
</nav>
|
|
}
|
|
}
|