@spark-ui/components 13.1.0 → 13.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react/jsx-runtime"),Z=require("../index-DnaHaH_0.js"),a=require("react"),ie=require("../form-field/index.js"),oe=require("../Icon-Bf0XrmiR.js"),ce=require("@spark-ui/icons/Minus"),L=a.createContext(null),le=()=>{const e=a.useContext(L);if(!e)throw new Error("InputOTP components must be used within InputOTP");return e},H=Z.cva(["relative","border-sm first:rounded-l-lg last:rounded-r-lg","size-sz-44","text-center text-body-1","text-on-surface","outline-hidden","transition-colors","flex items-center justify-center","data-[active=true]:ring-1","data-[active=true]:ring-inset","data-[active=true]:ring-l-2","data-[active=true]:border-focus","data-[active=true]:z-raised ring-focus","data-[disabled=true]:cursor-not-allowed","data-[disabled=true]:border-outline","data-[disabled=true]:bg-on-surface/dim-5","data-[disabled=true]:text-on-surface/dim-3"],{variants:{intent:{neutral:["bg-surface border-outline"],success:["border-success bg-success-container text-on-success-container"],alert:["border-alert bg-alert-container text-on-alert-container"],error:["border-error bg-error-container text-on-error-container"]}},defaultVariants:{intent:"neutral"}}),ue=H,A=({index:e,className:i,...t})=>{const c=le(),s=e??0,u=c.slots[s];if(!u)return null;const{char:b,isActive:v,hasFakeCaret:y}=u,I=!b&&!y&&c.placeholder;return f.jsxs("div",{className:H({intent:c.intent,className:i}),"data-active":v,"data-disabled":c.disabled,"data-valid":c.intent!=="error",...t,children:[f.jsx("span",{className:I?"text-on-surface/dim-3":"",children:c.type==="password"&&b?"•":b||(!y&&c.placeholder?c.placeholder:"")}),y&&f.jsx("span",{className:"pointer-events-none absolute inset-0 flex items-center justify-center","aria-hidden":"true",children:f.jsx("span",{className:"bg-on-surface animate-standalone-caret-blink h-sz-24 w-px"})})]})};A.displayName="InputOTP.Slot";const de="Backspace",pe="ArrowLeft",fe="ArrowUp",be="ArrowRight",xe="ArrowDown",me="e",ve=({maxLength:e,type:i,value:t,defaultValue:c,onValueChange:s,isValid:u,disabledProp:b,autoFocus:v,forceUppercase:y,filterKeys:O,pattern:I,placeholder:C,nameProp:V})=>{const z=a.useId(),r=a.useRef(null),B=a.useRef(null),l=ie.useFormFieldControl(),T=l.id??z,k=V??l.name,h=l.disabled??b,D=l.isInvalid??!u,W=l.isRequired??!1,Y=l.labelId,_=l.description,S=l.state,w=["success","alert","error"].includes(S??"")?S:D?"error":"neutral",P=t!==void 0?t:c,q=y?P.toUpperCase():P,[$,R]=a.useState(q),[E,M]=a.useState(!1),d=t!==void 0?t:$,x=Math.min(d.length,e-1);a.useEffect(()=>{r.current&&r.current.setSelectionRange(x,x)},[x,d.length,e]);const F=a.useMemo(()=>Array.from({length:e},(o,n)=>({char:d[n]||"",isActive:n===x&&E,hasFakeCaret:n===x&&!d[n]&&!h&&E})),[e,d,x,E,h]);a.useEffect(()=>{r.current&&t!==void 0&&(r.current.value=t)},[t]),a.useEffect(()=>{v&&r.current&&r.current.focus()},[v]);const N=o=>{let n=o;if(y&&(n=n.toUpperCase()),i==="number"&&(n=n.replace(/[^\d]/g,"")),I)try{let m=I;I.startsWith("^")||(m=`^${I}$`);const p=new RegExp(m);n=n.split("").filter(g=>p.test(g)).join("")}catch(m){console.error("Invalid pattern provided to InputOTP:",I,m)}return n};return{uuid:T,inputRef:r,containerRef:B,name:k,disabled:h,isInvalid:D,isRequired:W,description:_,maxLength:e,intent:w,currentValue:d,activeIndex:x,slots:F,contextValue:{value:d,maxLength:e,slots:F,activeIndex:x,intent:w,disabled:h,placeholder:C,type:i},handleChange:o=>{if(h)return;const n=o.target.value,p=N(n).slice(0,e);s&&s(p),t===void 0&&R(p);const g=Math.min(p.length,e-1);r.current&&r.current.setSelectionRange(g,g)},handleKeyDown:o=>{if(!h){if(O.length>0&&O.includes(o.key)){o.preventDefault();return}switch(o.key){case de:o.preventDefault();const n=d.length;if(n>0){const m=d.slice(0,n-1);s&&s(m),t===void 0&&R(m);const p=Math.max(0,m.length);r.current&&r.current.setSelectionRange(p,p)}break;case pe:case be:o.preventDefault();break;case fe:case xe:o.preventDefault();break;case me:case"E":i==="number"&&o.preventDefault();break}}},handlePaste:o=>{if(h)return;o.preventDefault();const n=o.clipboardData.getData("text");if(!n)return;const p=N(n).slice(0,e);s&&s(p),t===void 0&&R(p);const g=Math.min(p.length,e-1);r.current&&r.current.setSelectionRange(g,g)},handleFocus:()=>{if(M(!0),r.current){const o=Math.min(d.length,e-1);r.current.setSelectionRange(o,o)}},handleBlur:()=>{M(!1)},handleClick:()=>{r.current&&r.current.focus()},labelId:Y}},ee=e=>{let i=0;return a.Children.forEach(e,t=>{if(a.isValidElement(t)){const c=t.props;t.type===A||t.type?.displayName==="InputOTP.Slot"?i++:c.children&&(i+=ee(c.children))}}),i},te=(e,i=0)=>{let t=i;return[a.Children.map(e,s=>{if(a.isValidElement(s)){const u=s.props;if(s.type===A||s.type?.displayName==="InputOTP.Slot"){const b=typeof u.index=="number"?u.index:t++;return a.cloneElement(s,{...u,index:b})}else if(u.children){const[b,v]=te(u.children,t);return t=v,a.cloneElement(s,{...s.props,children:b})}}return s}),t]},ne=({maxLength:e,type:i="text",value:t,defaultValue:c="",onValueChange:s,isValid:u=!0,disabled:b=!1,autoFocus:v=!1,autoComplete:y="off",forceUppercase:O=!1,filterKeys:I=["-","."],pattern:C,inputMode:V,placeholder:z="",name:r,className:B,children:l,...T})=>{const k=a.useMemo(()=>{if(e!==void 0)return e;const j=ee(l);return j>0?j:4},[e,l]),h=a.useMemo(()=>{const[j]=te(l);return j},[l]),{uuid:D,inputRef:W,containerRef:Y,name:_,disabled:S,isInvalid:G,isRequired:w,description:P,currentValue:q,contextValue:$,handleChange:R,handleKeyDown:E,handlePaste:M,handleFocus:d,handleBlur:x,handleClick:F,labelId:N}=ve({maxLength:k,type:i,value:t,defaultValue:c,onValueChange:s,isValid:u,disabledProp:b,autoFocus:v,forceUppercase:O,filterKeys:I,pattern:C,placeholder:z,nameProp:r}),U="aria-label"in T?T["aria-label"]:void 0,{"aria-label":re,...X}=T,K=N?{"aria-labelledby":N}:U?{"aria-label":U}:{};return f.jsx(L.Provider,{value:$,children:f.jsxs("div",{ref:Y,"data-spark-component":"input-otp",role:"group",...K,...P?{"aria-describedby":P}:{},className:Z.cx("gap-md relative inline-flex items-center",S?"cursor-not-allowed":"cursor-text",B),onClick:F,...X,children:[_&&f.jsx("input",{type:"hidden",name:_,value:q,required:w,"aria-required":w,"aria-invalid":G,...K}),f.jsx("input",{ref:W,id:D,type:i==="password"?"password":"text",value:q,maxLength:k,autoFocus:v,autoComplete:y,disabled:S,pattern:C,inputMode:V,...K,...P?{"aria-describedby":P}:{},"aria-invalid":G,onChange:R,onKeyDown:E,onPaste:M,onFocus:d,onBlur:x,className:"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed",tabIndex:0}),h]})})};ne.displayName="InputOTP";const J=({children:e,className:i,...t})=>f.jsx("div",{className:`inline-flex [&>*:not(:first-child)]:-ml-px ${i||""}`,...t,children:e});J.displayName="InputOTP.Group";const Q=({className:e,...i})=>f.jsx("div",{className:`text-on-surface flex items-center justify-center ${e||""}`,...i,children:f.jsx(oe.Icon,{size:"md",children:f.jsx(ce.Minus,{})})});Q.displayName="InputOTP.Separator";const se=Object.assign(ne,{Group:J,Slot:A,Separator:Q});se.displayName="InputOTP";J.displayName="InputOTP.Group";A.displayName="InputOTP.Slot";Q.displayName="InputOTP.Separator";exports.InputOTP=se;exports.inputOTPSlotStyles=H;exports.inputOTPStyles=ue;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react/jsx-runtime"),Z=require("../index-DnaHaH_0.js"),a=require("react"),oe=require("../form-field/index.js"),ce=require("../Icon-Bf0XrmiR.js"),le=require("@spark-ui/icons/Minus"),L=a.createContext(null),ue=()=>{const e=a.useContext(L);if(!e)throw new Error("InputOTP components must be used within InputOTP");return e},H=Z.cva(["relative","border-sm first:rounded-l-lg last:rounded-r-lg","size-sz-44","text-center text-body-1","text-on-surface","outline-hidden","transition-colors","flex items-center justify-center","data-[active=true]:ring-1","data-[active=true]:ring-inset","data-[active=true]:ring-l-2","data-[active=true]:border-focus","data-[active=true]:z-raised ring-focus","data-[disabled=true]:cursor-not-allowed","data-[disabled=true]:border-outline","data-[disabled=true]:bg-on-surface/dim-5","data-[disabled=true]:text-on-surface/dim-3"],{variants:{intent:{neutral:["bg-surface border-outline"],success:["border-success bg-success-container text-on-success-container"],alert:["border-alert bg-alert-container text-on-alert-container"],error:["border-error bg-error-container text-on-error-container"]}},defaultVariants:{intent:"neutral"}}),de=H,j=({index:e,className:i,...t})=>{const c=ue(),s=e??0,u=c.slots[s];if(!u)return null;const{char:b,isActive:v,hasFakeCaret:y}=u,I=!b&&!y&&c.placeholder;return f.jsxs("div",{className:H({intent:c.intent,className:i}),"data-active":v,"data-disabled":c.disabled,"data-valid":c.intent!=="error",...t,children:[f.jsx("span",{className:I?"text-on-surface/dim-3":"",children:c.type==="password"&&b?"•":b||(!y&&c.placeholder?c.placeholder:"")}),y&&f.jsx("span",{className:"pointer-events-none absolute inset-0 flex items-center justify-center","aria-hidden":"true",children:f.jsx("span",{className:"bg-on-surface animate-standalone-caret-blink h-sz-24 w-px"})})]})};j.displayName="InputOTP.Slot";const pe="Backspace",fe="ArrowLeft",be="ArrowUp",xe="ArrowRight",me="ArrowDown",ve="e",Ie=({maxLength:e,type:i,value:t,defaultValue:c,onValueChange:s,isValid:u,disabledProp:b,autoFocus:v,forceUppercase:y,filterKeys:g,pattern:I,placeholder:C,nameProp:G})=>{const V=a.useId(),r=a.useRef(null),z=a.useRef(null),l=oe.useFormFieldControl(),O=l.id??V,D=G??l.name,h=l.disabled??b,_=l.isInvalid??!u,B=l.isRequired??!1,W=l.labelId,k=l.description,S=l.state,w=["success","alert","error"].includes(S??"")?S:_?"error":"neutral",P=t!==void 0?t:c,M=y?P.toUpperCase():P,[U,R]=a.useState(M),[E,F]=a.useState(!1),d=t!==void 0?t:U,x=Math.min(d.length,e-1);a.useEffect(()=>{r.current&&r.current.setSelectionRange(x,x)},[x,d.length,e]);const q=a.useMemo(()=>Array.from({length:e},(o,n)=>({char:d[n]||"",isActive:n===x&&E,hasFakeCaret:n===x&&!d[n]&&!h&&E})),[e,d,x,E,h]);a.useEffect(()=>{r.current&&t!==void 0&&(r.current.value=t)},[t]),a.useEffect(()=>{v&&r.current&&r.current.focus()},[v]);const N=o=>{let n=o;if(y&&(n=n.toUpperCase()),i==="number"&&(n=n.replace(/[^\d]/g,"")),I)try{let m=I;I.startsWith("^")||(m=`^${I}$`);const p=new RegExp(m);n=n.split("").filter(T=>p.test(T)).join("")}catch(m){console.error("Invalid pattern provided to InputOTP:",I,m)}return n};return{uuid:O,inputRef:r,containerRef:z,name:D,disabled:h,isInvalid:_,isRequired:B,description:k,maxLength:e,intent:w,currentValue:d,activeIndex:x,slots:q,contextValue:{value:d,maxLength:e,slots:q,activeIndex:x,intent:w,disabled:h,placeholder:C,type:i},handleChange:o=>{if(h)return;const n=o.target.value,p=N(n).slice(0,e);s&&s(p),t===void 0&&R(p);const T=Math.min(p.length,e-1);r.current&&r.current.setSelectionRange(T,T)},handleKeyDown:o=>{if(!h){if(g.length>0&&g.includes(o.key)){o.preventDefault();return}switch(o.key){case pe:o.preventDefault();const n=d.length;if(n>0){const m=d.slice(0,n-1);s&&s(m),t===void 0&&R(m);const p=Math.max(0,m.length);r.current&&r.current.setSelectionRange(p,p)}break;case fe:case xe:o.preventDefault();break;case be:case me:o.preventDefault();break;case ve:case"E":i==="number"&&o.preventDefault();break}}},handlePaste:o=>{if(h)return;o.preventDefault();const n=o.clipboardData.getData("text");if(!n)return;const p=N(n).slice(0,e);s&&s(p),t===void 0&&R(p);const T=Math.min(p.length,e-1);r.current&&r.current.setSelectionRange(T,T)},handleFocus:()=>{if(F(!0),r.current){const o=Math.min(d.length,e-1);r.current.setSelectionRange(o,o)}},handleBlur:()=>{F(!1)},handleClick:()=>{r.current&&r.current.focus()},labelId:W}},ee=e=>{let i=0;return a.Children.forEach(e,t=>{if(a.isValidElement(t)){const c=t.props;t.type===j||t.type?.displayName==="InputOTP.Slot"?i++:c.children&&(i+=ee(c.children))}}),i},te=(e,i=0)=>{let t=i;return[a.Children.map(e,s=>{if(a.isValidElement(s)){const u=s.props;if(s.type===j||s.type?.displayName==="InputOTP.Slot"){const b=typeof u.index=="number"?u.index:t++;return a.cloneElement(s,{...u,index:b})}else if(u.children){const[b,v]=te(u.children,t);return t=v,a.cloneElement(s,{...s.props,children:b})}}return s}),t]},ne=({maxLength:e,type:i="text",value:t,defaultValue:c="",onValueChange:s,isValid:u=!0,disabled:b=!1,autoFocus:v=!1,autoComplete:y="off",forceUppercase:g=!1,filterKeys:I=["-","."],pattern:C,inputMode:G,placeholder:V="",name:r,className:z,children:l,...O})=>{const D=a.useMemo(()=>{if(e!==void 0)return e;const A=ee(l);return A>0?A:4},[e,l]),h=a.useMemo(()=>{const[A]=te(l);return A},[l]),{uuid:_,inputRef:B,containerRef:W,name:k,disabled:S,isInvalid:Y,isRequired:w,description:P,currentValue:M,contextValue:U,handleChange:R,handleKeyDown:E,handlePaste:F,handleFocus:d,handleBlur:x,handleClick:q,labelId:N}=Ie({maxLength:D,type:i,value:t,defaultValue:c,onValueChange:s,isValid:u,disabledProp:b,autoFocus:v,forceUppercase:g,filterKeys:I,pattern:C,placeholder:V,nameProp:r}),$="aria-label"in O?O["aria-label"]:void 0,{"aria-label":re,...Q}=O,K=N?{"aria-labelledby":N}:$?{"aria-label":$}:{};return f.jsx(L.Provider,{value:U,children:f.jsxs("div",{ref:W,"data-spark-component":"input-otp",role:"group",...K,...P?{"aria-describedby":P}:{},className:Z.cx("gap-md relative inline-flex items-center",S?"cursor-not-allowed":"cursor-text",z),onClick:q,...Q,children:[k&&f.jsx("input",{type:"hidden",name:k,value:M,required:w,"aria-required":w,"aria-invalid":Y,...K}),f.jsx("input",{ref:B,id:_,type:i==="password"?"password":"text",value:M,maxLength:D,autoFocus:v,autoComplete:y,disabled:S,pattern:C,inputMode:G,...K,...P?{"aria-describedby":P}:{},"aria-invalid":Y,onChange:R,onKeyDown:E,onPaste:F,onFocus:d,onBlur:x,className:"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed",tabIndex:0}),h]})})};ne.displayName="InputOTP";const X=({children:e,className:i,...t})=>f.jsx("div",{className:`inline-flex [&>*:not(:first-child)]:-ml-px ${i||""}`,...t,children:e});X.displayName="InputOTP.Group";const J=({className:e,...i})=>f.jsx("div",{className:`text-on-surface flex items-center justify-center ${e||""}`,...i,children:f.jsx(ce.Icon,{size:"md",children:f.jsx(le.Minus,{})})});J.displayName="InputOTP.Separator";const se=Object.assign(ne,{Group:X,Slot:j,Separator:J});se.displayName="InputOTP";X.displayName="InputOTP.Group";j.displayName="InputOTP.Slot";J.displayName="InputOTP.Separator";exports.InputOTP=se;exports.inputOTPSlotStyles=H;exports.inputOTPStyles=de;
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/input-otp/InputOTPContext.tsx","../../src/input-otp/InputOTP.styles.ts","../../src/input-otp/InputOTPSlot.tsx","../../src/input-otp/useInputOTP.ts","../../src/input-otp/InputOTP.tsx","../../src/input-otp/InputOTPGroup.tsx","../../src/input-otp/InputOTPSeparator.tsx","../../src/input-otp/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputOTPContextValue {\n value: string\n maxLength: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n activeIndex: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n disabled: boolean\n placeholder?: string\n type: 'text' | 'number' | 'password' | 'tel'\n}\n\nexport const InputOTPContext = createContext<InputOTPContextValue | null>(null)\n\nexport const useInputOTPContext = () => {\n const context = useContext(InputOTPContext)\n if (!context) {\n throw new Error('InputOTP components must be used within InputOTP')\n }\n\n return context\n}\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputOTPContainerStyles = cva(['relative', 'inline-flex', 'items-center', 'gap-sm'])\n\nexport const inputOTPSlotStyles = cva(\n [\n // Base slot styles\n 'relative',\n 'border-sm first:rounded-l-lg last:rounded-r-lg',\n 'size-sz-44',\n 'text-center text-body-1',\n 'text-on-surface',\n 'outline-hidden',\n 'transition-colors',\n 'flex items-center justify-center',\n // Active state (when focused)\n 'data-[active=true]:ring-1',\n 'data-[active=true]:ring-inset',\n 'data-[active=true]:ring-l-2',\n\n 'data-[active=true]:border-focus',\n // 'data-[active=true]:ring-focus',\n // 'data-[active=true]:border-focus',\n 'data-[active=true]:z-raised ring-focus',\n // Disabled state\n 'data-[disabled=true]:cursor-not-allowed',\n 'data-[disabled=true]:border-outline',\n 'data-[disabled=true]:bg-on-surface/dim-5',\n 'data-[disabled=true]:text-on-surface/dim-3',\n ],\n {\n variants: {\n /**\n * Color scheme of the slot\n */\n intent: {\n neutral: ['bg-surface border-outline'],\n success: ['border-success bg-success-container text-on-success-container'],\n alert: ['border-alert bg-alert-container text-on-alert-container'],\n error: ['border-error bg-error-container text-on-error-container'],\n },\n },\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputOTPSlotStylesProps = VariantProps<typeof inputOTPSlotStyles>\n\n// Keep for backward compatibility\nexport const inputOTPStyles = inputOTPSlotStyles\nexport type InputOTPStylesProps = InputOTPSlotStylesProps\n","import { ComponentPropsWithoutRef } from 'react'\n\nimport { inputOTPSlotStyles } from './InputOTP.styles'\nimport { useInputOTPContext } from './InputOTPContext'\n\nexport interface InputOTPSlotProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Index of the slot (0-based).\n * If not provided, will be automatically assigned based on position in children.\n */\n index?: number\n}\n\nexport const InputOTPSlot = ({ index: indexProp, className, ...props }: InputOTPSlotProps) => {\n const context = useInputOTPContext()\n\n // Use provided index or fallback to 0 (should not happen if auto-assignment works)\n const index = indexProp ?? 0\n const slot = context.slots[index]\n\n if (!slot) {\n return null\n }\n\n const { char, isActive, hasFakeCaret } = slot\n const isEmpty = !char\n const isPlaceholder = isEmpty && !hasFakeCaret && context.placeholder\n\n return (\n <div\n className={inputOTPSlotStyles({\n intent: context.intent,\n className,\n })}\n data-active={isActive}\n data-disabled={context.disabled}\n data-valid={context.intent !== 'error'}\n {...props}\n >\n <span className={isPlaceholder ? 'text-on-surface/dim-3' : ''}>\n {context.type === 'password' && char\n ? '•'\n : char || (!hasFakeCaret && context.placeholder ? context.placeholder : '')}\n </span>\n {hasFakeCaret && (\n <span\n className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"bg-on-surface animate-standalone-caret-blink h-sz-24 w-px\" />\n </span>\n )}\n </div>\n )\n}\n\nInputOTPSlot.displayName = 'InputOTP.Slot'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport {\n ChangeEventHandler,\n ClipboardEventHandler,\n KeyboardEventHandler,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport type { InputOTPContextValue } from './InputOTPContext'\n\nconst BACKSPACE_KEY = 'Backspace'\nconst LEFT_ARROW_KEY = 'ArrowLeft'\nconst UP_ARROW_KEY = 'ArrowUp'\nconst RIGHT_ARROW_KEY = 'ArrowRight'\nconst DOWN_ARROW_KEY = 'ArrowDown'\nconst E_KEY = 'e'\n\nexport interface UseInputOTPProps {\n maxLength: number\n type: 'text' | 'number' | 'password' | 'tel'\n value?: string\n defaultValue: string\n onValueChange?: (value: string) => void\n isValid: boolean\n disabledProp: boolean\n autoFocus: boolean\n forceUppercase: boolean\n filterKeys: string[]\n pattern?: string\n placeholder: string\n nameProp?: string\n}\n\nexport interface UseInputOTPReturn {\n uuid: string\n inputRef: React.RefObject<HTMLInputElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n name: string | undefined\n disabled: boolean\n isInvalid: boolean\n isRequired: boolean\n description: string | undefined\n maxLength: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n currentValue: string\n activeIndex: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n contextValue: InputOTPContextValue\n handleChange: ChangeEventHandler<HTMLInputElement>\n handleKeyDown: KeyboardEventHandler<HTMLInputElement>\n handlePaste: ClipboardEventHandler<HTMLInputElement>\n handleFocus: () => void\n handleBlur: () => void\n handleClick: () => void\n labelId: string | undefined\n}\n\nexport const useInputOTP = ({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n}: UseInputOTPProps): UseInputOTPReturn => {\n const uuid = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Get FormField context (optional, falls back gracefully if not present)\n const field = useFormFieldControl()\n\n // Use FormField values if available, otherwise fall back to props\n // Use FormField id when available so label htmlFor works correctly\n const id = field.id ?? uuid\n const name = nameProp ?? field.name\n const disabled = field.disabled ?? disabledProp\n const isInvalid = field.isInvalid ?? !isValid\n const isRequired = field.isRequired ?? false\n const labelId = field.labelId\n const description = field.description\n const fieldState = field.state\n\n // Determine intent based on FormField state or isValid prop\n const getIntent = (): 'neutral' | 'success' | 'alert' | 'error' => {\n // FormField state takes priority\n if (['success', 'alert', 'error'].includes(fieldState ?? '')) {\n return fieldState as 'success' | 'alert' | 'error'\n }\n\n // Fallback to isValid prop for backward compatibility\n if (isInvalid) {\n return 'error'\n }\n\n return 'neutral'\n }\n\n const intent = getIntent()\n\n // Initialize value\n const initialValue = controlledValue !== undefined ? controlledValue : defaultValue\n const processedValue = forceUppercase ? initialValue.toUpperCase() : initialValue\n\n const [internalValue, setInternalValue] = useState<string>(processedValue)\n const [isFocused, setIsFocused] = useState<boolean>(false)\n\n // Use controlled value if provided, otherwise use internal state\n const currentValue = controlledValue !== undefined ? controlledValue : internalValue\n\n // Calculate active index: last empty slot, or last slot if all are filled\n const activeIndex = Math.min(currentValue.length, maxLength - 1)\n\n // Sync cursor position with active index\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.setSelectionRange(activeIndex, activeIndex)\n }\n }, [activeIndex, currentValue.length, maxLength])\n\n // Create slots array\n const slots = useMemo(\n () =>\n Array.from({ length: maxLength }, (_, i) => ({\n char: currentValue[i] || '',\n isActive: i === activeIndex && isFocused,\n hasFakeCaret: i === activeIndex && !currentValue[i] && !disabled && isFocused,\n })),\n [maxLength, currentValue, activeIndex, isFocused, disabled]\n )\n\n // Sync controlled value with input ref\n useEffect(() => {\n if (inputRef.current && controlledValue !== undefined) {\n inputRef.current.value = controlledValue\n }\n }, [controlledValue])\n\n // Focus management\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n }\n }, [autoFocus])\n\n const processInputValue = (inputValue: string): string => {\n let processed = inputValue\n\n if (forceUppercase) {\n processed = processed.toUpperCase()\n }\n\n if (type === 'number') {\n processed = processed.replace(/[^\\d]/g, '')\n }\n\n // Filter characters using pattern if provided\n if (pattern) {\n try {\n // Convert HTML pattern (string) to RegExp\n // HTML patterns validate the entire string, but we need to test each character\n // We create a regex that tests if a single character matches the pattern\n // For example: [0-9]* becomes ^[0-9]$ to test a single digit\n // We wrap the pattern in ^...$ to ensure it matches a single character\n let regexPattern = pattern\n // If pattern doesn't start with ^, wrap it to test single character\n if (!pattern.startsWith('^')) {\n regexPattern = `^${pattern}$`\n }\n const regex = new RegExp(regexPattern)\n processed = processed\n .split('')\n .filter(currChar => {\n // Test if the character matches the pattern\n return regex.test(currChar)\n })\n .join('')\n } catch (error) {\n // If pattern is invalid, ignore it and continue with other filters\n console.error('Invalid pattern provided to InputOTP:', pattern, error)\n }\n }\n\n return processed\n }\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n const inputValue = e.target.value\n const processedValue = processInputValue(inputValue)\n\n // Limit to maxLength\n const newValue = processedValue.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n // Filter keys\n if (filterKeys.length > 0 && filterKeys.includes(e.key)) {\n e.preventDefault()\n\n return\n }\n\n switch (e.key) {\n case BACKSPACE_KEY:\n e.preventDefault()\n const currentLength = currentValue.length\n if (currentLength > 0) {\n const newValue = currentValue.slice(0, currentLength - 1)\n\n // Call onValueChange first\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.max(0, newValue.length)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n break\n\n case LEFT_ARROW_KEY:\n case RIGHT_ARROW_KEY:\n // Prevent navigation with arrow keys - focus stays on last empty slot\n e.preventDefault()\n break\n\n case UP_ARROW_KEY:\n case DOWN_ARROW_KEY:\n e.preventDefault()\n break\n\n case E_KEY:\n case 'E':\n // Prevent 'e' or 'E' in number inputs\n if (type === 'number') {\n e.preventDefault()\n }\n break\n\n default:\n break\n }\n }\n\n const handlePaste: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n e.preventDefault()\n\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText) return\n\n const processedText = processInputValue(pastedText)\n const newValue = processedText.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Move cursor to end\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleFocus = () => {\n setIsFocused(true)\n if (inputRef.current) {\n // Focus on last empty slot, or last slot if all are filled\n const cursorPosition = Math.min(currentValue.length, maxLength - 1)\n inputRef.current.setSelectionRange(cursorPosition, cursorPosition)\n }\n }\n\n const handleBlur = () => {\n setIsFocused(false)\n }\n\n const handleClick = () => {\n if (inputRef.current) {\n inputRef.current.focus()\n }\n }\n\n const contextValue: InputOTPContextValue = {\n value: currentValue,\n maxLength,\n slots,\n activeIndex,\n intent,\n disabled,\n placeholder,\n type,\n }\n\n const returnValue: UseInputOTPReturn = {\n uuid: id,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n maxLength,\n intent,\n currentValue,\n activeIndex,\n slots,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n }\n\n return returnValue\n}\n","/* eslint-disable max-lines-per-function */\nimport { cx } from 'class-variance-authority'\nimport {\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n isValidElement,\n ReactElement,\n ReactNode,\n Ref,\n useMemo,\n} from 'react'\n\nimport { InputOTPContext } from './InputOTPContext'\nimport { InputOTPSlot } from './InputOTPSlot'\nimport { useInputOTP } from './useInputOTP'\n\n/**\n * Counts the number of InputOTPSlot components in the children tree\n */\nconst countSlots = (children: ReactNode): number => {\n let count = 0\n\n Children.forEach(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { children?: ReactNode }\n // Check if it's an InputOTPSlot by checking displayName\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n count++\n } else if (props.children) {\n // Recursively count slots in nested children (e.g., inside InputOTPGroup)\n count += countSlots(props.children)\n }\n }\n })\n\n return count\n}\n\n/**\n * Recursively assigns index to InputOTPSlot components\n * Returns a tuple of [processedChildren, nextIndex]\n */\nconst assignSlotIndexes = (children: ReactNode, startIndex: number = 0): [ReactNode, number] => {\n let currentIndex = startIndex\n\n const processed = Children.map(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { index?: number; children?: ReactNode }\n // Check if it's an InputOTPSlot\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n // Only assign index if not already provided\n const slotIndex = typeof props.index === 'number' ? props.index : currentIndex++\n\n return cloneElement(child as ReactElement<{ index?: number }>, {\n ...props,\n index: slotIndex,\n })\n } else if (props.children) {\n // Recursively process nested children\n const [processedChildren, nextIndex] = assignSlotIndexes(props.children, currentIndex)\n currentIndex = nextIndex\n\n return cloneElement(child, {\n ...(child.props as Record<string, unknown>),\n children: processedChildren,\n } as Parameters<typeof cloneElement>[1])\n }\n }\n\n return child\n })\n\n return [processed, currentIndex]\n}\n\nexport interface InputOTPProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'inputMode'> {\n /**\n * Maximum length of the input value.\n * If not provided, will be automatically detected from the number of InputOTP.Slot children.\n */\n maxLength?: number\n /**\n * Type of input\n * @default 'text'\n */\n type?: 'text' | 'number' | 'password' | 'tel'\n /**\n * Current value (controlled mode)\n */\n value?: string\n /**\n * Default value (uncontrolled mode)\n */\n defaultValue?: string\n /**\n * Callback fired when the value changes\n */\n onValueChange?: (value: string) => void\n /**\n * Whether the input is valid\n * @default true\n */\n isValid?: boolean\n /**\n * Whether the input is disabled\n * @default false\n */\n disabled?: boolean\n /**\n * Whether to auto-focus the input\n * @default false\n */\n autoFocus?: boolean\n /**\n * Auto-complete attribute\n * @default 'off'\n */\n autoComplete?: string\n /**\n * Whether to force uppercase\n * @default false\n */\n forceUppercase?: boolean\n /**\n * Array of keys to filter out (using KeyboardEvent.key values)\n * @default ['-', '.']\n */\n filterKeys?: string[]\n /**\n * Pattern attribute for input validation and character filtering.\n * Uses a regular expression to filter allowed characters in real-time.\n * For example: \"[0-9]\" for digits only, \"[a-c]\" for letters a, b, c only.\n */\n pattern?: string\n /**\n * Input mode attribute\n */\n inputMode?: string\n /**\n * Placeholder text\n */\n placeholder?: string\n /**\n * Name attribute for form integration\n */\n name?: string\n /**\n * Children components (InputOTPGroup, InputOTPSlot, InputOTPSeparator)\n */\n children: ReactNode\n /**\n * Ref callback for the container\n */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputOTP = ({\n maxLength: maxLengthProp,\n type = 'text',\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n isValid = true,\n disabled: disabledProp = false,\n autoFocus = false,\n autoComplete = 'off',\n forceUppercase = false,\n filterKeys = ['-', '.'],\n pattern,\n inputMode,\n placeholder = '',\n name: nameProp,\n className,\n children,\n ...others\n}: InputOTPProps) => {\n // Auto-detect maxLength from children if not provided\n const maxLength = useMemo(() => {\n if (maxLengthProp !== undefined) {\n return maxLengthProp\n }\n\n const detectedLength = countSlots(children)\n\n return detectedLength > 0 ? detectedLength : 4 // fallback to 4 if no slots found\n }, [maxLengthProp, children])\n\n // Assign indexes to slots automatically\n const processedChildren = useMemo(() => {\n const [processed] = assignSlotIndexes(children)\n\n return processed\n }, [children])\n\n // Use the hook for all business logic\n const {\n uuid,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n currentValue,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n } = useInputOTP({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n })\n\n // Extract aria-label from others if provided (for cases without FormField)\n const ariaLabel =\n 'aria-label' in others ? (others['aria-label'] as string | undefined) : undefined\n const { 'aria-label': _, ...restOthers } = others\n\n // Determine accessible name props\n const getAccessibleNameProps = (): Record<string, string | undefined> => {\n if (labelId) {\n return { 'aria-labelledby': labelId }\n }\n\n if (ariaLabel) {\n return { 'aria-label': ariaLabel }\n }\n\n return {}\n }\n\n const accessibleNameProps = getAccessibleNameProps()\n\n return (\n <InputOTPContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n data-spark-component=\"input-otp\"\n role=\"group\"\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n className={cx(\n 'gap-md relative inline-flex items-center',\n disabled ? 'cursor-not-allowed' : 'cursor-text',\n className\n )}\n onClick={handleClick}\n {...restOthers}\n >\n {/* Hidden input for form submission with complete value */}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValue}\n required={isRequired}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n {...accessibleNameProps}\n />\n )}\n {/* Actual input that handles all interactions */}\n <input\n ref={inputRef}\n id={uuid}\n type={type === 'password' ? 'password' : 'text'}\n value={currentValue}\n maxLength={maxLength}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n disabled={disabled}\n pattern={pattern}\n inputMode={inputMode as React.InputHTMLAttributes<HTMLInputElement>['inputMode']}\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed\"\n tabIndex={0}\n />\n {/* Children render slots with auto-assigned indexes */}\n {processedChildren}\n </div>\n </InputOTPContext.Provider>\n )\n}\n\nInputOTP.displayName = 'InputOTP'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPGroupProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPGroup = ({ children, className, ...props }: InputOTPGroupProps) => {\n return (\n <div className={`inline-flex [&>*:not(:first-child)]:-ml-px ${className || ''}`} {...props}>\n {children}\n </div>\n )\n}\n\nInputOTPGroup.displayName = 'InputOTP.Group'\n","import { Icon } from '@spark-ui/components/icon'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPSeparatorProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPSeparator = ({ className, ...props }: InputOTPSeparatorProps) => {\n return (\n <div\n className={`text-on-surface flex items-center justify-center ${className || ''}`}\n {...props}\n >\n <Icon size=\"md\">\n <Minus />\n </Icon>\n </div>\n )\n}\n\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n","import { InputOTP as Root } from './InputOTP'\nimport { InputOTPGroup } from './InputOTPGroup'\nimport { InputOTPSeparator } from './InputOTPSeparator'\nimport { InputOTPSlot } from './InputOTPSlot'\n\nexport const InputOTP: typeof Root & {\n Group: typeof InputOTPGroup\n Slot: typeof InputOTPSlot\n Separator: typeof InputOTPSeparator\n} = Object.assign(Root, {\n Group: InputOTPGroup,\n Slot: InputOTPSlot,\n Separator: InputOTPSeparator,\n})\n\nInputOTP.displayName = 'InputOTP'\nInputOTPGroup.displayName = 'InputOTP.Group'\nInputOTPSlot.displayName = 'InputOTP.Slot'\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n\nexport { type InputOTPProps } from './InputOTP'\nexport { type InputOTPGroupProps } from './InputOTPGroup'\nexport { type InputOTPSlotProps } from './InputOTPSlot'\nexport { type InputOTPSeparatorProps } from './InputOTPSeparator'\nexport {\n inputOTPSlotStyles,\n inputOTPStyles,\n type InputOTPSlotStylesProps,\n type InputOTPStylesProps,\n} from './InputOTP.styles'\n"],"names":["InputOTPContext","createContext","useInputOTPContext","context","useContext","inputOTPSlotStyles","cva","inputOTPStyles","InputOTPSlot","indexProp","className","props","index","slot","char","isActive","hasFakeCaret","isPlaceholder","jsxs","jsx","BACKSPACE_KEY","LEFT_ARROW_KEY","UP_ARROW_KEY","RIGHT_ARROW_KEY","DOWN_ARROW_KEY","E_KEY","useInputOTP","maxLength","type","controlledValue","defaultValue","onValueChange","isValid","disabledProp","autoFocus","forceUppercase","filterKeys","pattern","placeholder","nameProp","uuid","useId","inputRef","useRef","containerRef","field","useFormFieldControl","id","name","disabled","isInvalid","isRequired","labelId","description","fieldState","intent","initialValue","processedValue","internalValue","setInternalValue","useState","isFocused","setIsFocused","currentValue","activeIndex","useEffect","slots","useMemo","_","i","processInputValue","inputValue","processed","regexPattern","regex","currChar","error","e","newValue","newActiveIndex","currentLength","pastedText","cursorPosition","countSlots","children","count","Children","child","isValidElement","assignSlotIndexes","startIndex","currentIndex","slotIndex","cloneElement","processedChildren","nextIndex","InputOTP","maxLengthProp","autoComplete","inputMode","others","detectedLength","contextValue","handleChange","handleKeyDown","handlePaste","handleFocus","handleBlur","handleClick","ariaLabel","restOthers","accessibleNameProps","cx","InputOTPGroup","InputOTPSeparator","Icon","Minus","Root"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/input-otp/InputOTPContext.tsx","../../src/input-otp/InputOTP.styles.ts","../../src/input-otp/InputOTPSlot.tsx","../../src/input-otp/useInputOTP.ts","../../src/input-otp/InputOTP.tsx","../../src/input-otp/InputOTPGroup.tsx","../../src/input-otp/InputOTPSeparator.tsx","../../src/input-otp/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputOTPContextValue {\n value: string\n maxLength: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n activeIndex: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n disabled: boolean\n placeholder?: string\n type: 'text' | 'number' | 'password' | 'tel'\n}\n\nexport const InputOTPContext = createContext<InputOTPContextValue | null>(null)\n\nexport const useInputOTPContext = () => {\n const context = useContext(InputOTPContext)\n if (!context) {\n throw new Error('InputOTP components must be used within InputOTP')\n }\n\n return context\n}\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputOTPContainerStyles = cva(['relative', 'inline-flex', 'items-center', 'gap-sm'])\n\nexport const inputOTPSlotStyles = cva(\n [\n // Base slot styles\n 'relative',\n 'border-sm first:rounded-l-lg last:rounded-r-lg',\n 'size-sz-44',\n 'text-center text-body-1',\n 'text-on-surface',\n 'outline-hidden',\n 'transition-colors',\n 'flex items-center justify-center',\n // Active state (when focused)\n 'data-[active=true]:ring-1',\n 'data-[active=true]:ring-inset',\n 'data-[active=true]:ring-l-2',\n\n 'data-[active=true]:border-focus',\n // 'data-[active=true]:ring-focus',\n // 'data-[active=true]:border-focus',\n 'data-[active=true]:z-raised ring-focus',\n // Disabled state\n 'data-[disabled=true]:cursor-not-allowed',\n 'data-[disabled=true]:border-outline',\n 'data-[disabled=true]:bg-on-surface/dim-5',\n 'data-[disabled=true]:text-on-surface/dim-3',\n ],\n {\n variants: {\n /**\n * Color scheme of the slot\n */\n intent: {\n neutral: ['bg-surface border-outline'],\n success: ['border-success bg-success-container text-on-success-container'],\n alert: ['border-alert bg-alert-container text-on-alert-container'],\n error: ['border-error bg-error-container text-on-error-container'],\n },\n },\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputOTPSlotStylesProps = VariantProps<typeof inputOTPSlotStyles>\n\n// Keep for backward compatibility\nexport const inputOTPStyles = inputOTPSlotStyles\nexport type InputOTPStylesProps = InputOTPSlotStylesProps\n","import { ComponentPropsWithoutRef } from 'react'\n\nimport { inputOTPSlotStyles } from './InputOTP.styles'\nimport { useInputOTPContext } from './InputOTPContext'\n\nexport interface InputOTPSlotProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Index of the slot (0-based).\n * If not provided, will be automatically assigned based on position in children.\n */\n index?: number\n}\n\nexport const InputOTPSlot = ({ index: indexProp, className, ...props }: InputOTPSlotProps) => {\n const context = useInputOTPContext()\n\n // Use provided index or fallback to 0 (should not happen if auto-assignment works)\n const index = indexProp ?? 0\n const slot = context.slots[index]\n\n if (!slot) {\n return null\n }\n\n const { char, isActive, hasFakeCaret } = slot\n const isEmpty = !char\n const isPlaceholder = isEmpty && !hasFakeCaret && context.placeholder\n\n return (\n <div\n className={inputOTPSlotStyles({\n intent: context.intent,\n className,\n })}\n data-active={isActive}\n data-disabled={context.disabled}\n data-valid={context.intent !== 'error'}\n {...props}\n >\n <span className={isPlaceholder ? 'text-on-surface/dim-3' : ''}>\n {context.type === 'password' && char\n ? '•'\n : char || (!hasFakeCaret && context.placeholder ? context.placeholder : '')}\n </span>\n {hasFakeCaret && (\n <span\n className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"bg-on-surface animate-standalone-caret-blink h-sz-24 w-px\" />\n </span>\n )}\n </div>\n )\n}\n\nInputOTPSlot.displayName = 'InputOTP.Slot'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport {\n ChangeEventHandler,\n ClipboardEventHandler,\n KeyboardEventHandler,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport type { InputOTPContextValue } from './InputOTPContext'\n\nconst BACKSPACE_KEY = 'Backspace'\nconst LEFT_ARROW_KEY = 'ArrowLeft'\nconst UP_ARROW_KEY = 'ArrowUp'\nconst RIGHT_ARROW_KEY = 'ArrowRight'\nconst DOWN_ARROW_KEY = 'ArrowDown'\nconst E_KEY = 'e'\n\nexport interface UseInputOTPProps {\n maxLength: number\n type: 'text' | 'number' | 'password' | 'tel'\n value?: string\n defaultValue: string\n onValueChange?: (value: string) => void\n isValid: boolean\n disabledProp: boolean\n autoFocus: boolean\n forceUppercase: boolean\n filterKeys: string[]\n pattern?: string\n placeholder: string\n nameProp?: string\n}\n\nexport interface UseInputOTPReturn {\n uuid: string\n inputRef: React.RefObject<HTMLInputElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n name: string | undefined\n disabled: boolean\n isInvalid: boolean\n isRequired: boolean\n description: string | undefined\n maxLength: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n currentValue: string\n activeIndex: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n contextValue: InputOTPContextValue\n handleChange: ChangeEventHandler<HTMLInputElement>\n handleKeyDown: KeyboardEventHandler<HTMLInputElement>\n handlePaste: ClipboardEventHandler<HTMLInputElement>\n handleFocus: () => void\n handleBlur: () => void\n handleClick: () => void\n labelId: string | undefined\n}\n\nexport const useInputOTP = ({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n}: UseInputOTPProps): UseInputOTPReturn => {\n const uuid = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Get FormField context (optional, falls back gracefully if not present)\n const field = useFormFieldControl()\n\n // Use FormField values if available, otherwise fall back to props\n // Use FormField id when available so label htmlFor works correctly\n const id = field.id ?? uuid\n const name = nameProp ?? field.name\n const disabled = field.disabled ?? disabledProp\n const isInvalid = field.isInvalid ?? !isValid\n const isRequired = field.isRequired ?? false\n const labelId = field.labelId\n const description = field.description\n const fieldState = field.state\n\n // Determine intent based on FormField state or isValid prop\n const getIntent = (): 'neutral' | 'success' | 'alert' | 'error' => {\n // FormField state takes priority\n if (['success', 'alert', 'error'].includes(fieldState ?? '')) {\n return fieldState as 'success' | 'alert' | 'error'\n }\n\n // Fallback to isValid prop for backward compatibility\n if (isInvalid) {\n return 'error'\n }\n\n return 'neutral'\n }\n\n const intent = getIntent()\n\n // Initialize value\n const initialValue = controlledValue !== undefined ? controlledValue : defaultValue\n const processedValue = forceUppercase ? initialValue.toUpperCase() : initialValue\n\n const [internalValue, setInternalValue] = useState<string>(processedValue)\n const [isFocused, setIsFocused] = useState<boolean>(false)\n\n // Use controlled value if provided, otherwise use internal state\n const currentValue = controlledValue !== undefined ? controlledValue : internalValue\n\n // Calculate active index: last empty slot, or last slot if all are filled\n const activeIndex = Math.min(currentValue.length, maxLength - 1)\n\n // Sync cursor position with active index\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.setSelectionRange(activeIndex, activeIndex)\n }\n }, [activeIndex, currentValue.length, maxLength])\n\n // Create slots array\n const slots = useMemo(\n () =>\n Array.from({ length: maxLength }, (_, i) => ({\n char: currentValue[i] || '',\n isActive: i === activeIndex && isFocused,\n hasFakeCaret: i === activeIndex && !currentValue[i] && !disabled && isFocused,\n })),\n [maxLength, currentValue, activeIndex, isFocused, disabled]\n )\n\n // Sync controlled value with input ref\n useEffect(() => {\n if (inputRef.current && controlledValue !== undefined) {\n inputRef.current.value = controlledValue\n }\n }, [controlledValue])\n\n // Focus management\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n }\n }, [autoFocus])\n\n const processInputValue = (inputValue: string): string => {\n let processed = inputValue\n\n if (forceUppercase) {\n processed = processed.toUpperCase()\n }\n\n if (type === 'number') {\n processed = processed.replace(/[^\\d]/g, '')\n }\n\n // Filter characters using pattern if provided\n if (pattern) {\n try {\n // Convert HTML pattern (string) to RegExp\n // HTML patterns validate the entire string, but we need to test each character\n // We create a regex that tests if a single character matches the pattern\n // For example: [0-9]* becomes ^[0-9]$ to test a single digit\n // We wrap the pattern in ^...$ to ensure it matches a single character\n let regexPattern = pattern\n // If pattern doesn't start with ^, wrap it to test single character\n if (!pattern.startsWith('^')) {\n regexPattern = `^${pattern}$`\n }\n const regex = new RegExp(regexPattern)\n processed = processed\n .split('')\n .filter(currChar => {\n // Test if the character matches the pattern\n return regex.test(currChar)\n })\n .join('')\n } catch (error) {\n // If pattern is invalid, ignore it and continue with other filters\n console.error('Invalid pattern provided to InputOTP:', pattern, error)\n }\n }\n\n return processed\n }\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n const inputValue = e.target.value\n const processedValue = processInputValue(inputValue)\n\n // Limit to maxLength\n const newValue = processedValue.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n // Filter keys\n if (filterKeys.length > 0 && filterKeys.includes(e.key)) {\n e.preventDefault()\n\n return\n }\n\n switch (e.key) {\n case BACKSPACE_KEY:\n e.preventDefault()\n const currentLength = currentValue.length\n if (currentLength > 0) {\n const newValue = currentValue.slice(0, currentLength - 1)\n\n // Call onValueChange first\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.max(0, newValue.length)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n break\n\n case LEFT_ARROW_KEY:\n case RIGHT_ARROW_KEY:\n // Prevent navigation with arrow keys - focus stays on last empty slot\n e.preventDefault()\n break\n\n case UP_ARROW_KEY:\n case DOWN_ARROW_KEY:\n e.preventDefault()\n break\n\n case E_KEY:\n case 'E':\n // Prevent 'e' or 'E' in number inputs\n if (type === 'number') {\n e.preventDefault()\n }\n break\n\n default:\n break\n }\n }\n\n const handlePaste: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n e.preventDefault()\n\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText) return\n\n const processedText = processInputValue(pastedText)\n const newValue = processedText.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Move cursor to end\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleFocus = () => {\n setIsFocused(true)\n if (inputRef.current) {\n // Focus on last empty slot, or last slot if all are filled\n const cursorPosition = Math.min(currentValue.length, maxLength - 1)\n inputRef.current.setSelectionRange(cursorPosition, cursorPosition)\n }\n }\n\n const handleBlur = () => {\n setIsFocused(false)\n }\n\n const handleClick = () => {\n if (inputRef.current) {\n inputRef.current.focus()\n }\n }\n\n const contextValue: InputOTPContextValue = {\n value: currentValue,\n maxLength,\n slots,\n activeIndex,\n intent,\n disabled,\n placeholder,\n type,\n }\n\n const returnValue: UseInputOTPReturn = {\n uuid: id,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n maxLength,\n intent,\n currentValue,\n activeIndex,\n slots,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n }\n\n return returnValue\n}\n","/* eslint-disable max-lines-per-function */\nimport { cx } from 'class-variance-authority'\nimport {\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n isValidElement,\n ReactElement,\n ReactNode,\n Ref,\n useMemo,\n} from 'react'\n\nimport { InputOTPContext } from './InputOTPContext'\nimport { InputOTPSlot } from './InputOTPSlot'\nimport { useInputOTP } from './useInputOTP'\n\n/**\n * Counts the number of InputOTPSlot components in the children tree\n */\nconst countSlots = (children: ReactNode): number => {\n let count = 0\n\n Children.forEach(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { children?: ReactNode }\n // Check if it's an InputOTPSlot by checking displayName\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n count++\n } else if (props.children) {\n // Recursively count slots in nested children (e.g., inside InputOTPGroup)\n count += countSlots(props.children)\n }\n }\n })\n\n return count\n}\n\n/**\n * Recursively assigns index to InputOTPSlot components\n * Returns a tuple of [processedChildren, nextIndex]\n */\nconst assignSlotIndexes = (children: ReactNode, startIndex: number = 0): [ReactNode, number] => {\n let currentIndex = startIndex\n\n const processed = Children.map(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { index?: number; children?: ReactNode }\n // Check if it's an InputOTPSlot\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n // Only assign index if not already provided\n const slotIndex = typeof props.index === 'number' ? props.index : currentIndex++\n\n return cloneElement(child as ReactElement<{ index?: number }>, {\n ...props,\n index: slotIndex,\n })\n } else if (props.children) {\n // Recursively process nested children\n const [processedChildren, nextIndex] = assignSlotIndexes(props.children, currentIndex)\n currentIndex = nextIndex\n\n return cloneElement(child, {\n ...(child.props as Record<string, unknown>),\n children: processedChildren,\n } as Parameters<typeof cloneElement>[1])\n }\n }\n\n return child\n })\n\n return [processed, currentIndex]\n}\n\nexport interface InputOTPProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'inputMode'> {\n /**\n * Maximum length of the input value.\n * If not provided, will be automatically detected from the number of InputOTP.Slot children.\n */\n maxLength?: number\n /**\n * Type of input\n * @default 'text'\n */\n type?: 'text' | 'number' | 'password' | 'tel'\n /**\n * Current value (controlled mode)\n */\n value?: string\n /**\n * Default value (uncontrolled mode)\n */\n defaultValue?: string\n /**\n * Callback fired when the value changes\n */\n onValueChange?: (value: string) => void\n /**\n * Whether the input is valid\n * @default true\n */\n isValid?: boolean\n /**\n * Whether the input is disabled\n * @default false\n */\n disabled?: boolean\n /**\n * Whether to auto-focus the input\n * @default false\n */\n autoFocus?: boolean\n /**\n * Auto-complete attribute\n * @default 'off'\n */\n autoComplete?: string\n /**\n * Whether to force uppercase\n * @default false\n */\n forceUppercase?: boolean\n /**\n * Array of keys to filter out (using KeyboardEvent.key values)\n * @default ['-', '.']\n */\n filterKeys?: string[]\n /**\n * Pattern attribute for input validation and character filtering.\n * Uses a regular expression to filter allowed characters in real-time.\n * For example: \"[0-9]\" for digits only, \"[a-c]\" for letters a, b, c only.\n */\n pattern?: string\n /**\n * Input mode attribute\n */\n inputMode?: string\n /**\n * Placeholder text\n */\n placeholder?: string\n /**\n * Name attribute for form integration\n */\n name?: string\n /**\n * Children components (InputOTPGroup, InputOTPSlot, InputOTPSeparator)\n */\n children: ReactNode\n /**\n * Ref callback for the container\n */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputOTP = ({\n maxLength: maxLengthProp,\n type = 'text',\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n isValid = true,\n disabled: disabledProp = false,\n autoFocus = false,\n autoComplete = 'off',\n forceUppercase = false,\n filterKeys = ['-', '.'],\n pattern,\n inputMode,\n placeholder = '',\n name: nameProp,\n className,\n children,\n ...others\n}: InputOTPProps) => {\n // Auto-detect maxLength from children if not provided\n const maxLength = useMemo(() => {\n if (maxLengthProp !== undefined) {\n return maxLengthProp\n }\n\n const detectedLength = countSlots(children)\n const DEFAULT_MAX_LENGTH = 4\n\n return detectedLength > 0 ? detectedLength : DEFAULT_MAX_LENGTH // fallback to 4 if no slots found\n }, [maxLengthProp, children])\n\n // Assign indexes to slots automatically\n const processedChildren = useMemo(() => {\n const [processed] = assignSlotIndexes(children)\n\n return processed\n }, [children])\n\n // Use the hook for all business logic\n const {\n uuid,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n currentValue,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n } = useInputOTP({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n })\n\n // Extract aria-label from others if provided (for cases without FormField)\n const ariaLabel =\n 'aria-label' in others ? (others['aria-label'] as string | undefined) : undefined\n const { 'aria-label': _, ...restOthers } = others\n\n const getAccessibleNameProps = (): Record<string, string | undefined> => {\n if (labelId) {\n return { 'aria-labelledby': labelId }\n }\n\n if (ariaLabel) {\n return { 'aria-label': ariaLabel }\n }\n\n return {}\n }\n\n const accessibleNameProps = getAccessibleNameProps()\n\n return (\n <InputOTPContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n data-spark-component=\"input-otp\"\n role=\"group\"\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n className={cx(\n 'gap-md relative inline-flex items-center',\n disabled ? 'cursor-not-allowed' : 'cursor-text',\n className\n )}\n onClick={handleClick}\n {...restOthers}\n >\n {/* Hidden input for form submission with complete value */}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValue}\n required={isRequired}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n {...accessibleNameProps}\n />\n )}\n {/* Actual input that handles all interactions */}\n <input\n ref={inputRef}\n id={uuid}\n type={type === 'password' ? 'password' : 'text'}\n value={currentValue}\n maxLength={maxLength}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n disabled={disabled}\n pattern={pattern}\n inputMode={inputMode as React.InputHTMLAttributes<HTMLInputElement>['inputMode']}\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed\"\n tabIndex={0}\n />\n {/* Children render slots with auto-assigned indexes */}\n {processedChildren}\n </div>\n </InputOTPContext.Provider>\n )\n}\n\nInputOTP.displayName = 'InputOTP'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPGroupProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPGroup = ({ children, className, ...props }: InputOTPGroupProps) => {\n return (\n <div className={`inline-flex [&>*:not(:first-child)]:-ml-px ${className || ''}`} {...props}>\n {children}\n </div>\n )\n}\n\nInputOTPGroup.displayName = 'InputOTP.Group'\n","import { Icon } from '@spark-ui/components/icon'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPSeparatorProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPSeparator = ({ className, ...props }: InputOTPSeparatorProps) => {\n return (\n <div\n className={`text-on-surface flex items-center justify-center ${className || ''}`}\n {...props}\n >\n <Icon size=\"md\">\n <Minus />\n </Icon>\n </div>\n )\n}\n\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n","import { InputOTP as Root } from './InputOTP'\nimport { InputOTPGroup } from './InputOTPGroup'\nimport { InputOTPSeparator } from './InputOTPSeparator'\nimport { InputOTPSlot } from './InputOTPSlot'\n\nexport const InputOTP: typeof Root & {\n Group: typeof InputOTPGroup\n Slot: typeof InputOTPSlot\n Separator: typeof InputOTPSeparator\n} = Object.assign(Root, {\n Group: InputOTPGroup,\n Slot: InputOTPSlot,\n Separator: InputOTPSeparator,\n})\n\nInputOTP.displayName = 'InputOTP'\nInputOTPGroup.displayName = 'InputOTP.Group'\nInputOTPSlot.displayName = 'InputOTP.Slot'\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n\nexport { type InputOTPProps } from './InputOTP'\nexport { type InputOTPGroupProps } from './InputOTPGroup'\nexport { type InputOTPSlotProps } from './InputOTPSlot'\nexport { type InputOTPSeparatorProps } from './InputOTPSeparator'\nexport {\n inputOTPSlotStyles,\n inputOTPStyles,\n type InputOTPSlotStylesProps,\n type InputOTPStylesProps,\n} from './InputOTP.styles'\n"],"names":["InputOTPContext","createContext","useInputOTPContext","context","useContext","inputOTPSlotStyles","cva","inputOTPStyles","InputOTPSlot","indexProp","className","props","index","slot","char","isActive","hasFakeCaret","isPlaceholder","jsxs","jsx","BACKSPACE_KEY","LEFT_ARROW_KEY","UP_ARROW_KEY","RIGHT_ARROW_KEY","DOWN_ARROW_KEY","E_KEY","useInputOTP","maxLength","type","controlledValue","defaultValue","onValueChange","isValid","disabledProp","autoFocus","forceUppercase","filterKeys","pattern","placeholder","nameProp","uuid","useId","inputRef","useRef","containerRef","field","useFormFieldControl","id","name","disabled","isInvalid","isRequired","labelId","description","fieldState","intent","initialValue","processedValue","internalValue","setInternalValue","useState","isFocused","setIsFocused","currentValue","activeIndex","useEffect","slots","useMemo","_","i","processInputValue","inputValue","processed","regexPattern","regex","currChar","error","e","newValue","newActiveIndex","currentLength","pastedText","cursorPosition","countSlots","children","count","Children","child","isValidElement","assignSlotIndexes","startIndex","currentIndex","slotIndex","cloneElement","processedChildren","nextIndex","InputOTP","maxLengthProp","autoComplete","inputMode","others","detectedLength","contextValue","handleChange","handleKeyDown","handlePaste","handleFocus","handleBlur","handleClick","ariaLabel","restOthers","accessibleNameProps","cx","InputOTPGroup","InputOTPSeparator","Icon","Minus","Root"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
1
  import { jsxs as te, jsx as b } from "react/jsx-runtime";
2
- import { c as de, a as pe } from "../index-BmAFn37q.mjs";
3
- import { createContext as fe, useContext as me, useId as be, useRef as Z, useState as L, useEffect as U, useMemo as H, Children as ne, isValidElement as re, cloneElement as ee } from "react";
4
- import { useFormFieldControl as ve } from "../form-field/index.mjs";
5
- import { I as Ie } from "../Icon-D1RueiPY.mjs";
6
- import { Minus as xe } from "@spark-ui/icons/Minus";
7
- const se = fe(null), he = () => {
8
- const e = me(se);
2
+ import { c as pe, a as fe } from "../index-BmAFn37q.mjs";
3
+ import { createContext as me, useContext as be, useId as ve, useRef as Z, useState as L, useEffect as $, useMemo as H, Children as ne, isValidElement as re, cloneElement as ee } from "react";
4
+ import { useFormFieldControl as Ie } from "../form-field/index.mjs";
5
+ import { I as xe } from "../Icon-D1RueiPY.mjs";
6
+ import { Minus as he } from "@spark-ui/icons/Minus";
7
+ const se = me(null), ye = () => {
8
+ const e = be(se);
9
9
  if (!e)
10
10
  throw new Error("InputOTP components must be used within InputOTP");
11
11
  return e;
12
- }, ae = de(
12
+ }, ae = pe(
13
13
  [
14
14
  // Base slot styles
15
15
  "relative",
@@ -50,8 +50,8 @@ const se = fe(null), he = () => {
50
50
  intent: "neutral"
51
51
  }
52
52
  }
53
- ), Fe = ae, E = ({ index: e, className: a, ...t }) => {
54
- const o = he(), r = e ?? 0, l = o.slots[r];
53
+ ), Ke = ae, E = ({ index: e, className: a, ...t }) => {
54
+ const o = ye(), r = e ?? 0, l = o.slots[r];
55
55
  if (!l)
56
56
  return null;
57
57
  const { char: p, isActive: v, hasFakeCaret: h } = l, I = !p && !h && o.placeholder;
@@ -81,7 +81,7 @@ const se = fe(null), he = () => {
81
81
  );
82
82
  };
83
83
  E.displayName = "InputOTP.Slot";
84
- const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te = "ArrowDown", we = "e", Re = ({
84
+ const Pe = "Backspace", ge = "ArrowLeft", Te = "ArrowUp", Oe = "ArrowRight", we = "ArrowDown", Ne = "e", Re = ({
85
85
  maxLength: e,
86
86
  type: a,
87
87
  value: t,
@@ -94,26 +94,26 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
94
94
  filterKeys: g,
95
95
  pattern: I,
96
96
  placeholder: C,
97
- nameProp: z
97
+ nameProp: G
98
98
  }) => {
99
- const B = be(), s = Z(null), V = Z(null), c = ve(), O = c.id ?? B, k = z ?? c.name, x = c.disabled ?? p, D = c.isInvalid ?? !l, W = c.isRequired ?? !1, Y = c.labelId, _ = c.description, T = c.state, w = ["success", "alert", "error"].includes(T ?? "") ? T : D ? "error" : "neutral", y = t !== void 0 ? t : o, K = h ? y.toUpperCase() : y, [G, R] = L(K), [S, F] = L(!1), u = t !== void 0 ? t : G, f = Math.min(u.length, e - 1);
100
- U(() => {
99
+ const z = ve(), s = Z(null), B = Z(null), c = Ie(), T = c.id ?? z, D = G ?? c.name, x = c.disabled ?? p, _ = c.isInvalid ?? !l, V = c.isRequired ?? !1, W = c.labelId, k = c.description, O = c.state, w = ["success", "alert", "error"].includes(O ?? "") ? O : _ ? "error" : "neutral", y = t !== void 0 ? t : o, F = h ? y.toUpperCase() : y, [q, N] = L(F), [R, K] = L(!1), u = t !== void 0 ? t : q, f = Math.min(u.length, e - 1);
100
+ $(() => {
101
101
  s.current && s.current.setSelectionRange(f, f);
102
102
  }, [f, u.length, e]);
103
- const j = H(
103
+ const M = H(
104
104
  () => Array.from({ length: e }, (i, n) => ({
105
105
  char: u[n] || "",
106
- isActive: n === f && S,
107
- hasFakeCaret: n === f && !u[n] && !x && S
106
+ isActive: n === f && R,
107
+ hasFakeCaret: n === f && !u[n] && !x && R
108
108
  })),
109
- [e, u, f, S, x]
109
+ [e, u, f, R, x]
110
110
  );
111
- U(() => {
111
+ $(() => {
112
112
  s.current && t !== void 0 && (s.current.value = t);
113
- }, [t]), U(() => {
113
+ }, [t]), $(() => {
114
114
  v && s.current && s.current.focus();
115
115
  }, [v]);
116
- const N = (i) => {
116
+ const S = (i) => {
117
117
  let n = i;
118
118
  if (h && (n = n.toUpperCase()), a === "number" && (n = n.replace(/[^\d]/g, "")), I)
119
119
  try {
@@ -127,23 +127,23 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
127
127
  return n;
128
128
  };
129
129
  return {
130
- uuid: O,
130
+ uuid: T,
131
131
  inputRef: s,
132
- containerRef: V,
133
- name: k,
132
+ containerRef: B,
133
+ name: D,
134
134
  disabled: x,
135
- isInvalid: D,
136
- isRequired: W,
137
- description: _,
135
+ isInvalid: _,
136
+ isRequired: V,
137
+ description: k,
138
138
  maxLength: e,
139
139
  intent: w,
140
140
  currentValue: u,
141
141
  activeIndex: f,
142
- slots: j,
142
+ slots: M,
143
143
  contextValue: {
144
144
  value: u,
145
145
  maxLength: e,
146
- slots: j,
146
+ slots: M,
147
147
  activeIndex: f,
148
148
  intent: w,
149
149
  disabled: x,
@@ -152,8 +152,8 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
152
152
  },
153
153
  handleChange: (i) => {
154
154
  if (x) return;
155
- const n = i.target.value, d = N(n).slice(0, e);
156
- r && r(d), t === void 0 && R(d);
155
+ const n = i.target.value, d = S(n).slice(0, e);
156
+ r && r(d), t === void 0 && N(d);
157
157
  const P = Math.min(d.length, e - 1);
158
158
  s.current && s.current.setSelectionRange(P, P);
159
159
  },
@@ -164,25 +164,25 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
164
164
  return;
165
165
  }
166
166
  switch (i.key) {
167
- case ye:
167
+ case Pe:
168
168
  i.preventDefault();
169
169
  const n = u.length;
170
170
  if (n > 0) {
171
171
  const m = u.slice(0, n - 1);
172
- r && r(m), t === void 0 && R(m);
172
+ r && r(m), t === void 0 && N(m);
173
173
  const d = Math.max(0, m.length);
174
174
  s.current && s.current.setSelectionRange(d, d);
175
175
  }
176
176
  break;
177
- case Pe:
177
+ case ge:
178
178
  case Oe:
179
179
  i.preventDefault();
180
180
  break;
181
- case ge:
182
181
  case Te:
182
+ case we:
183
183
  i.preventDefault();
184
184
  break;
185
- case we:
185
+ case Ne:
186
186
  case "E":
187
187
  a === "number" && i.preventDefault();
188
188
  break;
@@ -194,24 +194,24 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
194
194
  i.preventDefault();
195
195
  const n = i.clipboardData.getData("text");
196
196
  if (!n) return;
197
- const d = N(n).slice(0, e);
198
- r && r(d), t === void 0 && R(d);
197
+ const d = S(n).slice(0, e);
198
+ r && r(d), t === void 0 && N(d);
199
199
  const P = Math.min(d.length, e - 1);
200
200
  s.current && s.current.setSelectionRange(P, P);
201
201
  },
202
202
  handleFocus: () => {
203
- if (F(!0), s.current) {
203
+ if (K(!0), s.current) {
204
204
  const i = Math.min(u.length, e - 1);
205
205
  s.current.setSelectionRange(i, i);
206
206
  }
207
207
  },
208
208
  handleBlur: () => {
209
- F(!1);
209
+ K(!1);
210
210
  },
211
211
  handleClick: () => {
212
212
  s.current && s.current.focus();
213
213
  },
214
- labelId: Y
214
+ labelId: W
215
215
  };
216
216
  }, ie = (e) => {
217
217
  let a = 0;
@@ -255,14 +255,14 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
255
255
  forceUppercase: g = !1,
256
256
  filterKeys: I = ["-", "."],
257
257
  pattern: C,
258
- inputMode: z,
259
- placeholder: B = "",
258
+ inputMode: G,
259
+ placeholder: z = "",
260
260
  name: s,
261
- className: V,
261
+ className: B,
262
262
  children: c,
263
- ...O
263
+ ...T
264
264
  }) => {
265
- const k = H(() => {
265
+ const D = H(() => {
266
266
  if (e !== void 0)
267
267
  return e;
268
268
  const A = ie(c);
@@ -271,25 +271,25 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
271
271
  const [A] = oe(c);
272
272
  return A;
273
273
  }, [c]), {
274
- uuid: D,
275
- inputRef: W,
276
- containerRef: Y,
277
- name: _,
278
- disabled: T,
279
- isInvalid: q,
274
+ uuid: _,
275
+ inputRef: V,
276
+ containerRef: W,
277
+ name: k,
278
+ disabled: O,
279
+ isInvalid: Y,
280
280
  isRequired: w,
281
281
  description: y,
282
- currentValue: K,
283
- contextValue: G,
284
- handleChange: R,
285
- handleKeyDown: S,
286
- handlePaste: F,
282
+ currentValue: F,
283
+ contextValue: q,
284
+ handleChange: N,
285
+ handleKeyDown: R,
286
+ handlePaste: K,
287
287
  handleFocus: u,
288
288
  handleBlur: f,
289
- handleClick: j,
290
- labelId: N
289
+ handleClick: M,
290
+ labelId: S
291
291
  } = Re({
292
- maxLength: k,
292
+ maxLength: D,
293
293
  type: a,
294
294
  value: t,
295
295
  defaultValue: o,
@@ -300,56 +300,56 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
300
300
  forceUppercase: g,
301
301
  filterKeys: I,
302
302
  pattern: C,
303
- placeholder: B,
303
+ placeholder: z,
304
304
  nameProp: s
305
- }), $ = "aria-label" in O ? O["aria-label"] : void 0, { "aria-label": le, ...X } = O, M = N ? { "aria-labelledby": N } : $ ? { "aria-label": $ } : {};
306
- return /* @__PURE__ */ b(se.Provider, { value: G, children: /* @__PURE__ */ te(
305
+ }), U = "aria-label" in T ? T["aria-label"] : void 0, { "aria-label": le, ...Q } = T, j = S ? { "aria-labelledby": S } : U ? { "aria-label": U } : {};
306
+ return /* @__PURE__ */ b(se.Provider, { value: q, children: /* @__PURE__ */ te(
307
307
  "div",
308
308
  {
309
- ref: Y,
309
+ ref: W,
310
310
  "data-spark-component": "input-otp",
311
311
  role: "group",
312
- ...M,
312
+ ...j,
313
313
  ...y ? { "aria-describedby": y } : {},
314
- className: pe(
314
+ className: fe(
315
315
  "gap-md relative inline-flex items-center",
316
- T ? "cursor-not-allowed" : "cursor-text",
317
- V
316
+ O ? "cursor-not-allowed" : "cursor-text",
317
+ B
318
318
  ),
319
- onClick: j,
320
- ...X,
319
+ onClick: M,
320
+ ...Q,
321
321
  children: [
322
- _ && /* @__PURE__ */ b(
322
+ k && /* @__PURE__ */ b(
323
323
  "input",
324
324
  {
325
325
  type: "hidden",
326
- name: _,
327
- value: K,
326
+ name: k,
327
+ value: F,
328
328
  required: w,
329
329
  "aria-required": w,
330
- "aria-invalid": q,
331
- ...M
330
+ "aria-invalid": Y,
331
+ ...j
332
332
  }
333
333
  ),
334
334
  /* @__PURE__ */ b(
335
335
  "input",
336
336
  {
337
- ref: W,
338
- id: D,
337
+ ref: V,
338
+ id: _,
339
339
  type: a === "password" ? "password" : "text",
340
- value: K,
341
- maxLength: k,
340
+ value: F,
341
+ maxLength: D,
342
342
  autoFocus: v,
343
343
  autoComplete: h,
344
- disabled: T,
344
+ disabled: O,
345
345
  pattern: C,
346
- inputMode: z,
347
- ...M,
346
+ inputMode: G,
347
+ ...j,
348
348
  ...y ? { "aria-describedby": y } : {},
349
- "aria-invalid": q,
350
- onChange: R,
351
- onKeyDown: S,
352
- onPaste: F,
349
+ "aria-invalid": Y,
350
+ onChange: N,
351
+ onKeyDown: R,
352
+ onPaste: K,
353
353
  onFocus: u,
354
354
  onBlur: f,
355
355
  className: "bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed",
@@ -362,29 +362,29 @@ const ye = "Backspace", Pe = "ArrowLeft", ge = "ArrowUp", Oe = "ArrowRight", Te
362
362
  ) });
363
363
  };
364
364
  ce.displayName = "InputOTP";
365
- const J = ({ children: e, className: a, ...t }) => /* @__PURE__ */ b("div", { className: `inline-flex [&>*:not(:first-child)]:-ml-px ${a || ""}`, ...t, children: e });
366
- J.displayName = "InputOTP.Group";
367
- const Q = ({ className: e, ...a }) => /* @__PURE__ */ b(
365
+ const X = ({ children: e, className: a, ...t }) => /* @__PURE__ */ b("div", { className: `inline-flex [&>*:not(:first-child)]:-ml-px ${a || ""}`, ...t, children: e });
366
+ X.displayName = "InputOTP.Group";
367
+ const J = ({ className: e, ...a }) => /* @__PURE__ */ b(
368
368
  "div",
369
369
  {
370
370
  className: `text-on-surface flex items-center justify-center ${e || ""}`,
371
371
  ...a,
372
- children: /* @__PURE__ */ b(Ie, { size: "md", children: /* @__PURE__ */ b(xe, {}) })
372
+ children: /* @__PURE__ */ b(xe, { size: "md", children: /* @__PURE__ */ b(he, {}) })
373
373
  }
374
374
  );
375
- Q.displayName = "InputOTP.Separator";
375
+ J.displayName = "InputOTP.Separator";
376
376
  const Se = Object.assign(ce, {
377
- Group: J,
377
+ Group: X,
378
378
  Slot: E,
379
- Separator: Q
379
+ Separator: J
380
380
  });
381
381
  Se.displayName = "InputOTP";
382
- J.displayName = "InputOTP.Group";
382
+ X.displayName = "InputOTP.Group";
383
383
  E.displayName = "InputOTP.Slot";
384
- Q.displayName = "InputOTP.Separator";
384
+ J.displayName = "InputOTP.Separator";
385
385
  export {
386
386
  Se as InputOTP,
387
387
  ae as inputOTPSlotStyles,
388
- Fe as inputOTPStyles
388
+ Ke as inputOTPStyles
389
389
  };
390
390
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/input-otp/InputOTPContext.tsx","../../src/input-otp/InputOTP.styles.ts","../../src/input-otp/InputOTPSlot.tsx","../../src/input-otp/useInputOTP.ts","../../src/input-otp/InputOTP.tsx","../../src/input-otp/InputOTPGroup.tsx","../../src/input-otp/InputOTPSeparator.tsx","../../src/input-otp/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputOTPContextValue {\n value: string\n maxLength: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n activeIndex: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n disabled: boolean\n placeholder?: string\n type: 'text' | 'number' | 'password' | 'tel'\n}\n\nexport const InputOTPContext = createContext<InputOTPContextValue | null>(null)\n\nexport const useInputOTPContext = () => {\n const context = useContext(InputOTPContext)\n if (!context) {\n throw new Error('InputOTP components must be used within InputOTP')\n }\n\n return context\n}\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputOTPContainerStyles = cva(['relative', 'inline-flex', 'items-center', 'gap-sm'])\n\nexport const inputOTPSlotStyles = cva(\n [\n // Base slot styles\n 'relative',\n 'border-sm first:rounded-l-lg last:rounded-r-lg',\n 'size-sz-44',\n 'text-center text-body-1',\n 'text-on-surface',\n 'outline-hidden',\n 'transition-colors',\n 'flex items-center justify-center',\n // Active state (when focused)\n 'data-[active=true]:ring-1',\n 'data-[active=true]:ring-inset',\n 'data-[active=true]:ring-l-2',\n\n 'data-[active=true]:border-focus',\n // 'data-[active=true]:ring-focus',\n // 'data-[active=true]:border-focus',\n 'data-[active=true]:z-raised ring-focus',\n // Disabled state\n 'data-[disabled=true]:cursor-not-allowed',\n 'data-[disabled=true]:border-outline',\n 'data-[disabled=true]:bg-on-surface/dim-5',\n 'data-[disabled=true]:text-on-surface/dim-3',\n ],\n {\n variants: {\n /**\n * Color scheme of the slot\n */\n intent: {\n neutral: ['bg-surface border-outline'],\n success: ['border-success bg-success-container text-on-success-container'],\n alert: ['border-alert bg-alert-container text-on-alert-container'],\n error: ['border-error bg-error-container text-on-error-container'],\n },\n },\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputOTPSlotStylesProps = VariantProps<typeof inputOTPSlotStyles>\n\n// Keep for backward compatibility\nexport const inputOTPStyles = inputOTPSlotStyles\nexport type InputOTPStylesProps = InputOTPSlotStylesProps\n","import { ComponentPropsWithoutRef } from 'react'\n\nimport { inputOTPSlotStyles } from './InputOTP.styles'\nimport { useInputOTPContext } from './InputOTPContext'\n\nexport interface InputOTPSlotProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Index of the slot (0-based).\n * If not provided, will be automatically assigned based on position in children.\n */\n index?: number\n}\n\nexport const InputOTPSlot = ({ index: indexProp, className, ...props }: InputOTPSlotProps) => {\n const context = useInputOTPContext()\n\n // Use provided index or fallback to 0 (should not happen if auto-assignment works)\n const index = indexProp ?? 0\n const slot = context.slots[index]\n\n if (!slot) {\n return null\n }\n\n const { char, isActive, hasFakeCaret } = slot\n const isEmpty = !char\n const isPlaceholder = isEmpty && !hasFakeCaret && context.placeholder\n\n return (\n <div\n className={inputOTPSlotStyles({\n intent: context.intent,\n className,\n })}\n data-active={isActive}\n data-disabled={context.disabled}\n data-valid={context.intent !== 'error'}\n {...props}\n >\n <span className={isPlaceholder ? 'text-on-surface/dim-3' : ''}>\n {context.type === 'password' && char\n ? '•'\n : char || (!hasFakeCaret && context.placeholder ? context.placeholder : '')}\n </span>\n {hasFakeCaret && (\n <span\n className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"bg-on-surface animate-standalone-caret-blink h-sz-24 w-px\" />\n </span>\n )}\n </div>\n )\n}\n\nInputOTPSlot.displayName = 'InputOTP.Slot'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport {\n ChangeEventHandler,\n ClipboardEventHandler,\n KeyboardEventHandler,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport type { InputOTPContextValue } from './InputOTPContext'\n\nconst BACKSPACE_KEY = 'Backspace'\nconst LEFT_ARROW_KEY = 'ArrowLeft'\nconst UP_ARROW_KEY = 'ArrowUp'\nconst RIGHT_ARROW_KEY = 'ArrowRight'\nconst DOWN_ARROW_KEY = 'ArrowDown'\nconst E_KEY = 'e'\n\nexport interface UseInputOTPProps {\n maxLength: number\n type: 'text' | 'number' | 'password' | 'tel'\n value?: string\n defaultValue: string\n onValueChange?: (value: string) => void\n isValid: boolean\n disabledProp: boolean\n autoFocus: boolean\n forceUppercase: boolean\n filterKeys: string[]\n pattern?: string\n placeholder: string\n nameProp?: string\n}\n\nexport interface UseInputOTPReturn {\n uuid: string\n inputRef: React.RefObject<HTMLInputElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n name: string | undefined\n disabled: boolean\n isInvalid: boolean\n isRequired: boolean\n description: string | undefined\n maxLength: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n currentValue: string\n activeIndex: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n contextValue: InputOTPContextValue\n handleChange: ChangeEventHandler<HTMLInputElement>\n handleKeyDown: KeyboardEventHandler<HTMLInputElement>\n handlePaste: ClipboardEventHandler<HTMLInputElement>\n handleFocus: () => void\n handleBlur: () => void\n handleClick: () => void\n labelId: string | undefined\n}\n\nexport const useInputOTP = ({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n}: UseInputOTPProps): UseInputOTPReturn => {\n const uuid = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Get FormField context (optional, falls back gracefully if not present)\n const field = useFormFieldControl()\n\n // Use FormField values if available, otherwise fall back to props\n // Use FormField id when available so label htmlFor works correctly\n const id = field.id ?? uuid\n const name = nameProp ?? field.name\n const disabled = field.disabled ?? disabledProp\n const isInvalid = field.isInvalid ?? !isValid\n const isRequired = field.isRequired ?? false\n const labelId = field.labelId\n const description = field.description\n const fieldState = field.state\n\n // Determine intent based on FormField state or isValid prop\n const getIntent = (): 'neutral' | 'success' | 'alert' | 'error' => {\n // FormField state takes priority\n if (['success', 'alert', 'error'].includes(fieldState ?? '')) {\n return fieldState as 'success' | 'alert' | 'error'\n }\n\n // Fallback to isValid prop for backward compatibility\n if (isInvalid) {\n return 'error'\n }\n\n return 'neutral'\n }\n\n const intent = getIntent()\n\n // Initialize value\n const initialValue = controlledValue !== undefined ? controlledValue : defaultValue\n const processedValue = forceUppercase ? initialValue.toUpperCase() : initialValue\n\n const [internalValue, setInternalValue] = useState<string>(processedValue)\n const [isFocused, setIsFocused] = useState<boolean>(false)\n\n // Use controlled value if provided, otherwise use internal state\n const currentValue = controlledValue !== undefined ? controlledValue : internalValue\n\n // Calculate active index: last empty slot, or last slot if all are filled\n const activeIndex = Math.min(currentValue.length, maxLength - 1)\n\n // Sync cursor position with active index\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.setSelectionRange(activeIndex, activeIndex)\n }\n }, [activeIndex, currentValue.length, maxLength])\n\n // Create slots array\n const slots = useMemo(\n () =>\n Array.from({ length: maxLength }, (_, i) => ({\n char: currentValue[i] || '',\n isActive: i === activeIndex && isFocused,\n hasFakeCaret: i === activeIndex && !currentValue[i] && !disabled && isFocused,\n })),\n [maxLength, currentValue, activeIndex, isFocused, disabled]\n )\n\n // Sync controlled value with input ref\n useEffect(() => {\n if (inputRef.current && controlledValue !== undefined) {\n inputRef.current.value = controlledValue\n }\n }, [controlledValue])\n\n // Focus management\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n }\n }, [autoFocus])\n\n const processInputValue = (inputValue: string): string => {\n let processed = inputValue\n\n if (forceUppercase) {\n processed = processed.toUpperCase()\n }\n\n if (type === 'number') {\n processed = processed.replace(/[^\\d]/g, '')\n }\n\n // Filter characters using pattern if provided\n if (pattern) {\n try {\n // Convert HTML pattern (string) to RegExp\n // HTML patterns validate the entire string, but we need to test each character\n // We create a regex that tests if a single character matches the pattern\n // For example: [0-9]* becomes ^[0-9]$ to test a single digit\n // We wrap the pattern in ^...$ to ensure it matches a single character\n let regexPattern = pattern\n // If pattern doesn't start with ^, wrap it to test single character\n if (!pattern.startsWith('^')) {\n regexPattern = `^${pattern}$`\n }\n const regex = new RegExp(regexPattern)\n processed = processed\n .split('')\n .filter(currChar => {\n // Test if the character matches the pattern\n return regex.test(currChar)\n })\n .join('')\n } catch (error) {\n // If pattern is invalid, ignore it and continue with other filters\n console.error('Invalid pattern provided to InputOTP:', pattern, error)\n }\n }\n\n return processed\n }\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n const inputValue = e.target.value\n const processedValue = processInputValue(inputValue)\n\n // Limit to maxLength\n const newValue = processedValue.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n // Filter keys\n if (filterKeys.length > 0 && filterKeys.includes(e.key)) {\n e.preventDefault()\n\n return\n }\n\n switch (e.key) {\n case BACKSPACE_KEY:\n e.preventDefault()\n const currentLength = currentValue.length\n if (currentLength > 0) {\n const newValue = currentValue.slice(0, currentLength - 1)\n\n // Call onValueChange first\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.max(0, newValue.length)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n break\n\n case LEFT_ARROW_KEY:\n case RIGHT_ARROW_KEY:\n // Prevent navigation with arrow keys - focus stays on last empty slot\n e.preventDefault()\n break\n\n case UP_ARROW_KEY:\n case DOWN_ARROW_KEY:\n e.preventDefault()\n break\n\n case E_KEY:\n case 'E':\n // Prevent 'e' or 'E' in number inputs\n if (type === 'number') {\n e.preventDefault()\n }\n break\n\n default:\n break\n }\n }\n\n const handlePaste: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n e.preventDefault()\n\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText) return\n\n const processedText = processInputValue(pastedText)\n const newValue = processedText.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Move cursor to end\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleFocus = () => {\n setIsFocused(true)\n if (inputRef.current) {\n // Focus on last empty slot, or last slot if all are filled\n const cursorPosition = Math.min(currentValue.length, maxLength - 1)\n inputRef.current.setSelectionRange(cursorPosition, cursorPosition)\n }\n }\n\n const handleBlur = () => {\n setIsFocused(false)\n }\n\n const handleClick = () => {\n if (inputRef.current) {\n inputRef.current.focus()\n }\n }\n\n const contextValue: InputOTPContextValue = {\n value: currentValue,\n maxLength,\n slots,\n activeIndex,\n intent,\n disabled,\n placeholder,\n type,\n }\n\n const returnValue: UseInputOTPReturn = {\n uuid: id,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n maxLength,\n intent,\n currentValue,\n activeIndex,\n slots,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n }\n\n return returnValue\n}\n","/* eslint-disable max-lines-per-function */\nimport { cx } from 'class-variance-authority'\nimport {\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n isValidElement,\n ReactElement,\n ReactNode,\n Ref,\n useMemo,\n} from 'react'\n\nimport { InputOTPContext } from './InputOTPContext'\nimport { InputOTPSlot } from './InputOTPSlot'\nimport { useInputOTP } from './useInputOTP'\n\n/**\n * Counts the number of InputOTPSlot components in the children tree\n */\nconst countSlots = (children: ReactNode): number => {\n let count = 0\n\n Children.forEach(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { children?: ReactNode }\n // Check if it's an InputOTPSlot by checking displayName\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n count++\n } else if (props.children) {\n // Recursively count slots in nested children (e.g., inside InputOTPGroup)\n count += countSlots(props.children)\n }\n }\n })\n\n return count\n}\n\n/**\n * Recursively assigns index to InputOTPSlot components\n * Returns a tuple of [processedChildren, nextIndex]\n */\nconst assignSlotIndexes = (children: ReactNode, startIndex: number = 0): [ReactNode, number] => {\n let currentIndex = startIndex\n\n const processed = Children.map(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { index?: number; children?: ReactNode }\n // Check if it's an InputOTPSlot\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n // Only assign index if not already provided\n const slotIndex = typeof props.index === 'number' ? props.index : currentIndex++\n\n return cloneElement(child as ReactElement<{ index?: number }>, {\n ...props,\n index: slotIndex,\n })\n } else if (props.children) {\n // Recursively process nested children\n const [processedChildren, nextIndex] = assignSlotIndexes(props.children, currentIndex)\n currentIndex = nextIndex\n\n return cloneElement(child, {\n ...(child.props as Record<string, unknown>),\n children: processedChildren,\n } as Parameters<typeof cloneElement>[1])\n }\n }\n\n return child\n })\n\n return [processed, currentIndex]\n}\n\nexport interface InputOTPProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'inputMode'> {\n /**\n * Maximum length of the input value.\n * If not provided, will be automatically detected from the number of InputOTP.Slot children.\n */\n maxLength?: number\n /**\n * Type of input\n * @default 'text'\n */\n type?: 'text' | 'number' | 'password' | 'tel'\n /**\n * Current value (controlled mode)\n */\n value?: string\n /**\n * Default value (uncontrolled mode)\n */\n defaultValue?: string\n /**\n * Callback fired when the value changes\n */\n onValueChange?: (value: string) => void\n /**\n * Whether the input is valid\n * @default true\n */\n isValid?: boolean\n /**\n * Whether the input is disabled\n * @default false\n */\n disabled?: boolean\n /**\n * Whether to auto-focus the input\n * @default false\n */\n autoFocus?: boolean\n /**\n * Auto-complete attribute\n * @default 'off'\n */\n autoComplete?: string\n /**\n * Whether to force uppercase\n * @default false\n */\n forceUppercase?: boolean\n /**\n * Array of keys to filter out (using KeyboardEvent.key values)\n * @default ['-', '.']\n */\n filterKeys?: string[]\n /**\n * Pattern attribute for input validation and character filtering.\n * Uses a regular expression to filter allowed characters in real-time.\n * For example: \"[0-9]\" for digits only, \"[a-c]\" for letters a, b, c only.\n */\n pattern?: string\n /**\n * Input mode attribute\n */\n inputMode?: string\n /**\n * Placeholder text\n */\n placeholder?: string\n /**\n * Name attribute for form integration\n */\n name?: string\n /**\n * Children components (InputOTPGroup, InputOTPSlot, InputOTPSeparator)\n */\n children: ReactNode\n /**\n * Ref callback for the container\n */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputOTP = ({\n maxLength: maxLengthProp,\n type = 'text',\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n isValid = true,\n disabled: disabledProp = false,\n autoFocus = false,\n autoComplete = 'off',\n forceUppercase = false,\n filterKeys = ['-', '.'],\n pattern,\n inputMode,\n placeholder = '',\n name: nameProp,\n className,\n children,\n ...others\n}: InputOTPProps) => {\n // Auto-detect maxLength from children if not provided\n const maxLength = useMemo(() => {\n if (maxLengthProp !== undefined) {\n return maxLengthProp\n }\n\n const detectedLength = countSlots(children)\n\n return detectedLength > 0 ? detectedLength : 4 // fallback to 4 if no slots found\n }, [maxLengthProp, children])\n\n // Assign indexes to slots automatically\n const processedChildren = useMemo(() => {\n const [processed] = assignSlotIndexes(children)\n\n return processed\n }, [children])\n\n // Use the hook for all business logic\n const {\n uuid,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n currentValue,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n } = useInputOTP({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n })\n\n // Extract aria-label from others if provided (for cases without FormField)\n const ariaLabel =\n 'aria-label' in others ? (others['aria-label'] as string | undefined) : undefined\n const { 'aria-label': _, ...restOthers } = others\n\n // Determine accessible name props\n const getAccessibleNameProps = (): Record<string, string | undefined> => {\n if (labelId) {\n return { 'aria-labelledby': labelId }\n }\n\n if (ariaLabel) {\n return { 'aria-label': ariaLabel }\n }\n\n return {}\n }\n\n const accessibleNameProps = getAccessibleNameProps()\n\n return (\n <InputOTPContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n data-spark-component=\"input-otp\"\n role=\"group\"\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n className={cx(\n 'gap-md relative inline-flex items-center',\n disabled ? 'cursor-not-allowed' : 'cursor-text',\n className\n )}\n onClick={handleClick}\n {...restOthers}\n >\n {/* Hidden input for form submission with complete value */}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValue}\n required={isRequired}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n {...accessibleNameProps}\n />\n )}\n {/* Actual input that handles all interactions */}\n <input\n ref={inputRef}\n id={uuid}\n type={type === 'password' ? 'password' : 'text'}\n value={currentValue}\n maxLength={maxLength}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n disabled={disabled}\n pattern={pattern}\n inputMode={inputMode as React.InputHTMLAttributes<HTMLInputElement>['inputMode']}\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed\"\n tabIndex={0}\n />\n {/* Children render slots with auto-assigned indexes */}\n {processedChildren}\n </div>\n </InputOTPContext.Provider>\n )\n}\n\nInputOTP.displayName = 'InputOTP'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPGroupProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPGroup = ({ children, className, ...props }: InputOTPGroupProps) => {\n return (\n <div className={`inline-flex [&>*:not(:first-child)]:-ml-px ${className || ''}`} {...props}>\n {children}\n </div>\n )\n}\n\nInputOTPGroup.displayName = 'InputOTP.Group'\n","import { Icon } from '@spark-ui/components/icon'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPSeparatorProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPSeparator = ({ className, ...props }: InputOTPSeparatorProps) => {\n return (\n <div\n className={`text-on-surface flex items-center justify-center ${className || ''}`}\n {...props}\n >\n <Icon size=\"md\">\n <Minus />\n </Icon>\n </div>\n )\n}\n\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n","import { InputOTP as Root } from './InputOTP'\nimport { InputOTPGroup } from './InputOTPGroup'\nimport { InputOTPSeparator } from './InputOTPSeparator'\nimport { InputOTPSlot } from './InputOTPSlot'\n\nexport const InputOTP: typeof Root & {\n Group: typeof InputOTPGroup\n Slot: typeof InputOTPSlot\n Separator: typeof InputOTPSeparator\n} = Object.assign(Root, {\n Group: InputOTPGroup,\n Slot: InputOTPSlot,\n Separator: InputOTPSeparator,\n})\n\nInputOTP.displayName = 'InputOTP'\nInputOTPGroup.displayName = 'InputOTP.Group'\nInputOTPSlot.displayName = 'InputOTP.Slot'\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n\nexport { type InputOTPProps } from './InputOTP'\nexport { type InputOTPGroupProps } from './InputOTPGroup'\nexport { type InputOTPSlotProps } from './InputOTPSlot'\nexport { type InputOTPSeparatorProps } from './InputOTPSeparator'\nexport {\n inputOTPSlotStyles,\n inputOTPStyles,\n type InputOTPSlotStylesProps,\n type InputOTPStylesProps,\n} from './InputOTP.styles'\n"],"names":["InputOTPContext","createContext","useInputOTPContext","context","useContext","inputOTPSlotStyles","cva","inputOTPStyles","InputOTPSlot","indexProp","className","props","index","slot","char","isActive","hasFakeCaret","isPlaceholder","jsxs","jsx","BACKSPACE_KEY","LEFT_ARROW_KEY","UP_ARROW_KEY","RIGHT_ARROW_KEY","DOWN_ARROW_KEY","E_KEY","useInputOTP","maxLength","type","controlledValue","defaultValue","onValueChange","isValid","disabledProp","autoFocus","forceUppercase","filterKeys","pattern","placeholder","nameProp","uuid","useId","inputRef","useRef","containerRef","field","useFormFieldControl","id","name","disabled","isInvalid","isRequired","labelId","description","fieldState","intent","initialValue","processedValue","internalValue","setInternalValue","useState","isFocused","setIsFocused","currentValue","activeIndex","useEffect","slots","useMemo","_","i","processInputValue","inputValue","processed","regexPattern","regex","currChar","error","e","newValue","newActiveIndex","currentLength","pastedText","cursorPosition","countSlots","children","count","Children","child","isValidElement","assignSlotIndexes","startIndex","currentIndex","slotIndex","cloneElement","processedChildren","nextIndex","InputOTP","maxLengthProp","autoComplete","inputMode","others","detectedLength","contextValue","handleChange","handleKeyDown","handlePaste","handleFocus","handleBlur","handleClick","ariaLabel","restOthers","accessibleNameProps","cx","InputOTPGroup","InputOTPSeparator","Icon","Minus","Root"],"mappings":";;;;;;AAiBO,MAAMA,KAAkBC,GAA2C,IAAI,GAEjEC,KAAqB,MAAM;AACtC,QAAMC,IAAUC,GAAWJ,EAAe;AAC1C,MAAI,CAACG;AACH,UAAM,IAAI,MAAM,kDAAkD;AAGpE,SAAOA;AACT,GCtBaE,KAAqBC;AAAA,EAChC;AAAA;AAAA,IAEE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA,MAIR,QAAQ;AAAA,QACN,SAAS,CAAC,2BAA2B;AAAA,QACrC,SAAS,CAAC,+DAA+D;AAAA,QACzE,OAAO,CAAC,yDAAyD;AAAA,QACjE,OAAO,CAAC,yDAAyD;AAAA,MAAA;AAAA,IACnE;AAAA,IAEF,iBAAiB;AAAA,MACf,QAAQ;AAAA,IAAA;AAAA,EACV;AAEJ,GAKaC,KAAiBF,ICtCjBG,IAAe,CAAC,EAAE,OAAOC,GAAW,WAAAC,GAAW,GAAGC,QAA+B;AAC5F,QAAMR,IAAUD,GAAA,GAGVU,IAAQH,KAAa,GACrBI,IAAOV,EAAQ,MAAMS,CAAK;AAEhC,MAAI,CAACC;AACH,WAAO;AAGT,QAAM,EAAE,MAAAC,GAAM,UAAAC,GAAU,cAAAC,EAAA,IAAiBH,GAEnCI,IADU,CAACH,KACgB,CAACE,KAAgBb,EAAQ;AAE1D,SACE,gBAAAe;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWb,GAAmB;AAAA,QAC5B,QAAQF,EAAQ;AAAA,QAChB,WAAAO;AAAA,MAAA,CACD;AAAA,MACD,eAAaK;AAAA,MACb,iBAAeZ,EAAQ;AAAA,MACvB,cAAYA,EAAQ,WAAW;AAAA,MAC9B,GAAGQ;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAQ,EAAC,UAAK,WAAWF,IAAgB,0BAA0B,IACxD,YAAQ,SAAS,cAAcH,IAC5B,MACAA,MAAS,CAACE,KAAgBb,EAAQ,cAAcA,EAAQ,cAAc,KAC5E;AAAA,QACCa,KACC,gBAAAG;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,eAAY;AAAA,YAEZ,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,4DAAA,CAA4D;AAAA,UAAA;AAAA,QAAA;AAAA,MAC9E;AAAA,IAAA;AAAA,EAAA;AAIR;AAEAX,EAAa,cAAc;ACzC3B,MAAMY,KAAgB,aAChBC,KAAiB,aACjBC,KAAe,WACfC,KAAkB,cAClBC,KAAiB,aACjBC,KAAQ,KA8CDC,KAAc,CAAC;AAAA,EAC1B,WAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAOC;AAAA,EACP,cAAAC;AAAA,EACA,eAAAC;AAAA,EACA,SAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AACF,MAA2C;AACzC,QAAMC,IAAOC,GAAA,GACPC,IAAWC,EAAyB,IAAI,GACxCC,IAAeD,EAAuB,IAAI,GAG1CE,IAAQC,GAAA,GAIRC,IAAKF,EAAM,MAAML,GACjBQ,IAAOT,KAAYM,EAAM,MACzBI,IAAWJ,EAAM,YAAYZ,GAC7BiB,IAAYL,EAAM,aAAa,CAACb,GAChCmB,IAAaN,EAAM,cAAc,IACjCO,IAAUP,EAAM,SAChBQ,IAAcR,EAAM,aACpBS,IAAaT,EAAM,OAiBnBU,IAZA,CAAC,WAAW,SAAS,OAAO,EAAE,SAASD,KAAc,EAAE,IAClDA,IAILJ,IACK,UAGF,WAMHM,IAAe3B,MAAoB,SAAYA,IAAkBC,GACjE2B,IAAiBtB,IAAiBqB,EAAa,YAAA,IAAgBA,GAE/D,CAACE,GAAeC,CAAgB,IAAIC,EAAiBH,CAAc,GACnE,CAACI,GAAWC,CAAY,IAAIF,EAAkB,EAAK,GAGnDG,IAAelC,MAAoB,SAAYA,IAAkB6B,GAGjEM,IAAc,KAAK,IAAID,EAAa,QAAQpC,IAAY,CAAC;AAG/D,EAAAsC,EAAU,MAAM;AACd,IAAIvB,EAAS,WACXA,EAAS,QAAQ,kBAAkBsB,GAAaA,CAAW;AAAA,EAE/D,GAAG,CAACA,GAAaD,EAAa,QAAQpC,CAAS,CAAC;AAGhD,QAAMuC,IAAQC;AAAA,IACZ,MACE,MAAM,KAAK,EAAE,QAAQxC,KAAa,CAACyC,GAAGC,OAAO;AAAA,MAC3C,MAAMN,EAAaM,CAAC,KAAK;AAAA,MACzB,UAAUA,MAAML,KAAeH;AAAA,MAC/B,cAAcQ,MAAML,KAAe,CAACD,EAAaM,CAAC,KAAK,CAACpB,KAAYY;AAAA,IAAA,EACpE;AAAA,IACJ,CAAClC,GAAWoC,GAAcC,GAAaH,GAAWZ,CAAQ;AAAA,EAAA;AAI5D,EAAAgB,EAAU,MAAM;AACd,IAAIvB,EAAS,WAAWb,MAAoB,WAC1Ca,EAAS,QAAQ,QAAQb;AAAA,EAE7B,GAAG,CAACA,CAAe,CAAC,GAGpBoC,EAAU,MAAM;AACd,IAAI/B,KAAaQ,EAAS,WACxBA,EAAS,QAAQ,MAAA;AAAA,EAErB,GAAG,CAACR,CAAS,CAAC;AAEd,QAAMoC,IAAoB,CAACC,MAA+B;AACxD,QAAIC,IAAYD;AAWhB,QATIpC,MACFqC,IAAYA,EAAU,YAAA,IAGpB5C,MAAS,aACX4C,IAAYA,EAAU,QAAQ,UAAU,EAAE,IAIxCnC;AACF,UAAI;AAMF,YAAIoC,IAAepC;AAEnB,QAAKA,EAAQ,WAAW,GAAG,MACzBoC,IAAe,IAAIpC,CAAO;AAE5B,cAAMqC,IAAQ,IAAI,OAAOD,CAAY;AACrC,QAAAD,IAAYA,EACT,MAAM,EAAE,EACR,OAAO,CAAAG,MAECD,EAAM,KAAKC,CAAQ,CAC3B,EACA,KAAK,EAAE;AAAA,MACZ,SAASC,GAAO;AAEd,gBAAQ,MAAM,yCAAyCvC,GAASuC,CAAK;AAAA,MACvE;AAGF,WAAOJ;AAAA,EACT;AA6KA,SAxBuC;AAAA,IACrC,MAAMzB;AAAA,IACN,UAAAL;AAAA,IACA,cAAAE;AAAA,IACA,MAAAI;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,aAAAE;AAAA,IACA,WAAA1B;AAAA,IACA,QAAA4B;AAAA,IACA,cAAAQ;AAAA,IACA,aAAAC;AAAA,IACA,OAAAE;AAAA,IACA,cAzByC;AAAA,MACzC,OAAOH;AAAA,MACP,WAAApC;AAAA,MACA,OAAAuC;AAAA,MACA,aAAAF;AAAA,MACA,QAAAT;AAAA,MACA,UAAAN;AAAA,MACA,aAAAX;AAAA,MACA,MAAAV;AAAA,IAAA;AAAA,IAkBA,cAlKyD,CAAAiD,MAAK;AAC9D,UAAI5B,EAAU;AAEd,YAAMsB,IAAaM,EAAE,OAAO,OAItBC,IAHiBR,EAAkBC,CAAU,EAGnB,MAAM,GAAG5C,CAAS;AAGlD,MAAII,KACFA,EAAc+C,CAAQ,GAIpBjD,MAAoB,UACtB8B,EAAiBmB,CAAQ;AAK3B,YAAMC,IAAiB,KAAK,IAAID,EAAS,QAAQnD,IAAY,CAAC;AAC9D,MAAIe,EAAS,WACXA,EAAS,QAAQ,kBAAkBqC,GAAgBA,CAAc;AAAA,IAErE;AAAA,IA0IE,eAxI4D,CAAAF,MAAK;AACjE,UAAI,CAAA5B,GAGJ;AAAA,YAAIb,EAAW,SAAS,KAAKA,EAAW,SAASyC,EAAE,GAAG,GAAG;AACvD,UAAAA,EAAE,eAAA;AAEF;AAAA,QACF;AAEA,gBAAQA,EAAE,KAAA;AAAA,UACR,KAAKzD;AACH,YAAAyD,EAAE,eAAA;AACF,kBAAMG,IAAgBjB,EAAa;AACnC,gBAAIiB,IAAgB,GAAG;AACrB,oBAAMF,IAAWf,EAAa,MAAM,GAAGiB,IAAgB,CAAC;AAGxD,cAAIjD,KACFA,EAAc+C,CAAQ,GAIpBjD,MAAoB,UACtB8B,EAAiBmB,CAAQ;AAK3B,oBAAMC,IAAiB,KAAK,IAAI,GAAGD,EAAS,MAAM;AAClD,cAAIpC,EAAS,WACXA,EAAS,QAAQ,kBAAkBqC,GAAgBA,CAAc;AAAA,YAErE;AACA;AAAA,UAEF,KAAK1D;AAAA,UACL,KAAKE;AAEH,YAAAsD,EAAE,eAAA;AACF;AAAA,UAEF,KAAKvD;AAAA,UACL,KAAKE;AACH,YAAAqD,EAAE,eAAA;AACF;AAAA,UAEF,KAAKpD;AAAA,UACL,KAAK;AAEH,YAAIG,MAAS,YACXiD,EAAE,eAAA;AAEJ;AAAA,QAGA;AAAA;AAAA,IAEN;AAAA,IA+EE,aA7E2D,CAAAA,MAAK;AAChE,UAAI5B,EAAU;AAEd,MAAA4B,EAAE,eAAA;AAEF,YAAMI,IAAaJ,EAAE,cAAc,QAAQ,MAAM;AAEjD,UAAI,CAACI,EAAY;AAGjB,YAAMH,IADgBR,EAAkBW,CAAU,EACnB,MAAM,GAAGtD,CAAS;AAGjD,MAAII,KACFA,EAAc+C,CAAQ,GAIpBjD,MAAoB,UACtB8B,EAAiBmB,CAAQ;AAK3B,YAAMC,IAAiB,KAAK,IAAID,EAAS,QAAQnD,IAAY,CAAC;AAC9D,MAAIe,EAAS,WACXA,EAAS,QAAQ,kBAAkBqC,GAAgBA,CAAc;AAAA,IAErE;AAAA,IAkDE,aAhDkB,MAAM;AAExB,UADAjB,EAAa,EAAI,GACbpB,EAAS,SAAS;AAEpB,cAAMwC,IAAiB,KAAK,IAAInB,EAAa,QAAQpC,IAAY,CAAC;AAClE,QAAAe,EAAS,QAAQ,kBAAkBwC,GAAgBA,CAAc;AAAA,MACnE;AAAA,IACF;AAAA,IA0CE,YAxCiB,MAAM;AACvB,MAAApB,EAAa,EAAK;AAAA,IACpB;AAAA,IAuCE,aArCkB,MAAM;AACxB,MAAIpB,EAAS,WACXA,EAAS,QAAQ,MAAA;AAAA,IAErB;AAAA,IAkCE,SAAAU;AAAA,EAAA;AAIJ,GClWM+B,KAAa,CAACC,MAAgC;AAClD,MAAIC,IAAQ;AAEZ,SAAAC,GAAS,QAAQF,GAAU,CAAAG,MAAS;AAClC,QAAIC,GAAeD,CAAK,GAAG;AACzB,YAAM5E,IAAQ4E,EAAM;AAEpB,MACEA,EAAM,SAAS/E,KACd+E,EAAM,MAAmC,gBAAgB,kBAE1DF,MACS1E,EAAM,aAEf0E,KAASF,GAAWxE,EAAM,QAAQ;AAAA,IAEtC;AAAA,EACF,CAAC,GAEM0E;AACT,GAMMI,KAAoB,CAACL,GAAqBM,IAAqB,MAA2B;AAC9F,MAAIC,IAAeD;AAgCnB,SAAO,CA9BWJ,GAAS,IAAIF,GAAU,CAAAG,MAAS;AAChD,QAAIC,GAAeD,CAAK,GAAG;AACzB,YAAM5E,IAAQ4E,EAAM;AAEpB,UACEA,EAAM,SAAS/E,KACd+E,EAAM,MAAmC,gBAAgB,iBAC1D;AAEA,cAAMK,IAAY,OAAOjF,EAAM,SAAU,WAAWA,EAAM,QAAQgF;AAElE,eAAOE,GAAaN,GAA2C;AAAA,UAC7D,GAAG5E;AAAA,UACH,OAAOiF;AAAA,QAAA,CACR;AAAA,MACH,WAAWjF,EAAM,UAAU;AAEzB,cAAM,CAACmF,GAAmBC,CAAS,IAAIN,GAAkB9E,EAAM,UAAUgF,CAAY;AACrF,eAAAA,IAAeI,GAERF,GAAaN,GAAO;AAAA,UACzB,GAAIA,EAAM;AAAA,UACV,UAAUO;AAAA,QAAA,CAC2B;AAAA,MACzC;AAAA,IACF;AAEA,WAAOP;AAAA,EACT,CAAC,GAEkBI,CAAY;AACjC,GAoFaK,KAAW,CAAC;AAAA,EACvB,WAAWC;AAAA,EACX,MAAArE,IAAO;AAAA,EACP,OAAOC;AAAA,EACP,cAAAC,IAAe;AAAA,EACf,eAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,UAAUC,IAAe;AAAA,EACzB,WAAAC,IAAY;AAAA,EACZ,cAAAgE,IAAe;AAAA,EACf,gBAAA/D,IAAiB;AAAA,EACjB,YAAAC,IAAa,CAAC,KAAK,GAAG;AAAA,EACtB,SAAAC;AAAA,EACA,WAAA8D;AAAA,EACA,aAAA7D,IAAc;AAAA,EACd,MAAMC;AAAA,EACN,WAAA7B;AAAA,EACA,UAAA0E;AAAA,EACA,GAAGgB;AACL,MAAqB;AAEnB,QAAMzE,IAAYwC,EAAQ,MAAM;AAC9B,QAAI8B,MAAkB;AACpB,aAAOA;AAGT,UAAMI,IAAiBlB,GAAWC,CAAQ;AAE1C,WAAOiB,IAAiB,IAAIA,IAAiB;AAAA,EAC/C,GAAG,CAACJ,GAAeb,CAAQ,CAAC,GAGtBU,IAAoB3B,EAAQ,MAAM;AACtC,UAAM,CAACK,CAAS,IAAIiB,GAAkBL,CAAQ;AAE9C,WAAOZ;AAAA,EACT,GAAG,CAACY,CAAQ,CAAC,GAGP;AAAA,IACJ,MAAA5C;AAAA,IACA,UAAAE;AAAA,IACA,cAAAE;AAAA,IACA,MAAAI;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,aAAAE;AAAA,IACA,cAAAU;AAAA,IACA,cAAAuC;AAAA,IACA,cAAAC;AAAA,IACA,eAAAC;AAAA,IACA,aAAAC;AAAA,IACA,aAAAC;AAAA,IACA,YAAAC;AAAA,IACA,aAAAC;AAAA,IACA,SAAAxD;AAAA,EAAA,IACE1B,GAAY;AAAA,IACd,WAAAC;AAAA,IACA,MAAAC;AAAA,IACA,OAAOC;AAAA,IACP,cAAAC;AAAA,IACA,eAAAC;AAAA,IACA,SAAAC;AAAA,IACA,cAAAC;AAAA,IACA,WAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,SAAAC;AAAA,IACA,aAAAC;AAAA,IACA,UAAAC;AAAA,EAAA,CACD,GAGKsE,IACJ,gBAAgBT,IAAUA,EAAO,YAAY,IAA2B,QACpE,EAAE,cAAchC,IAAG,GAAG0C,MAAeV,GAerCW,IAXA3D,IACK,EAAE,mBAAmBA,EAAA,IAG1ByD,IACK,EAAE,cAAcA,EAAA,IAGlB,CAAA;AAKT,SACE,gBAAA1F,EAACnB,GAAgB,UAAhB,EAAyB,OAAOsG,GAC/B,UAAA,gBAAApF;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK0B;AAAA,MACL,wBAAqB;AAAA,MACrB,MAAK;AAAA,MACJ,GAAGmE;AAAA,MACH,GAAI1D,IAAc,EAAE,oBAAoBA,EAAA,IAAgB,CAAA;AAAA,MACzD,WAAW2D;AAAA,QACT;AAAA,QACA/D,IAAW,uBAAuB;AAAA,QAClCvC;AAAA,MAAA;AAAA,MAEF,SAASkG;AAAA,MACR,GAAGE;AAAA,MAGH,UAAA;AAAA,QAAA9D,KACC,gBAAA7B;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAA6B;AAAA,YACA,OAAOe;AAAA,YACP,UAAUZ;AAAA,YACV,iBAAeA;AAAA,YACf,gBAAcD;AAAA,YACb,GAAG6D;AAAA,UAAA;AAAA,QAAA;AAAA,QAIR,gBAAA5F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKuB;AAAA,YACL,IAAIF;AAAA,YACJ,MAAMZ,MAAS,aAAa,aAAa;AAAA,YACzC,OAAOmC;AAAA,YACP,WAAApC;AAAA,YACA,WAAAO;AAAA,YACA,cAAAgE;AAAA,YACA,UAAAjD;AAAA,YACA,SAAAZ;AAAA,YACA,WAAA8D;AAAA,YACC,GAAGY;AAAA,YACH,GAAI1D,IAAc,EAAE,oBAAoBA,EAAA,IAAgB,CAAA;AAAA,YACzD,gBAAcH;AAAA,YACd,UAAUqD;AAAA,YACV,WAAWC;AAAA,YACX,SAASC;AAAA,YACT,SAASC;AAAA,YACT,QAAQC;AAAA,YACR,WAAU;AAAA,YACV,UAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAGXb;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;AAEAE,GAAS,cAAc;ACvThB,MAAMiB,IAAgB,CAAC,EAAE,UAAA7B,GAAU,WAAA1E,GAAW,GAAGC,QAEpD,gBAAAQ,EAAC,SAAI,WAAW,8CAA8CT,KAAa,EAAE,IAAK,GAAGC,GAClF,UAAAyE,EAAA,CACH;AAIJ6B,EAAc,cAAc;ACNrB,MAAMC,IAAoB,CAAC,EAAE,WAAAxG,GAAW,GAAGC,QAE9C,gBAAAQ;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAW,oDAAoDT,KAAa,EAAE;AAAA,IAC7E,GAAGC;AAAA,IAEJ,4BAACwG,IAAA,EAAK,MAAK,MACT,UAAA,gBAAAhG,EAACiG,MAAM,EAAA,CACT;AAAA,EAAA;AAAA;AAKNF,EAAkB,cAAc;ACdzB,MAAMlB,KAIT,OAAO,OAAOqB,IAAM;AAAA,EACtB,OAAOJ;AAAA,EACP,MAAMzG;AAAA,EACN,WAAW0G;AACb,CAAC;AAEDlB,GAAS,cAAc;AACvBiB,EAAc,cAAc;AAC5BzG,EAAa,cAAc;AAC3B0G,EAAkB,cAAc;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../src/input-otp/InputOTPContext.tsx","../../src/input-otp/InputOTP.styles.ts","../../src/input-otp/InputOTPSlot.tsx","../../src/input-otp/useInputOTP.ts","../../src/input-otp/InputOTP.tsx","../../src/input-otp/InputOTPGroup.tsx","../../src/input-otp/InputOTPSeparator.tsx","../../src/input-otp/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputOTPContextValue {\n value: string\n maxLength: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n activeIndex: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n disabled: boolean\n placeholder?: string\n type: 'text' | 'number' | 'password' | 'tel'\n}\n\nexport const InputOTPContext = createContext<InputOTPContextValue | null>(null)\n\nexport const useInputOTPContext = () => {\n const context = useContext(InputOTPContext)\n if (!context) {\n throw new Error('InputOTP components must be used within InputOTP')\n }\n\n return context\n}\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputOTPContainerStyles = cva(['relative', 'inline-flex', 'items-center', 'gap-sm'])\n\nexport const inputOTPSlotStyles = cva(\n [\n // Base slot styles\n 'relative',\n 'border-sm first:rounded-l-lg last:rounded-r-lg',\n 'size-sz-44',\n 'text-center text-body-1',\n 'text-on-surface',\n 'outline-hidden',\n 'transition-colors',\n 'flex items-center justify-center',\n // Active state (when focused)\n 'data-[active=true]:ring-1',\n 'data-[active=true]:ring-inset',\n 'data-[active=true]:ring-l-2',\n\n 'data-[active=true]:border-focus',\n // 'data-[active=true]:ring-focus',\n // 'data-[active=true]:border-focus',\n 'data-[active=true]:z-raised ring-focus',\n // Disabled state\n 'data-[disabled=true]:cursor-not-allowed',\n 'data-[disabled=true]:border-outline',\n 'data-[disabled=true]:bg-on-surface/dim-5',\n 'data-[disabled=true]:text-on-surface/dim-3',\n ],\n {\n variants: {\n /**\n * Color scheme of the slot\n */\n intent: {\n neutral: ['bg-surface border-outline'],\n success: ['border-success bg-success-container text-on-success-container'],\n alert: ['border-alert bg-alert-container text-on-alert-container'],\n error: ['border-error bg-error-container text-on-error-container'],\n },\n },\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputOTPSlotStylesProps = VariantProps<typeof inputOTPSlotStyles>\n\n// Keep for backward compatibility\nexport const inputOTPStyles = inputOTPSlotStyles\nexport type InputOTPStylesProps = InputOTPSlotStylesProps\n","import { ComponentPropsWithoutRef } from 'react'\n\nimport { inputOTPSlotStyles } from './InputOTP.styles'\nimport { useInputOTPContext } from './InputOTPContext'\n\nexport interface InputOTPSlotProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Index of the slot (0-based).\n * If not provided, will be automatically assigned based on position in children.\n */\n index?: number\n}\n\nexport const InputOTPSlot = ({ index: indexProp, className, ...props }: InputOTPSlotProps) => {\n const context = useInputOTPContext()\n\n // Use provided index or fallback to 0 (should not happen if auto-assignment works)\n const index = indexProp ?? 0\n const slot = context.slots[index]\n\n if (!slot) {\n return null\n }\n\n const { char, isActive, hasFakeCaret } = slot\n const isEmpty = !char\n const isPlaceholder = isEmpty && !hasFakeCaret && context.placeholder\n\n return (\n <div\n className={inputOTPSlotStyles({\n intent: context.intent,\n className,\n })}\n data-active={isActive}\n data-disabled={context.disabled}\n data-valid={context.intent !== 'error'}\n {...props}\n >\n <span className={isPlaceholder ? 'text-on-surface/dim-3' : ''}>\n {context.type === 'password' && char\n ? '•'\n : char || (!hasFakeCaret && context.placeholder ? context.placeholder : '')}\n </span>\n {hasFakeCaret && (\n <span\n className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"bg-on-surface animate-standalone-caret-blink h-sz-24 w-px\" />\n </span>\n )}\n </div>\n )\n}\n\nInputOTPSlot.displayName = 'InputOTP.Slot'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport {\n ChangeEventHandler,\n ClipboardEventHandler,\n KeyboardEventHandler,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport type { InputOTPContextValue } from './InputOTPContext'\n\nconst BACKSPACE_KEY = 'Backspace'\nconst LEFT_ARROW_KEY = 'ArrowLeft'\nconst UP_ARROW_KEY = 'ArrowUp'\nconst RIGHT_ARROW_KEY = 'ArrowRight'\nconst DOWN_ARROW_KEY = 'ArrowDown'\nconst E_KEY = 'e'\n\nexport interface UseInputOTPProps {\n maxLength: number\n type: 'text' | 'number' | 'password' | 'tel'\n value?: string\n defaultValue: string\n onValueChange?: (value: string) => void\n isValid: boolean\n disabledProp: boolean\n autoFocus: boolean\n forceUppercase: boolean\n filterKeys: string[]\n pattern?: string\n placeholder: string\n nameProp?: string\n}\n\nexport interface UseInputOTPReturn {\n uuid: string\n inputRef: React.RefObject<HTMLInputElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n name: string | undefined\n disabled: boolean\n isInvalid: boolean\n isRequired: boolean\n description: string | undefined\n maxLength: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n currentValue: string\n activeIndex: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n contextValue: InputOTPContextValue\n handleChange: ChangeEventHandler<HTMLInputElement>\n handleKeyDown: KeyboardEventHandler<HTMLInputElement>\n handlePaste: ClipboardEventHandler<HTMLInputElement>\n handleFocus: () => void\n handleBlur: () => void\n handleClick: () => void\n labelId: string | undefined\n}\n\nexport const useInputOTP = ({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n}: UseInputOTPProps): UseInputOTPReturn => {\n const uuid = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Get FormField context (optional, falls back gracefully if not present)\n const field = useFormFieldControl()\n\n // Use FormField values if available, otherwise fall back to props\n // Use FormField id when available so label htmlFor works correctly\n const id = field.id ?? uuid\n const name = nameProp ?? field.name\n const disabled = field.disabled ?? disabledProp\n const isInvalid = field.isInvalid ?? !isValid\n const isRequired = field.isRequired ?? false\n const labelId = field.labelId\n const description = field.description\n const fieldState = field.state\n\n // Determine intent based on FormField state or isValid prop\n const getIntent = (): 'neutral' | 'success' | 'alert' | 'error' => {\n // FormField state takes priority\n if (['success', 'alert', 'error'].includes(fieldState ?? '')) {\n return fieldState as 'success' | 'alert' | 'error'\n }\n\n // Fallback to isValid prop for backward compatibility\n if (isInvalid) {\n return 'error'\n }\n\n return 'neutral'\n }\n\n const intent = getIntent()\n\n // Initialize value\n const initialValue = controlledValue !== undefined ? controlledValue : defaultValue\n const processedValue = forceUppercase ? initialValue.toUpperCase() : initialValue\n\n const [internalValue, setInternalValue] = useState<string>(processedValue)\n const [isFocused, setIsFocused] = useState<boolean>(false)\n\n // Use controlled value if provided, otherwise use internal state\n const currentValue = controlledValue !== undefined ? controlledValue : internalValue\n\n // Calculate active index: last empty slot, or last slot if all are filled\n const activeIndex = Math.min(currentValue.length, maxLength - 1)\n\n // Sync cursor position with active index\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.setSelectionRange(activeIndex, activeIndex)\n }\n }, [activeIndex, currentValue.length, maxLength])\n\n // Create slots array\n const slots = useMemo(\n () =>\n Array.from({ length: maxLength }, (_, i) => ({\n char: currentValue[i] || '',\n isActive: i === activeIndex && isFocused,\n hasFakeCaret: i === activeIndex && !currentValue[i] && !disabled && isFocused,\n })),\n [maxLength, currentValue, activeIndex, isFocused, disabled]\n )\n\n // Sync controlled value with input ref\n useEffect(() => {\n if (inputRef.current && controlledValue !== undefined) {\n inputRef.current.value = controlledValue\n }\n }, [controlledValue])\n\n // Focus management\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n }\n }, [autoFocus])\n\n const processInputValue = (inputValue: string): string => {\n let processed = inputValue\n\n if (forceUppercase) {\n processed = processed.toUpperCase()\n }\n\n if (type === 'number') {\n processed = processed.replace(/[^\\d]/g, '')\n }\n\n // Filter characters using pattern if provided\n if (pattern) {\n try {\n // Convert HTML pattern (string) to RegExp\n // HTML patterns validate the entire string, but we need to test each character\n // We create a regex that tests if a single character matches the pattern\n // For example: [0-9]* becomes ^[0-9]$ to test a single digit\n // We wrap the pattern in ^...$ to ensure it matches a single character\n let regexPattern = pattern\n // If pattern doesn't start with ^, wrap it to test single character\n if (!pattern.startsWith('^')) {\n regexPattern = `^${pattern}$`\n }\n const regex = new RegExp(regexPattern)\n processed = processed\n .split('')\n .filter(currChar => {\n // Test if the character matches the pattern\n return regex.test(currChar)\n })\n .join('')\n } catch (error) {\n // If pattern is invalid, ignore it and continue with other filters\n console.error('Invalid pattern provided to InputOTP:', pattern, error)\n }\n }\n\n return processed\n }\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n const inputValue = e.target.value\n const processedValue = processInputValue(inputValue)\n\n // Limit to maxLength\n const newValue = processedValue.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n // Filter keys\n if (filterKeys.length > 0 && filterKeys.includes(e.key)) {\n e.preventDefault()\n\n return\n }\n\n switch (e.key) {\n case BACKSPACE_KEY:\n e.preventDefault()\n const currentLength = currentValue.length\n if (currentLength > 0) {\n const newValue = currentValue.slice(0, currentLength - 1)\n\n // Call onValueChange first\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.max(0, newValue.length)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n break\n\n case LEFT_ARROW_KEY:\n case RIGHT_ARROW_KEY:\n // Prevent navigation with arrow keys - focus stays on last empty slot\n e.preventDefault()\n break\n\n case UP_ARROW_KEY:\n case DOWN_ARROW_KEY:\n e.preventDefault()\n break\n\n case E_KEY:\n case 'E':\n // Prevent 'e' or 'E' in number inputs\n if (type === 'number') {\n e.preventDefault()\n }\n break\n\n default:\n break\n }\n }\n\n const handlePaste: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n e.preventDefault()\n\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText) return\n\n const processedText = processInputValue(pastedText)\n const newValue = processedText.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Move cursor to end\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleFocus = () => {\n setIsFocused(true)\n if (inputRef.current) {\n // Focus on last empty slot, or last slot if all are filled\n const cursorPosition = Math.min(currentValue.length, maxLength - 1)\n inputRef.current.setSelectionRange(cursorPosition, cursorPosition)\n }\n }\n\n const handleBlur = () => {\n setIsFocused(false)\n }\n\n const handleClick = () => {\n if (inputRef.current) {\n inputRef.current.focus()\n }\n }\n\n const contextValue: InputOTPContextValue = {\n value: currentValue,\n maxLength,\n slots,\n activeIndex,\n intent,\n disabled,\n placeholder,\n type,\n }\n\n const returnValue: UseInputOTPReturn = {\n uuid: id,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n maxLength,\n intent,\n currentValue,\n activeIndex,\n slots,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n }\n\n return returnValue\n}\n","/* eslint-disable max-lines-per-function */\nimport { cx } from 'class-variance-authority'\nimport {\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n isValidElement,\n ReactElement,\n ReactNode,\n Ref,\n useMemo,\n} from 'react'\n\nimport { InputOTPContext } from './InputOTPContext'\nimport { InputOTPSlot } from './InputOTPSlot'\nimport { useInputOTP } from './useInputOTP'\n\n/**\n * Counts the number of InputOTPSlot components in the children tree\n */\nconst countSlots = (children: ReactNode): number => {\n let count = 0\n\n Children.forEach(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { children?: ReactNode }\n // Check if it's an InputOTPSlot by checking displayName\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n count++\n } else if (props.children) {\n // Recursively count slots in nested children (e.g., inside InputOTPGroup)\n count += countSlots(props.children)\n }\n }\n })\n\n return count\n}\n\n/**\n * Recursively assigns index to InputOTPSlot components\n * Returns a tuple of [processedChildren, nextIndex]\n */\nconst assignSlotIndexes = (children: ReactNode, startIndex: number = 0): [ReactNode, number] => {\n let currentIndex = startIndex\n\n const processed = Children.map(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { index?: number; children?: ReactNode }\n // Check if it's an InputOTPSlot\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n // Only assign index if not already provided\n const slotIndex = typeof props.index === 'number' ? props.index : currentIndex++\n\n return cloneElement(child as ReactElement<{ index?: number }>, {\n ...props,\n index: slotIndex,\n })\n } else if (props.children) {\n // Recursively process nested children\n const [processedChildren, nextIndex] = assignSlotIndexes(props.children, currentIndex)\n currentIndex = nextIndex\n\n return cloneElement(child, {\n ...(child.props as Record<string, unknown>),\n children: processedChildren,\n } as Parameters<typeof cloneElement>[1])\n }\n }\n\n return child\n })\n\n return [processed, currentIndex]\n}\n\nexport interface InputOTPProps\n extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'inputMode'> {\n /**\n * Maximum length of the input value.\n * If not provided, will be automatically detected from the number of InputOTP.Slot children.\n */\n maxLength?: number\n /**\n * Type of input\n * @default 'text'\n */\n type?: 'text' | 'number' | 'password' | 'tel'\n /**\n * Current value (controlled mode)\n */\n value?: string\n /**\n * Default value (uncontrolled mode)\n */\n defaultValue?: string\n /**\n * Callback fired when the value changes\n */\n onValueChange?: (value: string) => void\n /**\n * Whether the input is valid\n * @default true\n */\n isValid?: boolean\n /**\n * Whether the input is disabled\n * @default false\n */\n disabled?: boolean\n /**\n * Whether to auto-focus the input\n * @default false\n */\n autoFocus?: boolean\n /**\n * Auto-complete attribute\n * @default 'off'\n */\n autoComplete?: string\n /**\n * Whether to force uppercase\n * @default false\n */\n forceUppercase?: boolean\n /**\n * Array of keys to filter out (using KeyboardEvent.key values)\n * @default ['-', '.']\n */\n filterKeys?: string[]\n /**\n * Pattern attribute for input validation and character filtering.\n * Uses a regular expression to filter allowed characters in real-time.\n * For example: \"[0-9]\" for digits only, \"[a-c]\" for letters a, b, c only.\n */\n pattern?: string\n /**\n * Input mode attribute\n */\n inputMode?: string\n /**\n * Placeholder text\n */\n placeholder?: string\n /**\n * Name attribute for form integration\n */\n name?: string\n /**\n * Children components (InputOTPGroup, InputOTPSlot, InputOTPSeparator)\n */\n children: ReactNode\n /**\n * Ref callback for the container\n */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputOTP = ({\n maxLength: maxLengthProp,\n type = 'text',\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n isValid = true,\n disabled: disabledProp = false,\n autoFocus = false,\n autoComplete = 'off',\n forceUppercase = false,\n filterKeys = ['-', '.'],\n pattern,\n inputMode,\n placeholder = '',\n name: nameProp,\n className,\n children,\n ...others\n}: InputOTPProps) => {\n // Auto-detect maxLength from children if not provided\n const maxLength = useMemo(() => {\n if (maxLengthProp !== undefined) {\n return maxLengthProp\n }\n\n const detectedLength = countSlots(children)\n const DEFAULT_MAX_LENGTH = 4\n\n return detectedLength > 0 ? detectedLength : DEFAULT_MAX_LENGTH // fallback to 4 if no slots found\n }, [maxLengthProp, children])\n\n // Assign indexes to slots automatically\n const processedChildren = useMemo(() => {\n const [processed] = assignSlotIndexes(children)\n\n return processed\n }, [children])\n\n // Use the hook for all business logic\n const {\n uuid,\n inputRef,\n containerRef,\n name,\n disabled,\n isInvalid,\n isRequired,\n description,\n currentValue,\n contextValue,\n handleChange,\n handleKeyDown,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n } = useInputOTP({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n })\n\n // Extract aria-label from others if provided (for cases without FormField)\n const ariaLabel =\n 'aria-label' in others ? (others['aria-label'] as string | undefined) : undefined\n const { 'aria-label': _, ...restOthers } = others\n\n const getAccessibleNameProps = (): Record<string, string | undefined> => {\n if (labelId) {\n return { 'aria-labelledby': labelId }\n }\n\n if (ariaLabel) {\n return { 'aria-label': ariaLabel }\n }\n\n return {}\n }\n\n const accessibleNameProps = getAccessibleNameProps()\n\n return (\n <InputOTPContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n data-spark-component=\"input-otp\"\n role=\"group\"\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n className={cx(\n 'gap-md relative inline-flex items-center',\n disabled ? 'cursor-not-allowed' : 'cursor-text',\n className\n )}\n onClick={handleClick}\n {...restOthers}\n >\n {/* Hidden input for form submission with complete value */}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValue}\n required={isRequired}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n {...accessibleNameProps}\n />\n )}\n {/* Actual input that handles all interactions */}\n <input\n ref={inputRef}\n id={uuid}\n type={type === 'password' ? 'password' : 'text'}\n value={currentValue}\n maxLength={maxLength}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n disabled={disabled}\n pattern={pattern}\n inputMode={inputMode as React.InputHTMLAttributes<HTMLInputElement>['inputMode']}\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 disabled:cursor-not-allowed\"\n tabIndex={0}\n />\n {/* Children render slots with auto-assigned indexes */}\n {processedChildren}\n </div>\n </InputOTPContext.Provider>\n )\n}\n\nInputOTP.displayName = 'InputOTP'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPGroupProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPGroup = ({ children, className, ...props }: InputOTPGroupProps) => {\n return (\n <div className={`inline-flex [&>*:not(:first-child)]:-ml-px ${className || ''}`} {...props}>\n {children}\n </div>\n )\n}\n\nInputOTPGroup.displayName = 'InputOTP.Group'\n","import { Icon } from '@spark-ui/components/icon'\nimport { Minus } from '@spark-ui/icons/Minus'\nimport { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPSeparatorProps extends ComponentPropsWithoutRef<'div'> {}\n\nexport const InputOTPSeparator = ({ className, ...props }: InputOTPSeparatorProps) => {\n return (\n <div\n className={`text-on-surface flex items-center justify-center ${className || ''}`}\n {...props}\n >\n <Icon size=\"md\">\n <Minus />\n </Icon>\n </div>\n )\n}\n\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n","import { InputOTP as Root } from './InputOTP'\nimport { InputOTPGroup } from './InputOTPGroup'\nimport { InputOTPSeparator } from './InputOTPSeparator'\nimport { InputOTPSlot } from './InputOTPSlot'\n\nexport const InputOTP: typeof Root & {\n Group: typeof InputOTPGroup\n Slot: typeof InputOTPSlot\n Separator: typeof InputOTPSeparator\n} = Object.assign(Root, {\n Group: InputOTPGroup,\n Slot: InputOTPSlot,\n Separator: InputOTPSeparator,\n})\n\nInputOTP.displayName = 'InputOTP'\nInputOTPGroup.displayName = 'InputOTP.Group'\nInputOTPSlot.displayName = 'InputOTP.Slot'\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n\nexport { type InputOTPProps } from './InputOTP'\nexport { type InputOTPGroupProps } from './InputOTPGroup'\nexport { type InputOTPSlotProps } from './InputOTPSlot'\nexport { type InputOTPSeparatorProps } from './InputOTPSeparator'\nexport {\n inputOTPSlotStyles,\n inputOTPStyles,\n type InputOTPSlotStylesProps,\n type InputOTPStylesProps,\n} from './InputOTP.styles'\n"],"names":["InputOTPContext","createContext","useInputOTPContext","context","useContext","inputOTPSlotStyles","cva","inputOTPStyles","InputOTPSlot","indexProp","className","props","index","slot","char","isActive","hasFakeCaret","isPlaceholder","jsxs","jsx","BACKSPACE_KEY","LEFT_ARROW_KEY","UP_ARROW_KEY","RIGHT_ARROW_KEY","DOWN_ARROW_KEY","E_KEY","useInputOTP","maxLength","type","controlledValue","defaultValue","onValueChange","isValid","disabledProp","autoFocus","forceUppercase","filterKeys","pattern","placeholder","nameProp","uuid","useId","inputRef","useRef","containerRef","field","useFormFieldControl","id","name","disabled","isInvalid","isRequired","labelId","description","fieldState","intent","initialValue","processedValue","internalValue","setInternalValue","useState","isFocused","setIsFocused","currentValue","activeIndex","useEffect","slots","useMemo","_","i","processInputValue","inputValue","processed","regexPattern","regex","currChar","error","e","newValue","newActiveIndex","currentLength","pastedText","cursorPosition","countSlots","children","count","Children","child","isValidElement","assignSlotIndexes","startIndex","currentIndex","slotIndex","cloneElement","processedChildren","nextIndex","InputOTP","maxLengthProp","autoComplete","inputMode","others","detectedLength","contextValue","handleChange","handleKeyDown","handlePaste","handleFocus","handleBlur","handleClick","ariaLabel","restOthers","accessibleNameProps","cx","InputOTPGroup","InputOTPSeparator","Icon","Minus","Root"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spark-ui/components",
3
- "version": "13.1.0",
3
+ "version": "13.1.2",
4
4
  "license": "MIT",
5
5
  "description": "Spark (Leboncoin design system) components.",
6
6
  "exports": {
@@ -53,9 +53,9 @@
53
53
  "@react-aria/toast": "^3.0.0-beta.18",
54
54
  "@react-stately/numberfield": "3.9.11",
55
55
  "@react-stately/toast": "^3.0.0-beta.7",
56
- "@spark-ui/hooks": "^13.1.0",
57
- "@spark-ui/icons": "^13.1.0",
58
- "@spark-ui/internal-utils": "^13.1.0",
56
+ "@spark-ui/hooks": "^13.1.2",
57
+ "@spark-ui/icons": "^13.1.2",
58
+ "@spark-ui/internal-utils": "^13.1.2",
59
59
  "@zag-js/pagination": "1.31.1",
60
60
  "@zag-js/react": "1.31.1",
61
61
  "class-variance-authority": "0.7.1",
@@ -81,6 +81,5 @@
81
81
  "bugs": {
82
82
  "url": "https://github.com/leboncoin/spark-web/issues?q=is%3Aopen+label%3A%22Component%3A+button%22"
83
83
  },
84
- "homepage": "https://sparkui.vercel.app",
85
- "gitHead": "999f63f5c614cc8abc9c29d88f52fe97cc93d6f3"
84
+ "homepage": "https://sparkui.vercel.app"
86
85
  }