component PinInput { outputs { input(payload: { value?: string | number | boolean | null; values?: Array; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null) change(payload: { value?: string | number | boolean | null; values?: Array; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null) complete(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object }) paste(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[]) clear(payload: { value?: string | number | boolean | null; values?: Array; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null) error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string) } props { size: string = "default" color: string = "primary" label: string = "Verification code" name: string = "pin" value: string = "" length: number = 4 pattern: string = "[0-9]" type: string = "text" inputMode: string = "numeric" placeholder: string = "○" autocomplete: string = "one-time-code" masked: boolean = false disabled: boolean = false readonly: boolean = false required: boolean = false autoFocus: boolean = false autoSubmit: boolean = false allowPaste: boolean = true clearable: boolean = true clearLabel: string = "Clear code" separator: string = "" groupSize: number = 0 helpText: string = "" invalid: boolean = false validationMessage: string = "" class: string = "" } functions { shared function inputIndexes() { return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].slice( 0, Math.max(1, Math.min(12, Number(length))) ) } } view {
{label}
{#each inputIndexes() as index} {#if separator && groupSize !== 0 && (index + 1) % groupSize === 0 && index + 1 !== length} {/if} {/each}
{#if helpText && !validationMessage}{helpText}{/if} {validationMessage}
} style { .wire-next--pin-input.wire-next--invalid .wire-next__pin-cells input, .wire-next--pin-input:has(input.wire-invalid) .wire-next__pin-cells input { border-color: var(--wire-color-danger); } .wire-next--pin-input { display: grid; width: 100%; min-width: 0; gap: 0.65rem; padding: 0; border: 0; color: var(--wire-color-text); } .wire-next__pin-heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; } .wire-next__pin-heading legend { padding: 0; font-size: 0.82em; font-weight: 700; } .wire-next__pin-clear { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0; border: 0; color: var(--wire-component-color); background: transparent; font: inherit; font-size: 0.7em; font-weight: 750; cursor: pointer; } .wire-next__pin-clear > span:first-child { width: 0.9rem; height: 0.9rem; } .wire-next__pin-cells { display: flex; max-width: 100%; align-items: center; gap: clamp(0.35rem, 1.5vw, 0.65rem); overflow-x: auto; padding: 0.2rem; scrollbar-width: thin; } .wire-next--pin-input .wire-next__pin-cells input { flex: 0 0 clamp(2.4rem, 8vw, 3.25rem); width: clamp(2.4rem, 8vw, 3.25rem); height: clamp(2.75rem, 9vw, 3.5rem); min-width: clamp(2.4rem, 8vw, 3.25rem); padding: 0; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius-sm); color: var(--wire-color-text); background: var(--wire-color-bg); font: inherit; font-size: clamp(1rem, 3vw, 1.25rem); font-weight: 750; text-align: center; caret-color: var(--wire-component-color); transition: border-color var(--wire-motion-base) var(--wire-ease-standard), box-shadow var(--wire-motion-base) var(--wire-ease-standard), transform var(--wire-motion-fast) var(--wire-ease-standard); } .wire-next--pin-input .wire-next__pin-cells input::placeholder { color: var(--wire-color-muted); opacity: 0.45; } .wire-next--pin-input .wire-next__pin-cells input:focus-visible { border-color: var(--wire-component-color); outline: 0; box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-component-color) 18%, transparent); transform: translateY(-1px); } .wire-next--pin-input .wire-next__pin-cells input:disabled, .wire-next--pin-input .wire-next__pin-cells input:read-only { cursor: not-allowed; opacity: 0.55; } .wire-next__pin-separator { color: var(--wire-color-muted); font-size: 1.1rem; font-weight: 800; } .wire-next--pin-input[data-complete="true"] .wire-next__pin-cells input { border-color: color-mix(in srgb, var(--wire-component-color) 72%, var(--wire-color-border)); background: color-mix(in srgb, var(--wire-component-color) 7%, var(--wire-color-bg)); } @media (max-width: 480px) { .wire-next__pin-cells { gap: 0.3rem; } .wire-next--pin-input .wire-next__pin-cells input { flex-basis: min(2.7rem, 12vw); width: min(2.7rem, 12vw); min-width: min(2.7rem, 12vw); height: min(3rem, 14vw); } } /* Shared component foundation. */ .wire-component { --wire-component-color: var(--wire-color-primary); --wire-component-scale: 1; margin: 0; color: var(--wire-color-text); font-family: var(--wrn-font-sans, inherit); } .wire-component--color-primary { --wire-component-color: var(--wire-color-primary); } .wire-component--color-secondary { --wire-component-color: var(--wire-color-secondary); } .wire-component--color-success { --wire-component-color: var(--wire-color-success); } .wire-component--color-warning { --wire-component-color: var(--wire-color-warning); } .wire-component--color-danger { --wire-component-color: var(--wire-color-danger); } .wire-component--color-info { --wire-component-color: var(--wire-color-info); } .wire-component--size-xs { --wire-component-scale: 0.78; } .wire-component--size-sm { --wire-component-scale: 0.88; } .wire-component--size-default, .wire-component--size-md { --wire-component-scale: 1; } .wire-component--size-lg { --wire-component-scale: 1.14; } .wire-component--size-xl { --wire-component-scale: 1.28; } .wire-component:not(.wire-btn) { font-size: calc(1em * var(--wire-component-scale)); } .wire-component :is(a, button, input, select, textarea):focus-visible { outline-color: var(--wire-component-color); } .wire-component p { margin: 0; color: var(--wire-color-muted); line-height: 1.6; } } }