import { html, type TemplateResult } from 'lit'; import { formatUsageFromDefaults, type PlaygroundControl, type PlaygroundDefinition, type PlaygroundPreviewHandlers, type PlaygroundProps, whenBoolean, whenString, } from '../types.js'; const ATTRIBUTE_NAMES: Record = { integerOnly: 'integer-only', ariaLabel: 'aria-label', ariaLabelledby: 'aria-labelledby', nuiType: 'nui-type', otpClass: 'otp-class', inputClass: 'input-class', }; export const NUI_INPUT_OTP_DEFAULTS: PlaygroundProps = { value: '', length: '4', mask: false, integerOnly: false, disabled: false, readonly: false, invalid: false, tabindex: '0', size: '', variant: '', fluid: false, unstyled: false, nuiType: '', otpClass: '', inputClass: '', ariaLabel: 'One-time code', ariaLabelledby: '', }; const CONTROLS: PlaygroundControl[] = [ { key: 'value', label: 'value', type: 'text', section: 'Content', placeholder: '1234', }, { key: 'otpClass', label: 'otp-class', type: 'text', section: 'Content', }, { key: 'inputClass', label: 'input-class', type: 'text', section: 'Content', }, { key: 'size', label: 'size', type: 'select', section: 'Appearance', options: [ { value: '', label: '(default)' }, { value: 'small', label: 'small' }, { value: 'large', label: 'large' }, ], }, { key: 'variant', label: 'variant', type: 'select', section: 'Appearance', options: [ { value: '', label: '(default)' }, { value: 'outlined', label: 'outlined' }, { value: 'filled', label: 'filled' }, ], }, { key: 'nuiType', label: 'nui-type', type: 'text', section: 'Appearance' }, { key: 'mask', label: 'mask', type: 'boolean', section: 'Modifiers' }, { key: 'integerOnly', label: 'integer-only', type: 'boolean', section: 'Modifiers', }, { key: 'unstyled', label: 'unstyled', type: 'boolean', section: 'Modifiers', }, { key: 'length', label: 'length', type: 'text', section: 'Layout', placeholder: '4', }, { key: 'fluid', label: 'fluid', type: 'boolean', section: 'Layout' }, { key: 'disabled', label: 'disabled', type: 'boolean', section: 'State' }, { key: 'readonly', label: 'readonly', type: 'boolean', section: 'State' }, { key: 'invalid', label: 'invalid', type: 'boolean', section: 'State' }, { key: 'tabindex', label: 'tabindex', type: 'text', section: 'HTML', placeholder: '0', }, { key: 'ariaLabel', label: 'aria-label', type: 'text', section: 'HTML', }, { key: 'ariaLabelledby', label: 'aria-labelledby', type: 'text', section: 'HTML', }, ]; function handleInputOtpChange( event: Event, handlers?: PlaygroundPreviewHandlers, ): void { if (!handlers) { return; } const value = (event as CustomEvent<{ value: string }>).detail.value; handlers.onPropChange('value', value); } function renderPreview( props: PlaygroundProps, handlers?: PlaygroundPreviewHandlers, ): TemplateResult { const length = Math.max(1, Number(props.length) || 4); return html` handleInputOtpChange(event, handlers)} > `; } export const nuiInputOtpPlayground: PlaygroundDefinition = { tag: 'nui-input-otp', label: 'Input OTP', description: 'One-time password input with per-digit fields, paste support, and keyboard navigation.', defaults: NUI_INPUT_OTP_DEFAULTS, controls: CONTROLS, renderPreview, formatUsage: (props) => formatUsageFromDefaults( 'nui-input-otp', props, NUI_INPUT_OTP_DEFAULTS, ATTRIBUTE_NAMES, ), };