Files

478 lines
42 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Generated by scripts/generate-showcase.mjs. Do not edit directly.
page PinInputDetail {
layout = "showcase"
state playground_size = ctx.url.searchParams.get("pg_size") ?? "default"
state playground_color = ctx.url.searchParams.get("pg_color") ?? "primary"
state playground_label = ctx.url.searchParams.get("pg_label") ?? "Default four-digit PIN"
state playground_name = ctx.url.searchParams.get("pg_name") ?? "pin-input-1"
state playground_value = ctx.url.searchParams.get("pg_value") ?? ""
state playground_length = Number(ctx.url.searchParams.get("pg_length") ?? "4")
state playground_pattern = ctx.url.searchParams.get("pg_pattern") ?? "[0-9]"
state playground_type = ctx.url.searchParams.get("pg_type") ?? "text"
state playground_inputMode = ctx.url.searchParams.get("pg_inputMode") ?? "numeric"
state playground_placeholder = ctx.url.searchParams.get("pg_placeholder") ?? "○"
state playground_autocomplete = ctx.url.searchParams.get("pg_autocomplete") ?? "one-time-code"
state playground_masked = (ctx.url.searchParams.get("pg_masked") ?? "false") === "true"
state playground_disabled = (ctx.url.searchParams.get("pg_disabled") ?? "false") === "true"
state playground_readonly = (ctx.url.searchParams.get("pg_readonly") ?? "false") === "true"
state playground_required = (ctx.url.searchParams.get("pg_required") ?? "false") === "true"
state playground_autoFocus = (ctx.url.searchParams.get("pg_autoFocus") ?? "false") === "true"
state playground_autoSubmit = (ctx.url.searchParams.get("pg_autoSubmit") ?? "false") === "true"
state playground_allowPaste = (ctx.url.searchParams.get("pg_allowPaste") ?? "true") === "true"
state playground_clearable = (ctx.url.searchParams.get("pg_clearable") ?? "true") === "true"
state playground_clearLabel = ctx.url.searchParams.get("pg_clearLabel") ?? "Clear code"
state playground_separator = ctx.url.searchParams.get("pg_separator") ?? ""
state playground_groupSize = Number(ctx.url.searchParams.get("pg_groupSize") ?? "0")
state playground_helpText = ctx.url.searchParams.get("pg_helpText") ?? ""
state playground_invalid = (ctx.url.searchParams.get("pg_invalid") ?? "false") === "true"
state playground_validationMessage = ctx.url.searchParams.get("pg_validationMessage") ?? ""
state playground_class = ctx.url.searchParams.get("pg_class") ?? ""
seo {
title = "Pin Input"
description = "Secure multi-cell PIN and verification-code input with regex and paste support."
}
view {
<nav class="docs-breadcrumbs" aria-label="Breadcrumb">
<a href="/">Components</a><span aria-hidden="true">/</span><a href="/advanced-forms">Advanced Forms</a><span aria-hidden="true">/</span><span>Pin Input</span>
</nav>
<header class="detail-hero">
<div class="detail-hero-copy">
<span class="showcase-eyebrow">Advanced Forms component</span>
<h1>Pin Input</h1>
<p>Secure multi-cell PIN and verification-code input with regex and paste support.</p>
<div class="detail-badges"><span>26 props</span><span>0 slots</span><span>6 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="PinInput" data-playground-public-tag="true" data-playground-has-slot="false" data-playground-events="input,change,complete,paste,clear,error">
<div class="detail-section-heading"><span>Interactive playground</span><h2>Configure Pin Input</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><PinInput size='{playground_size}' color='{playground_color}' label='{playground_label}' name='{playground_name}' value='{playground_value}' length='{playground_length}' pattern='{playground_pattern}' type='{playground_type}' inputMode='{playground_inputMode}' placeholder='{playground_placeholder}' autocomplete='{playground_autocomplete}' masked='{playground_masked}' disabled='{playground_disabled}' readonly='{playground_readonly}' required='{playground_required}' autoFocus='{playground_autoFocus}' autoSubmit='{playground_autoSubmit}' allowPaste='{playground_allowPaste}' clearable='{playground_clearable}' clearLabel='{playground_clearLabel}' separator='{playground_separator}' groupSize='{playground_groupSize}' helpText='{playground_helpText}' invalid='{playground_invalid}' validationMessage='{playground_validationMessage}' 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>&lt;PinInput
label="Default four-digit PIN"
name="pin-input-1"
/&gt;</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>26 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-pin-input-size"><span><strong>size</strong><small>string</small></span><select id="playground-pin-input-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-pin-input-color"><span><strong>color</strong><small>string</small></span><select id="playground-pin-input-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-pin-input-label"><span><strong>label</strong><small>string</small></span><input id="playground-pin-input-label" name="pg_label" type="text" value="Default four-digit PIN" /></label><label class="playground-field" for="playground-pin-input-name"><span><strong>name</strong><small>string</small></span><input id="playground-pin-input-name" name="pg_name" type="text" value="pin-input-1" /></label><label class="playground-field" for="playground-pin-input-value"><span><strong>value</strong><small>string</small></span><input id="playground-pin-input-value" name="pg_value" type="text" value="" /></label><label class="playground-field" for="playground-pin-input-length"><span><strong>length</strong><small>number</small></span><input id="playground-pin-input-length" name="pg_length" type="number" value="4" /></label><label class="playground-field" for="playground-pin-input-pattern"><span><strong>pattern</strong><small>string</small></span><input id="playground-pin-input-pattern" name="pg_pattern" type="text" value="[0-9]" /></label><label class="playground-field" for="playground-pin-input-type"><span><strong>type</strong><small>string</small></span><input id="playground-pin-input-type" name="pg_type" type="text" value="text" /></label><label class="playground-field" for="playground-pin-input-inputMode"><span><strong>input Mode</strong><small>string</small></span><input id="playground-pin-input-inputMode" name="pg_inputMode" type="text" value="numeric" /></label><label class="playground-field" for="playground-pin-input-placeholder"><span><strong>placeholder</strong><small>string</small></span><input id="playground-pin-input-placeholder" name="pg_placeholder" type="text" value="○" /></label><label class="playground-field" for="playground-pin-input-autocomplete"><span><strong>autocomplete</strong><small>string</small></span><input id="playground-pin-input-autocomplete" name="pg_autocomplete" type="text" value="one-time-code" /></label><label class="playground-toggle" for="playground-pin-input-masked"><span><strong>masked</strong><small>boolean</small></span><input id="playground-pin-input-masked" name="pg_masked" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-disabled"><span><strong>disabled</strong><small>boolean</small></span><input id="playground-pin-input-disabled" name="pg_disabled" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-readonly"><span><strong>readonly</strong><small>boolean</small></span><input id="playground-pin-input-readonly" name="pg_readonly" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-required"><span><strong>required</strong><small>boolean</small></span><input id="playground-pin-input-required" name="pg_required" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-autoFocus"><span><strong>auto Focus</strong><small>boolean</small></span><input id="playground-pin-input-autoFocus" name="pg_autoFocus" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-autoSubmit"><span><strong>auto Submit</strong><small>boolean</small></span><input id="playground-pin-input-autoSubmit" name="pg_autoSubmit" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-allowPaste"><span><strong>allow Paste</strong><small>boolean</small></span><input id="playground-pin-input-allowPaste" name="pg_allowPaste" type="checkbox" value="true" checked data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-toggle" for="playground-pin-input-clearable"><span><strong>clearable</strong><small>boolean</small></span><input id="playground-pin-input-clearable" name="pg_clearable" type="checkbox" value="true" checked data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-field" for="playground-pin-input-clearLabel"><span><strong>clear Label</strong><small>string</small></span><input id="playground-pin-input-clearLabel" name="pg_clearLabel" type="text" value="Clear code" /></label><label class="playground-field" for="playground-pin-input-separator"><span><strong>separator</strong><small>string</small></span><input id="playground-pin-input-separator" name="pg_separator" type="text" value="" /></label><label class="playground-field" for="playground-pin-input-groupSize"><span><strong>group Size</strong><small>number</small></span><input id="playground-pin-input-groupSize" name="pg_groupSize" type="number" value="0" /></label><label class="playground-field" for="playground-pin-input-helpText"><span><strong>help Text</strong><small>string</small></span><input id="playground-pin-input-helpText" name="pg_helpText" type="text" value="" /></label><label class="playground-toggle" for="playground-pin-input-invalid"><span><strong>invalid</strong><small>boolean</small></span><input id="playground-pin-input-invalid" name="pg_invalid" type="checkbox" value="true" data-playground-boolean /><i aria-hidden="true"></i></label><label class="playground-field" for="playground-pin-input-validationMessage"><span><strong>validation Message</strong><small>string</small></span><input id="playground-pin-input-validationMessage" name="pg_validationMessage" type="text" value="" /></label><label class="playground-field" for="playground-pin-input-class"><span><strong>class</strong><small>string</small></span><input id="playground-pin-input-class" name="pg_class" type="text" value="" /></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">Entry behavior</span><h2>Default four-digit PIN</h2><p>Live default four-digit pin example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">01</span>
</header>
<div class="demo-workbench">
<div id="pin-input-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"><PinInput size="default" label="Default four-digit PIN" name="pin-input-1" value="" length="4" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Default four-digit PIN usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Default four-digit PIN"
name="pin-input-1"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Entry behavior</span><h2>Different lengths</h2><p>Live different lengths example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">02</span>
</header>
<div class="demo-workbench">
<div id="pin-input-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"><div class="pin-length-demo"><PinInput size="default" label="3-digit code" name="pin-length-3" value="" length="3" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /><PinInput size="default" label="5-digit code" name="pin-length-5" value="" length="5" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /><PinInput size="default" label="7-digit code" name="pin-length-7" value="" length="7" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div></div>
</div>
<section class="demo-code" aria-label="Different lengths usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="3-digit code"
name="pinLength3"
length="3"
/&gt;
&lt;PinInput
label="5-digit code"
name="pinLength5"
length="5"
/&gt;
&lt;PinInput
label="7-digit code"
name="pinLength7"
length="7"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Entry behavior</span><h2>Pre-filled verification code</h2><p>Live pre-filled verification code example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">03</span>
</header>
<div class="demo-workbench">
<div id="pin-input-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"><PinInput size="default" label="Pre-filled verification code" name="pin-input-3" value="482915" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Pre-filled verification code usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Pre-filled verification code"
name="pin-input-3"
value="482915"
length="6"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Entry behavior</span><h2>Masked security PIN</h2><p>Live masked security pin example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">04</span>
</header>
<div class="demo-workbench">
<div id="pin-input-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"><PinInput size="default" label="Masked security PIN" name="pin-input-4" value="" length="4" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="true" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Masked security PIN usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Masked security PIN"
name="pin-input-4"
masked="true"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Entry behavior</span><h2>Alphanumeric regex</h2><p>Live alphanumeric regex example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">05</span>
</header>
<div class="demo-workbench">
<div id="pin-input-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"><PinInput size="default" label="Alphanumeric regex" name="pin-input-5" value="" length="6" pattern="[A-Z0-9]" inputMode="text" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Alphanumeric regex usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Alphanumeric regex"
name="pin-input-5"
length="6"
pattern="[A-Z0-9]"
inputMode="text"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Entry behavior</span><h2>Grouped code with separator</h2><p>Live grouped code with separator example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">06</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-6" class="demo-canvas demo-canvas--6">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Grouped code with separator" name="pin-input-6" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="3" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Grouped code with separator usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Grouped code with separator"
name="pin-input-6"
length="6"
separator=""
groupSize="3"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Entry behavior</span><h2>Paste from clipboard</h2><p>Live paste from clipboard example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">07</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-7" class="demo-canvas demo-canvas--7">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Paste from clipboard" name="pin-input-7" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Paste from clipboard usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Paste from clipboard"
name="pin-input-7"
length="6"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">States & design</span><h2>Disabled PIN input</h2><p>Live disabled pin input example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">08</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-8" class="demo-canvas demo-canvas--8">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Disabled PIN input" name="pin-input-8" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="true" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Disabled PIN input usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Disabled PIN input"
name="pin-input-8"
length="6"
disabled="true"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">States & design</span><h2>Read-only code</h2><p>Live read-only code example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">09</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-9" class="demo-canvas demo-canvas--9">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Read-only code" name="pin-input-9" value="739204" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="true" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Read-only code usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Read-only code"
name="pin-input-9"
value="739204"
length="6"
readonly="true"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">States & design</span><h2>Validation state</h2><p>Live validation state example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">010</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-10" class="demo-canvas demo-canvas--10">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><form data-schema="pin-input-validation" class="demo-validation-form"><PinInput size="default" label="Validation state" name="pin-input-10" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="true" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /><button type="submit" class="wire-btn wire-btn--variant-default">Validate selection</button></form></div>
</div>
<section class="demo-code" aria-label="Validation state usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Validation state"
name="pin-input-10"
length="6"
required="true"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">States & design</span><h2>Supporting help text</h2><p>Live supporting help text example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">011</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-11" class="demo-canvas demo-canvas--11">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Supporting help text" name="pin-input-11" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="Enter the code sent to your registered email address." invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Supporting help text usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Supporting help text"
name="pin-input-11"
length="6"
helpText="Enter the code sent to your registered email address."
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">States & design</span><h2>Large PIN cells</h2><p>Live large pin cells example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">012</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-12" class="demo-canvas demo-canvas--12">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="lg" label="Large PIN cells" name="pin-input-12" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Large PIN cells usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
size="lg"
label="Large PIN cells"
name="pin-input-12"
length="6"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">States & design</span><h2>Custom placeholder</h2><p>Live custom placeholder example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">013</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-13" class="demo-canvas demo-canvas--13">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Custom placeholder" name="pin-input-13" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="•" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Custom placeholder usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Custom placeholder"
name="pin-input-13"
length="6"
placeholder="•"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Automation</span><h2>Automatic form submission</h2><p>Live automatic form submission example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">014</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-14" class="demo-canvas demo-canvas--14">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Automatic form submission" name="pin-input-14" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="true" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Automatic form submission usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Automatic form submission"
name="pin-input-14"
length="6"
autoSubmit="true"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Automation</span><h2>Completion events</h2><p>Live completion events example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">015</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-15" class="demo-canvas demo-canvas--15">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="Completion events" name="pin-input-15" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="Completion events usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="Completion events"
name="pin-input-15"
length="6"
/&gt;</code></pre>
</section>
</div>
</article>
<article class="demo-case">
<header class="demo-case-header">
<div><span class="demo-case-eyebrow">Automation</span><h2>JavaScript methods</h2><p>Live javascript methods example with keyboard navigation, filtering, and copyable component code.</p></div>
<span class="demo-case-number">016</span>
</header>
<div class="demo-workbench">
<div id="pin-input-demo-16" class="demo-canvas demo-canvas--16">
<div class="demo-browser-chrome"><span></span><span></span><span></span><small>Live preview</small></div>
<div class="demo-render"><PinInput size="default" label="JavaScript methods" name="pin-input-16" value="" length="6" pattern="[0-9]" inputMode="numeric" placeholder="○" masked="false" disabled="false" readonly="false" required="false" autoSubmit="false" allowPaste="true" separator="" groupSize="0" helpText="" invalid="false" validationMessage="" /></div>
</div>
<section class="demo-code" aria-label="JavaScript methods usage">
<header><span><span class="icon-[lucide--code-2] size-4" aria-hidden="true"></span>Component usage</span><small>.wrn</small></header>
<pre><code>&lt;PinInput
label="JavaScript methods"
name="pin-input-16"
length="6"
/&gt;</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>@input</code><span>Fires as the editable value changes.</span></div><div><code>@change</code><span>Fires when the component's committed value or selection changes.</span></div><div><code>@complete</code><span>Fires when the component emits the complete event.</span></div><div><code>@paste</code><span>Fires after clipboard content is processed.</span></div><div><code>@clear</code><span>Fires after the current value or selection is cleared.</span></div><div><code>@error</code><span>Fires when the component cannot complete an operation.</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>&lt;PinInput
@input='console.log(payload)'
@change='console.log(payload)'
@complete='console.log(payload)'
@paste='console.log(payload)'
@clear='console.log(payload)'
@error='console.log(payload)'
/&gt;</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>&#123;</span> registerOutputHandler <span>&#125;</span> from "@wrnexus/csr/outputs"
const component = document.querySelector("[data-ui-component=\"PinInput\"], [data-component=\"PinInput\"]")
if (component) registerOutputHandler(component, "input", (payload) =&gt; <span>&#123;</span>
console.log("input", payload)
<span>&#125;</span>)
if (component) registerOutputHandler(component, "change", (payload) =&gt; <span>&#123;</span>
console.log("change", payload)
<span>&#125;</span>)
if (component) registerOutputHandler(component, "complete", (payload) =&gt; <span>&#123;</span>
console.log("complete", payload)
<span>&#125;</span>)
if (component) registerOutputHandler(component, "paste", (payload) =&gt; <span>&#123;</span>
console.log("paste", payload)
<span>&#125;</span>)
if (component) registerOutputHandler(component, "clear", (payload) =&gt; <span>&#123;</span>
console.log("clear", payload)
<span>&#125;</span>)
if (component) registerOutputHandler(component, "error", (payload) =&gt; <span>&#123;</span>
console.log("error", payload)
<span>&#125;</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>size</code></td><td>string</td><td><code>"default"</code></td><td>No</td></tr><tr><td><code>color</code></td><td>string</td><td><code>"primary"</code></td><td>No</td></tr><tr><td><code>label</code></td><td>string</td><td><code>"Verification code"</code></td><td>No</td></tr><tr><td><code>name</code></td><td>string</td><td><code>"pin"</code></td><td>No</td></tr><tr><td><code>value</code></td><td>string</td><td><code>""</code></td><td>No</td></tr><tr><td><code>length</code></td><td>number</td><td><code>4</code></td><td>No</td></tr><tr><td><code>pattern</code></td><td>string</td><td><code>"[0-9]"</code></td><td>No</td></tr><tr><td><code>type</code></td><td>string</td><td><code>"text"</code></td><td>No</td></tr><tr><td><code>inputMode</code></td><td>string</td><td><code>"numeric"</code></td><td>No</td></tr><tr><td><code>placeholder</code></td><td>string</td><td><code>"○"</code></td><td>No</td></tr><tr><td><code>autocomplete</code></td><td>string</td><td><code>"one-time-code"</code></td><td>No</td></tr><tr><td><code>masked</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>disabled</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>readonly</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>required</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>autoFocus</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>autoSubmit</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>allowPaste</code></td><td>boolean</td><td><code>true</code></td><td>No</td></tr><tr><td><code>clearable</code></td><td>boolean</td><td><code>true</code></td><td>No</td></tr><tr><td><code>clearLabel</code></td><td>string</td><td><code>"Clear code"</code></td><td>No</td></tr><tr><td><code>separator</code></td><td>string</td><td><code>""</code></td><td>No</td></tr><tr><td><code>groupSize</code></td><td>number</td><td><code>0</code></td><td>No</td></tr><tr><td><code>helpText</code></td><td>string</td><td><code>""</code></td><td>No</td></tr><tr><td><code>invalid</code></td><td>boolean</td><td><code>false</code></td><td>No</td></tr><tr><td><code>validationMessage</code></td><td>string</td><td><code>""</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="#pin-input-demo-1">Default four-digit PIN</a><a href="#pin-input-demo-2">Different lengths</a><a href="#pin-input-demo-3">Pre-filled verification code</a><a href="#pin-input-demo-4">Masked security PIN</a><a href="#pin-input-demo-5">Alphanumeric regex</a><a href="#pin-input-demo-6">Grouped code with separator</a><a href="#pin-input-demo-7">Paste from clipboard</a><a href="#pin-input-demo-8">Disabled PIN input</a><a href="#pin-input-demo-9">Read-only code</a><a href="#pin-input-demo-10">Validation state</a><a href="#pin-input-demo-11">Supporting help text</a><a href="#pin-input-demo-12">Large PIN cells</a><a href="#pin-input-demo-13">Custom placeholder</a><a href="#pin-input-demo-14">Automatic form submission</a><a href="#pin-input-demo-15">Completion events</a><a href="#pin-input-demo-16">JavaScript methods</a><a href="#events">Outputs</a><a href="#api">Props API</a></div>
</aside>
</div>
<nav class="detail-pagination">
<a href="/components/input-number"><small>Previous</small><strong>← Input Number</strong></a>
<a href="/components/strong-password"><small>Next</small><strong>Strong Password →</strong></a>
</nav>
}
}