@nori-ui/core 1.7.0 → 1.9.0

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.
Files changed (63) hide show
  1. package/dist/chunk-BOMPFNM4.js +165 -0
  2. package/dist/chunk-BOMPFNM4.js.map +1 -0
  3. package/dist/chunk-BVLOX4A3.js +256 -0
  4. package/dist/chunk-BVLOX4A3.js.map +1 -0
  5. package/dist/{chunk-PLQPBMG2.js → chunk-BXZGCOKT.js} +2 -2
  6. package/dist/{chunk-PLQPBMG2.js.map → chunk-BXZGCOKT.js.map} +1 -1
  7. package/dist/{chunk-RI4Y2C5U.js → chunk-KLK7OMFT.js} +3 -3
  8. package/dist/{chunk-RI4Y2C5U.js.map → chunk-KLK7OMFT.js.map} +1 -1
  9. package/dist/chunk-OHWRTHGL.js +495 -0
  10. package/dist/chunk-OHWRTHGL.js.map +1 -0
  11. package/dist/{chunk-V5QSMDZL.js → chunk-QB6RH6UU.js} +3 -3
  12. package/dist/{chunk-V5QSMDZL.js.map → chunk-QB6RH6UU.js.map} +1 -1
  13. package/dist/chunk-S763GTIZ.js +350 -0
  14. package/dist/chunk-S763GTIZ.js.map +1 -0
  15. package/dist/chunk-UJRVWGK7.js +3 -0
  16. package/dist/chunk-UJRVWGK7.js.map +1 -0
  17. package/dist/chunk-VFUV6XJR.js +257 -0
  18. package/dist/chunk-VFUV6XJR.js.map +1 -0
  19. package/dist/client.cjs +2860 -1386
  20. package/dist/client.cjs.map +1 -1
  21. package/dist/client.d.cts +5 -0
  22. package/dist/client.d.ts +5 -0
  23. package/dist/client.js +23 -17
  24. package/dist/client.js.map +1 -1
  25. package/dist/components/Accordion/index.js +2 -2
  26. package/dist/components/Carousel/index.cjs +297 -0
  27. package/dist/components/Carousel/index.cjs.map +1 -0
  28. package/dist/components/Carousel/index.d.cts +67 -0
  29. package/dist/components/Carousel/index.d.ts +67 -0
  30. package/dist/components/Carousel/index.js +5 -0
  31. package/dist/components/Carousel/index.js.map +1 -0
  32. package/dist/components/Command/index.cjs +1371 -0
  33. package/dist/components/Command/index.cjs.map +1 -0
  34. package/dist/components/Command/index.d.cts +89 -0
  35. package/dist/components/Command/index.d.ts +89 -0
  36. package/dist/components/Command/index.js +11 -0
  37. package/dist/components/Command/index.js.map +1 -0
  38. package/dist/components/Dialog/index.js +2 -1
  39. package/dist/components/HoverCard/index.cjs +894 -0
  40. package/dist/components/HoverCard/index.cjs.map +1 -0
  41. package/dist/components/HoverCard/index.d.cts +66 -0
  42. package/dist/components/HoverCard/index.d.ts +66 -0
  43. package/dist/components/HoverCard/index.js +9 -0
  44. package/dist/components/HoverCard/index.js.map +1 -0
  45. package/dist/components/InputOTP/index.cjs +580 -0
  46. package/dist/components/InputOTP/index.cjs.map +1 -0
  47. package/dist/components/InputOTP/index.d.cts +49 -0
  48. package/dist/components/InputOTP/index.d.ts +49 -0
  49. package/dist/components/InputOTP/index.js +7 -0
  50. package/dist/components/InputOTP/index.js.map +1 -0
  51. package/dist/components/Sidebar/index.cjs +675 -0
  52. package/dist/components/Sidebar/index.cjs.map +1 -0
  53. package/dist/components/Sidebar/index.d.cts +109 -0
  54. package/dist/components/Sidebar/index.d.ts +109 -0
  55. package/dist/components/Sidebar/index.js +7 -0
  56. package/dist/components/Sidebar/index.js.map +1 -0
  57. package/dist/components/Switch/index.js +2 -2
  58. package/dist/index.cjs +2860 -1386
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.d.cts +5 -0
  61. package/dist/index.d.ts +5 -0
  62. package/dist/index.js +23 -17
  63. package/package.json +1 -1
@@ -0,0 +1,165 @@
1
+ import { Popover } from './chunk-HXCETKCC.js';
2
+ import { Slot } from './chunk-ZIBNLXIV.js';
3
+ import { __name } from './chunk-WCQVDF3K.js';
4
+ import { createContext, useContext, useState, useId, useCallback, useRef, useEffect, isValidElement } from 'react';
5
+ import { jsx } from 'nativewind/jsx-runtime';
6
+
7
+ var HoverCardContext = createContext(null);
8
+ function useHoverCardContext(caller) {
9
+ const ctx = useContext(HoverCardContext);
10
+ if (!ctx) {
11
+ throw new Error(`<${caller}> must be rendered inside <HoverCard>.`);
12
+ }
13
+ return ctx;
14
+ }
15
+ __name(useHoverCardContext, "useHoverCardContext");
16
+ var DEFAULT_OPEN_DELAY = 300;
17
+ var DEFAULT_CLOSE_DELAY = 200;
18
+ var HoverCardRoot = /* @__PURE__ */ __name(({
19
+ open: controlledOpen,
20
+ defaultOpen = false,
21
+ onOpenChange,
22
+ openDelay = DEFAULT_OPEN_DELAY,
23
+ closeDelay = DEFAULT_CLOSE_DELAY,
24
+ children
25
+ }) => {
26
+ const [inner, setInner] = useState(defaultOpen);
27
+ const isControlled = controlledOpen !== void 0;
28
+ const open = isControlled ? controlledOpen : inner;
29
+ const id = useId();
30
+ const setOpen = useCallback(
31
+ (next) => {
32
+ if (!isControlled) {
33
+ setInner(next);
34
+ }
35
+ onOpenChange?.(next);
36
+ },
37
+ [isControlled, onOpenChange]
38
+ );
39
+ const openTimer = useRef(null);
40
+ const closeTimer = useRef(null);
41
+ const cancelTimers = useCallback(() => {
42
+ if (openTimer.current) {
43
+ clearTimeout(openTimer.current);
44
+ openTimer.current = null;
45
+ }
46
+ if (closeTimer.current) {
47
+ clearTimeout(closeTimer.current);
48
+ closeTimer.current = null;
49
+ }
50
+ }, []);
51
+ const requestOpen = useCallback(() => {
52
+ if (closeTimer.current) {
53
+ clearTimeout(closeTimer.current);
54
+ closeTimer.current = null;
55
+ }
56
+ if (openTimer.current) {
57
+ return;
58
+ }
59
+ if (openDelay <= 0) {
60
+ setOpen(true);
61
+ return;
62
+ }
63
+ openTimer.current = setTimeout(() => {
64
+ openTimer.current = null;
65
+ setOpen(true);
66
+ }, openDelay);
67
+ }, [openDelay, setOpen]);
68
+ const requestClose = useCallback(() => {
69
+ if (openTimer.current) {
70
+ clearTimeout(openTimer.current);
71
+ openTimer.current = null;
72
+ }
73
+ if (closeTimer.current) {
74
+ return;
75
+ }
76
+ if (closeDelay <= 0) {
77
+ setOpen(false);
78
+ return;
79
+ }
80
+ closeTimer.current = setTimeout(() => {
81
+ closeTimer.current = null;
82
+ setOpen(false);
83
+ }, closeDelay);
84
+ }, [closeDelay, setOpen]);
85
+ useEffect(() => () => cancelTimers(), [cancelTimers]);
86
+ return /* @__PURE__ */ jsx(
87
+ HoverCardContext.Provider,
88
+ {
89
+ value: { open, requestOpen, requestClose, cancelTimers, contentId: `hc-content-${id}` },
90
+ children: /* @__PURE__ */ jsx(Popover, { open, onOpenChange: setOpen, children })
91
+ }
92
+ );
93
+ }, "HoverCardRoot");
94
+ var HoverCardTrigger = /* @__PURE__ */ __name(({ asChild = true, children, className, testID }) => {
95
+ const ctx = useHoverCardContext("HoverCard.Trigger");
96
+ const handleMouseEnter = useCallback(() => {
97
+ ctx.cancelTimers();
98
+ ctx.requestOpen();
99
+ }, [ctx]);
100
+ const handleMouseLeave = useCallback(() => {
101
+ ctx.requestClose();
102
+ }, [ctx]);
103
+ const handlers = {
104
+ onMouseEnter: handleMouseEnter,
105
+ onMouseLeave: handleMouseLeave,
106
+ "aria-haspopup": "dialog",
107
+ "aria-expanded": ctx.open
108
+ };
109
+ if (asChild && isValidElement(children)) {
110
+ const child = children;
111
+ const compose = /* @__PURE__ */ __name((existing, next) => (event) => {
112
+ existing?.(event);
113
+ next(event);
114
+ }, "compose");
115
+ return /* @__PURE__ */ jsx(
116
+ Slot,
117
+ {
118
+ ...handlers,
119
+ onMouseEnter: compose(child.props.onMouseEnter, handleMouseEnter),
120
+ onMouseLeave: compose(child.props.onMouseLeave, handleMouseLeave),
121
+ ...className !== void 0 ? { className } : {},
122
+ ...testID !== void 0 ? { "data-testid": testID } : {},
123
+ children: child
124
+ }
125
+ );
126
+ }
127
+ return /* @__PURE__ */ jsx("span", { ...handlers, className, ...testID !== void 0 ? { "data-testid": testID } : {}, children });
128
+ }, "HoverCardTrigger");
129
+ var HoverCardContent = /* @__PURE__ */ __name(({ side = "bottom", align = "start", children, className, testID }) => {
130
+ const ctx = useHoverCardContext("HoverCard.Content");
131
+ const handleMouseEnter = useCallback(() => {
132
+ ctx.cancelTimers();
133
+ }, [ctx]);
134
+ const handleMouseLeave = useCallback(() => {
135
+ ctx.requestClose();
136
+ }, [ctx]);
137
+ return /* @__PURE__ */ jsx(
138
+ Popover.Content,
139
+ {
140
+ side,
141
+ align,
142
+ ...className !== void 0 ? { className } : {},
143
+ ...testID !== void 0 ? { testID } : {},
144
+ children: /* @__PURE__ */ jsx(
145
+ "div",
146
+ {
147
+ id: ctx.contentId,
148
+ role: "dialog",
149
+ "aria-label": "Hover card",
150
+ onMouseEnter: handleMouseEnter,
151
+ onMouseLeave: handleMouseLeave,
152
+ children
153
+ }
154
+ )
155
+ }
156
+ );
157
+ }, "HoverCardContent");
158
+ var HoverCard = Object.assign(HoverCardRoot, {
159
+ Trigger: HoverCardTrigger,
160
+ Content: HoverCardContent
161
+ });
162
+
163
+ export { HoverCard };
164
+ //# sourceMappingURL=chunk-BOMPFNM4.js.map
165
+ //# sourceMappingURL=chunk-BOMPFNM4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/HoverCard/HoverCard.web.tsx"],"names":[],"mappings":";;;;;;AA8BA,IAAM,gBAAA,GAAmB,cAA4C,IAAI,CAAA;AAEzE,SAAS,oBAAoB,MAAA,EAAuC;AAChE,EAAA,MAAM,GAAA,GAAM,WAAW,gBAAgB,CAAA;AACvC,EAAA,IAAI,CAAC,GAAA,EAAK;AACN,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,CAAA,EAAI,MAAM,CAAA,sCAAA,CAAwC,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,GAAA;AACX;AANS,MAAA,CAAA,mBAAA,EAAA,qBAAA,CAAA;AAYT,IAAM,kBAAA,GAAqB,GAAA;AAC3B,IAAM,mBAAA,GAAsB,GAAA;AAsB5B,IAAM,gCAAgB,MAAA,CAAA,CAAC;AAAA,EACnB,IAAA,EAAM,cAAA;AAAA,EACN,WAAA,GAAc,KAAA;AAAA,EACd,YAAA;AAAA,EACA,SAAA,GAAY,kBAAA;AAAA,EACZ,UAAA,GAAa,mBAAA;AAAA,EACb;AACJ,CAAA,KAAsB;AAClB,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,WAAW,CAAA;AAC9C,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,IAAA,GAAO,eAAgB,cAAA,GAA6B,KAAA;AAC1D,EAAA,MAAM,KAAK,KAAA,EAAM;AAEjB,EAAA,MAAM,OAAA,GAAU,WAAA;AAAA,IACZ,CAAC,IAAA,KAAkB;AACf,MAAA,IAAI,CAAC,YAAA,EAAc;AACf,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACjB;AACA,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACvB,CAAA;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,GAC/B;AAEA,EAAA,MAAM,SAAA,GAAY,OAA6C,IAAI,CAAA;AACnE,EAAA,MAAM,UAAA,GAAa,OAA6C,IAAI,CAAA;AAEpE,EAAA,MAAM,YAAA,GAAe,YAAY,MAAM;AACnC,IAAA,IAAI,UAAU,OAAA,EAAS;AACnB,MAAA,YAAA,CAAa,UAAU,OAAO,CAAA;AAC9B,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACxB;AACA,IAAA,IAAI,WAAW,OAAA,EAAS;AACpB,MAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACzB;AAAA,EACJ,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,WAAA,GAAc,YAAY,MAAM;AAClC,IAAA,IAAI,WAAW,OAAA,EAAS;AACpB,MAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACzB;AACA,IAAA,IAAI,UAAU,OAAA,EAAS;AACnB,MAAA;AAAA,IACJ;AACA,IAAA,IAAI,aAAa,CAAA,EAAG;AAChB,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA;AAAA,IACJ;AACA,IAAA,SAAA,CAAU,OAAA,GAAU,WAAW,MAAM;AACjC,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IAChB,GAAG,SAAS,CAAA;AAAA,EAChB,CAAA,EAAG,CAAC,SAAA,EAAW,OAAO,CAAC,CAAA;AAEvB,EAAA,MAAM,YAAA,GAAe,YAAY,MAAM;AACnC,IAAA,IAAI,UAAU,OAAA,EAAS;AACnB,MAAA,YAAA,CAAa,UAAU,OAAO,CAAA;AAC9B,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACxB;AACA,IAAA,IAAI,WAAW,OAAA,EAAS;AACpB,MAAA;AAAA,IACJ;AACA,IAAA,IAAI,cAAc,CAAA,EAAG;AACjB,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA;AAAA,IACJ;AACA,IAAA,UAAA,CAAW,OAAA,GAAU,WAAW,MAAM;AAClC,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACjB,GAAG,UAAU,CAAA;AAAA,EACjB,CAAA,EAAG,CAAC,UAAA,EAAY,OAAO,CAAC,CAAA;AAExB,EAAA,SAAA,CAAU,MAAM,MAAM,YAAA,EAAa,EAAG,CAAC,YAAY,CAAC,CAAA;AAEpD,EAAA,uBACI,GAAA;AAAA,IAAC,gBAAA,CAAiB,QAAA;AAAA,IAAjB;AAAA,MACG,KAAA,EAAO,EAAE,IAAA,EAAM,WAAA,EAAa,cAAc,YAAA,EAAc,SAAA,EAAW,CAAA,WAAA,EAAc,EAAE,CAAA,CAAA,EAAG;AAAA,MAEtF,QAAA,kBAAA,GAAA,CAAC,OAAA,EAAA,EAAQ,IAAA,EAAY,YAAA,EAAc,SAC9B,QAAA,EACL;AAAA;AAAA,GACJ;AAER,CAAA,EApFsB,eAAA,CAAA;AAkGtB,IAAM,gBAAA,2BAAoB,EAAE,OAAA,GAAU,MAAM,QAAA,EAAU,SAAA,EAAW,QAAO,KAA6B;AACjG,EAAA,MAAM,GAAA,GAAM,oBAAoB,mBAAmB,CAAA;AAEnD,EAAA,MAAM,gBAAA,GAAmB,YAAY,MAAM;AACvC,IAAA,GAAA,CAAI,YAAA,EAAa;AACjB,IAAA,GAAA,CAAI,WAAA,EAAY;AAAA,EACpB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,gBAAA,GAAmB,YAAY,MAAM;AACvC,IAAA,GAAA,CAAI,YAAA,EAAa;AAAA,EACrB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,QAAA,GAAW;AAAA,IACb,YAAA,EAAc,gBAAA;AAAA,IACd,YAAA,EAAc,gBAAA;AAAA,IACd,eAAA,EAAiB,QAAA;AAAA,IACjB,iBAAiB,GAAA,CAAI;AAAA,GACzB;AAEA,EAAA,IAAI,OAAA,IAAW,cAAA,CAAe,QAAQ,CAAA,EAAG;AACrC,IAAA,MAAM,KAAA,GAAQ,QAAA;AACd,IAAA,MAAM,OAAA,mBACF,MAAA,CAAA,CAAK,QAAA,EAAwC,IAAA,KAC7C,CAAC,KAAA,KAAa;AACV,MAAA,QAAA,GAAW,KAAK,CAAA;AAChB,MAAA,IAAA,CAAK,KAAK,CAAA;AAAA,IACd,CAAA,EAJA,SAAA,CAAA;AAKJ,IAAA,uBACI,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACI,GAAG,QAAA;AAAA,QACJ,YAAA,EAAc,OAAA,CAAQ,KAAA,CAAM,KAAA,CAAM,cAAoD,gBAAgB,CAAA;AAAA,QACtG,YAAA,EAAc,OAAA,CAAQ,KAAA,CAAM,KAAA,CAAM,cAAoD,gBAAgB,CAAA;AAAA,QACrG,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,QAC/C,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,aAAA,EAAe,MAAA,KAAW,EAAC;AAAA,QAExD,QAAA,EAAA;AAAA;AAAA,KACL;AAAA,EAER;AAEA,EAAA,uBACI,GAAA,CAAC,MAAA,EAAA,EAAM,GAAG,QAAA,EAAU,WAAuB,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,aAAA,EAAe,MAAA,EAAO,GAAI,IAC7F,QAAA,EACL,CAAA;AAER,CAAA,EA7CyB,kBAAA,CAAA;AA6DzB,IAAM,gBAAA,mBAAmB,MAAA,CAAA,CAAC,EAAE,IAAA,GAAO,QAAA,EAAU,QAAQ,OAAA,EAAS,QAAA,EAAU,SAAA,EAAW,MAAA,EAAO,KAA6B;AACnH,EAAA,MAAM,GAAA,GAAM,oBAAoB,mBAAmB,CAAA;AAGnD,EAAA,MAAM,gBAAA,GAAmB,YAAY,MAAM;AACvC,IAAA,GAAA,CAAI,YAAA,EAAa;AAAA,EACrB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,MAAM,gBAAA,GAAmB,YAAY,MAAM;AACvC,IAAA,GAAA,CAAI,YAAA,EAAa;AAAA,EACrB,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAER,EAAA,uBACI,GAAA;AAAA,IAAC,OAAA,CAAQ,OAAA;AAAA,IAAR;AAAA,MACG,IAAA;AAAA,MACA,KAAA;AAAA,MACC,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,MAC/C,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,MAI1C,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACG,IAAI,GAAA,CAAI,SAAA;AAAA,UACR,IAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAW,YAAA;AAAA,UACX,YAAA,EAAc,gBAAA;AAAA,UACd,YAAA,EAAc,gBAAA;AAAA,UAEb;AAAA;AAAA;AACL;AAAA,GACJ;AAER,CAAA,EAhCyB,kBAAA,CAAA;AA2DlB,IAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,aAAA,EAAe;AAAA,EAClD,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS;AACb,CAAC","file":"chunk-BOMPFNM4.js","sourcesContent":["'use client';\n\nimport {\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { Slot } from '../../slot';\nimport type { PopoverAlign, PopoverSide } from '../Popover/Popover';\nimport { Popover } from '../Popover/Popover';\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ntype HoverCardContextValue = {\n open: boolean;\n requestOpen: () => void;\n requestClose: () => void;\n cancelTimers: () => void;\n contentId: string;\n};\n\nconst HoverCardContext = createContext<HoverCardContextValue | null>(null);\n\nfunction useHoverCardContext(caller: string): HoverCardContextValue {\n const ctx = useContext(HoverCardContext);\n if (!ctx) {\n throw new Error(`<${caller}> must be rendered inside <HoverCard>.`);\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_OPEN_DELAY = 300;\nconst DEFAULT_CLOSE_DELAY = 200;\n\nexport type HoverCardProps = {\n /** Controlled open state. */\n open?: boolean;\n /** Uncontrolled initial open state. @defaultValue false */\n defaultOpen?: boolean;\n /** Fires with the new open state. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Milliseconds before the card opens after hover-in.\n * @defaultValue 300\n */\n openDelay?: number;\n /**\n * Milliseconds before the card closes after hover-out.\n * @defaultValue 200\n */\n closeDelay?: number;\n children?: ReactNode;\n};\n\nconst HoverCardRoot = ({\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n openDelay = DEFAULT_OPEN_DELAY,\n closeDelay = DEFAULT_CLOSE_DELAY,\n children,\n}: HoverCardProps) => {\n const [inner, setInner] = useState(defaultOpen);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? (controlledOpen as boolean) : inner;\n const id = useId();\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) {\n setInner(next);\n }\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const openTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const cancelTimers = useCallback(() => {\n if (openTimer.current) {\n clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n }, []);\n\n const requestOpen = useCallback(() => {\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n if (openTimer.current) {\n return;\n }\n if (openDelay <= 0) {\n setOpen(true);\n return;\n }\n openTimer.current = setTimeout(() => {\n openTimer.current = null;\n setOpen(true);\n }, openDelay);\n }, [openDelay, setOpen]);\n\n const requestClose = useCallback(() => {\n if (openTimer.current) {\n clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n if (closeTimer.current) {\n return;\n }\n if (closeDelay <= 0) {\n setOpen(false);\n return;\n }\n closeTimer.current = setTimeout(() => {\n closeTimer.current = null;\n setOpen(false);\n }, closeDelay);\n }, [closeDelay, setOpen]);\n\n useEffect(() => () => cancelTimers(), [cancelTimers]);\n\n return (\n <HoverCardContext.Provider\n value={{ open, requestOpen, requestClose, cancelTimers, contentId: `hc-content-${id}` }}\n >\n <Popover open={open} onOpenChange={setOpen}>\n {children}\n </Popover>\n </HoverCardContext.Provider>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Trigger\n// ---------------------------------------------------------------------------\n\nexport type HoverCardTriggerProps = {\n /** Use the child element as the trigger instead of wrapping it. @defaultValue true */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\nconst HoverCardTrigger = ({ asChild = true, children, className, testID }: HoverCardTriggerProps) => {\n const ctx = useHoverCardContext('HoverCard.Trigger');\n\n const handleMouseEnter = useCallback(() => {\n ctx.cancelTimers();\n ctx.requestOpen();\n }, [ctx]);\n\n const handleMouseLeave = useCallback(() => {\n ctx.requestClose();\n }, [ctx]);\n\n const handlers = {\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n 'aria-haspopup': 'dialog' as const,\n 'aria-expanded': ctx.open,\n };\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<Record<string, unknown>>;\n const compose =\n <T,>(existing: ((e: T) => void) | undefined, next: (e: T) => void) =>\n (event: T) => {\n existing?.(event);\n next(event);\n };\n return (\n <Slot\n {...handlers}\n onMouseEnter={compose(child.props.onMouseEnter as ((e: unknown) => void) | undefined, handleMouseEnter)}\n onMouseLeave={compose(child.props.onMouseLeave as ((e: unknown) => void) | undefined, handleMouseLeave)}\n {...(className !== undefined ? { className } : {})}\n {...(testID !== undefined ? { 'data-testid': testID } : {})}\n >\n {child}\n </Slot>\n );\n }\n\n return (\n <span {...handlers} className={className} {...(testID !== undefined ? { 'data-testid': testID } : {})}>\n {children}\n </span>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Content\n// ---------------------------------------------------------------------------\n\nexport type HoverCardContentProps = {\n /** Which side of the trigger to render on. @defaultValue 'bottom' */\n side?: PopoverSide;\n /** Alignment along the trigger edge. @defaultValue 'start' */\n align?: PopoverAlign;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\nconst HoverCardContent = ({ side = 'bottom', align = 'start', children, className, testID }: HoverCardContentProps) => {\n const ctx = useHoverCardContext('HoverCard.Content');\n\n // Keep hover card open while hovering over content itself\n const handleMouseEnter = useCallback(() => {\n ctx.cancelTimers();\n }, [ctx]);\n\n const handleMouseLeave = useCallback(() => {\n ctx.requestClose();\n }, [ctx]);\n\n return (\n <Popover.Content\n side={side}\n align={align}\n {...(className !== undefined ? { className } : {})}\n {...(testID !== undefined ? { testID } : {})}\n >\n {/* Intercept mouse events on the content surface so hovering\n over it cancels the close timer. */}\n <div\n id={ctx.contentId}\n role=\"dialog\"\n aria-label=\"Hover card\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {children}\n </div>\n </Popover.Content>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public compound export\n// ---------------------------------------------------------------------------\n\n/**\n * Hover-triggered popover card. Web only.\n *\n * On native, `HoverCard.Content` is omitted — only the trigger renders.\n * See `HoverCard.native.tsx`.\n *\n * Composition:\n * - `HoverCard.Trigger` — wraps any element; hover opens the card.\n * - `HoverCard.Content` — the floating card surface.\n *\n * ```tsx\n * <HoverCard>\n * <HoverCard.Trigger>\n * <Avatar src=\"...\" />\n * </HoverCard.Trigger>\n * <HoverCard.Content>\n * <Text>@manuelbieh — Senior dev at Wiremore</Text>\n * </HoverCard.Content>\n * </HoverCard>\n * ```\n */\nexport const HoverCard = Object.assign(HoverCardRoot, {\n Trigger: HoverCardTrigger,\n Content: HoverCardContent,\n});\n"]}
@@ -0,0 +1,256 @@
1
+ import { px } from './chunk-5A2QOOVN.js';
2
+ import { useThemeColors } from './chunk-R5JMDDCB.js';
3
+ import { cn } from './chunk-CHXHRJNZ.js';
4
+ import { __name } from './chunk-WCQVDF3K.js';
5
+ import { useState, useRef, useEffect, useCallback } from 'react';
6
+ import { StyleSheet, Platform, View, TextInput } from 'react-native';
7
+ import { jsxs, jsx } from 'nativewind/jsx-runtime';
8
+
9
+ function isAllowed(char, pattern) {
10
+ if (pattern === "numeric") {
11
+ return /^\d$/.test(char);
12
+ }
13
+ return /^[a-zA-Z0-9]$/.test(char);
14
+ }
15
+ __name(isAllowed, "isAllowed");
16
+ function filterValue(value, pattern, length) {
17
+ return value.split("").filter((c) => isAllowed(c, pattern)).slice(0, length).join("");
18
+ }
19
+ __name(filterValue, "filterValue");
20
+ var InputOTP = /* @__PURE__ */ __name(({
21
+ value = "",
22
+ onChange,
23
+ onComplete,
24
+ length = 6,
25
+ placeholder = "\xB7",
26
+ pattern = "numeric",
27
+ disabled = false,
28
+ autoFocus = false,
29
+ id,
30
+ name,
31
+ "aria-label": ariaLabel = "One-time code",
32
+ "aria-labelledby": ariaLabelledBy,
33
+ "aria-describedby": ariaDescribedBy,
34
+ "aria-invalid": ariaInvalid,
35
+ className,
36
+ testID
37
+ }) => {
38
+ const colors = useThemeColors();
39
+ const [cells, setCells] = useState(() => {
40
+ const filtered = filterValue(value, pattern, length);
41
+ return Array.from({ length }, (_, i) => filtered[i] ?? "");
42
+ });
43
+ const prevValue = useRef(value);
44
+ useEffect(() => {
45
+ if (value !== prevValue.current) {
46
+ prevValue.current = value;
47
+ const filtered = filterValue(value, pattern, length);
48
+ setCells(Array.from({ length }, (_, i) => filtered[i] ?? ""));
49
+ }
50
+ }, [value, pattern, length]);
51
+ const inputRefs = useRef([]);
52
+ const focusCell = useCallback(
53
+ (idx) => {
54
+ if (idx >= 0 && idx < length) {
55
+ inputRefs.current[idx]?.focus();
56
+ }
57
+ },
58
+ [length]
59
+ );
60
+ const updateCells = useCallback(
61
+ (next) => {
62
+ setCells(next);
63
+ const joined = next.join("");
64
+ onChange?.(joined);
65
+ if (joined.length === length && !next.includes("")) {
66
+ onComplete?.(joined);
67
+ }
68
+ },
69
+ [onChange, onComplete, length]
70
+ );
71
+ const onContainerPaste = useCallback(
72
+ (e) => {
73
+ e.preventDefault();
74
+ const text = e.clipboardData.getData("text/plain") ?? "";
75
+ const filtered = filterValue(text, pattern, length);
76
+ const next = Array.from({ length }, (_, i) => filtered[i] ?? "");
77
+ updateCells(next);
78
+ const nextEmpty = next.indexOf("");
79
+ focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
80
+ },
81
+ [pattern, length, updateCells, focusCell]
82
+ );
83
+ const handleChangeText = useCallback(
84
+ (text, idx) => {
85
+ if (text.length > 1) {
86
+ const filtered = filterValue(text, pattern, length);
87
+ const next2 = Array.from({ length }, (_, i) => filtered[i] ?? "");
88
+ updateCells(next2);
89
+ const nextEmpty = next2.indexOf("");
90
+ focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);
91
+ return;
92
+ }
93
+ const char = text.slice(-1);
94
+ if (char && !isAllowed(char, pattern)) {
95
+ return;
96
+ }
97
+ const next = [...cells];
98
+ next[idx] = char;
99
+ updateCells(next);
100
+ if (char) {
101
+ focusCell(idx + 1);
102
+ }
103
+ },
104
+ [cells, pattern, length, updateCells, focusCell]
105
+ );
106
+ const handleWebKeyDown = useCallback(
107
+ (e, idx) => {
108
+ if (e.key === "Backspace") {
109
+ if (cells[idx] !== "") {
110
+ const next = [...cells];
111
+ next[idx] = "";
112
+ updateCells(next);
113
+ } else {
114
+ focusCell(idx - 1);
115
+ }
116
+ e.preventDefault();
117
+ } else if (e.key === "ArrowLeft") {
118
+ focusCell(idx - 1);
119
+ e.preventDefault();
120
+ } else if (e.key === "ArrowRight") {
121
+ focusCell(idx + 1);
122
+ e.preventDefault();
123
+ } else if (e.key.length === 1 && isAllowed(e.key, pattern)) {
124
+ const next = [...cells];
125
+ next[idx] = e.key;
126
+ updateCells(next);
127
+ focusCell(idx + 1);
128
+ e.preventDefault();
129
+ }
130
+ },
131
+ [cells, pattern, focusCell, updateCells]
132
+ );
133
+ const handleNativeKeyPress = useCallback(
134
+ (e, idx) => {
135
+ if (e.nativeEvent.key === "Backspace") {
136
+ if (cells[idx] !== "") {
137
+ const next = [...cells];
138
+ next[idx] = "";
139
+ updateCells(next);
140
+ } else {
141
+ focusCell(idx - 1);
142
+ }
143
+ }
144
+ },
145
+ [cells, focusCell, updateCells]
146
+ );
147
+ const cellStyle = [
148
+ styles.cell,
149
+ {
150
+ width: px(48),
151
+ height: px(56),
152
+ borderRadius: px(colors.radius.md),
153
+ borderColor: colors.semantic.border.default,
154
+ backgroundColor: colors.semantic.background.elevated,
155
+ color: colors.semantic.text.default,
156
+ fontSize: px(colors.fontSize.xl),
157
+ fontFamily: colors.fontFamily.body
158
+ },
159
+ disabled ? styles.disabled : null,
160
+ ariaInvalid === true || ariaInvalid === "true" ? { borderColor: colors.color.danger } : null
161
+ ];
162
+ const isWeb = Platform.OS === "web";
163
+ const containerProps = isWeb ? {
164
+ onPaste: onContainerPaste,
165
+ role: "group",
166
+ "aria-label": ariaLabel,
167
+ "aria-labelledby": ariaLabelledBy,
168
+ "aria-describedby": ariaDescribedBy
169
+ } : {};
170
+ return /* @__PURE__ */ jsxs(
171
+ View,
172
+ {
173
+ testID,
174
+ ...isWeb ? {} : { accessible: true, accessibilityLabel: ariaLabel },
175
+ ...containerProps,
176
+ className: cn("flex-row items-center gap-2", className),
177
+ style: styles.container,
178
+ children: [
179
+ Array.from({ length }, (_, idx) => {
180
+ const cellValue = cells[idx] ?? "";
181
+ const cellRef = /* @__PURE__ */ __name((el) => {
182
+ inputRefs.current[idx] = el;
183
+ }, "cellRef");
184
+ const webProps = isWeb ? {
185
+ onKeyDown: /* @__PURE__ */ __name((e) => handleWebKeyDown(e, idx), "onKeyDown"),
186
+ // id only on the first cell
187
+ ...idx === 0 && id ? { id, nativeID: id } : {},
188
+ ...idx === 0 && name ? { name } : {},
189
+ ...idx === 0 && ariaLabelledBy ? { "aria-labelledby": ariaLabelledBy } : {},
190
+ ...idx === 0 && ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
191
+ ...idx === 0 && ariaInvalid !== void 0 ? { "aria-invalid": ariaInvalid } : {},
192
+ inputMode: pattern === "numeric" ? "numeric" : "text"
193
+ } : {};
194
+ const nativeOnlyProps = isWeb ? {} : {
195
+ keyboardType: pattern === "numeric" ? "number-pad" : "default",
196
+ textAlign: "center",
197
+ selectTextOnFocus: true,
198
+ onKeyPress: /* @__PURE__ */ __name((e) => handleNativeKeyPress(e, idx), "onKeyPress")
199
+ };
200
+ return /* @__PURE__ */ jsx(
201
+ TextInput,
202
+ {
203
+ ref: cellRef,
204
+ value: cellValue,
205
+ placeholder: placeholder,
206
+ maxLength: 1,
207
+ editable: !disabled,
208
+ autoFocus: autoFocus && idx === 0,
209
+ testID: testID ? `${testID}-cell-${idx}` : void 0,
210
+ onChangeText: (text) => handleChangeText(text, idx),
211
+ accessibilityLabel: `Digit ${idx + 1} of ${length}`,
212
+ ...nativeOnlyProps,
213
+ ...webProps,
214
+ style: cellStyle
215
+ },
216
+ idx
217
+ );
218
+ }),
219
+ isWeb && name ? /* @__PURE__ */ jsx(
220
+ TextInput,
221
+ {
222
+ style: styles.hidden,
223
+ value: cells.join(""),
224
+ "aria-hidden": true,
225
+ tabIndex: -1,
226
+ ...{ name }
227
+ }
228
+ ) : null
229
+ ]
230
+ }
231
+ );
232
+ }, "InputOTP");
233
+ var styles = StyleSheet.create({
234
+ container: {
235
+ flexDirection: "row",
236
+ alignItems: "center",
237
+ gap: 8
238
+ },
239
+ cell: {
240
+ borderWidth: 1,
241
+ textAlign: "center"
242
+ },
243
+ disabled: {
244
+ opacity: 0.6
245
+ },
246
+ hidden: {
247
+ position: "absolute",
248
+ width: 0,
249
+ height: 0,
250
+ opacity: 0
251
+ }
252
+ });
253
+
254
+ export { InputOTP };
255
+ //# sourceMappingURL=chunk-BVLOX4A3.js.map
256
+ //# sourceMappingURL=chunk-BVLOX4A3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/InputOTP/InputOTP.tsx"],"names":["next","RNTextInput"],"mappings":"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","file":"chunk-BVLOX4A3.js","sourcesContent":["'use client';\n\nimport { type ClipboardEvent, type KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport {\n type NativeSyntheticEvent,\n Platform,\n TextInput as RNTextInput,\n StyleSheet,\n type TextInputKeyPressEventData,\n View,\n} from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type InputOTPPattern = 'numeric' | 'alphanumeric';\n\nexport type InputOTPProps = {\n /** Current value (string of digits/chars, length ≤ `length`). */\n value?: string;\n /** Called with the full value string on any change. */\n onChange?: (value: string) => void;\n /** Called once the code reaches `length` characters. */\n onComplete?: (value: string) => void;\n /** Number of OTP cells. @defaultValue 6 */\n length?: number;\n /** Placeholder shown in empty cells. @defaultValue '·' */\n placeholder?: string;\n /** Input character set validation. @defaultValue 'numeric' */\n pattern?: InputOTPPattern;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Auto-focus the first cell on mount. */\n autoFocus?: boolean;\n /** a11y / form id forwarded to the first cell. */\n id?: string;\n /** Form field name forwarded to hidden input (web). */\n name?: string;\n /** aria-label override. @defaultValue 'One-time code' */\n 'aria-label'?: string;\n /** aria-labelledby for Field.Control wiring. */\n 'aria-labelledby'?: string;\n /** aria-describedby for Field.Control wiring. */\n 'aria-describedby'?: string;\n /** aria-invalid for Field.Control wiring. */\n 'aria-invalid'?: boolean | 'true' | 'false';\n className?: string;\n testID?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isAllowed(char: string, pattern: InputOTPPattern): boolean {\n if (pattern === 'numeric') {\n return /^\\d$/.test(char);\n }\n return /^[a-zA-Z0-9]$/.test(char);\n}\n\nfunction filterValue(value: string, pattern: InputOTPPattern, length: number): string {\n return value\n .split('')\n .filter((c) => isAllowed(c, pattern))\n .slice(0, length)\n .join('');\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Segmented one-time-code input with auto-advance, backspace backtrack,\n * and paste-to-fill. Works cross-platform (web + native) via RN TextInput refs.\n *\n * Field.Control-compatible: pass `id`, `aria-labelledby`, `aria-describedby`,\n * `aria-invalid`, and `disabled` down from Field.Control to wire a11y.\n *\n * ```tsx\n * <InputOTP value={code} onChange={setCode} onComplete={submit} length={6} />\n * ```\n */\nexport const InputOTP = ({\n value = '',\n onChange,\n onComplete,\n length = 6,\n placeholder = '·',\n pattern = 'numeric',\n disabled = false,\n autoFocus = false,\n id,\n name,\n 'aria-label': ariaLabel = 'One-time code',\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n className,\n testID,\n}: InputOTPProps) => {\n const colors = useThemeColors();\n\n // Internal representation as array of single chars\n const [cells, setCells] = useState<string[]>(() => {\n const filtered = filterValue(value, pattern, length);\n return Array.from({ length }, (_, i) => filtered[i] ?? '');\n });\n\n // Sync controlled value into cells\n const prevValue = useRef(value);\n useEffect(() => {\n if (value !== prevValue.current) {\n prevValue.current = value;\n const filtered = filterValue(value, pattern, length);\n setCells(Array.from({ length }, (_, i) => filtered[i] ?? ''));\n }\n }, [value, pattern, length]);\n\n const inputRefs = useRef<Array<RNTextInput | null>>([]);\n\n const focusCell = useCallback(\n (idx: number) => {\n if (idx >= 0 && idx < length) {\n inputRefs.current[idx]?.focus();\n }\n },\n [length]\n );\n\n const updateCells = useCallback(\n (next: string[]) => {\n setCells(next);\n const joined = next.join('');\n onChange?.(joined);\n if (joined.length === length && !next.includes('')) {\n onComplete?.(joined);\n }\n },\n [onChange, onComplete, length]\n );\n\n // -------------------------------------------------------------------------\n // Web: handle paste on the container div\n // -------------------------------------------------------------------------\n const onContainerPaste = useCallback(\n (e: ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData('text/plain') ?? '';\n const filtered = filterValue(text, pattern, length);\n const next = Array.from({ length }, (_, i) => filtered[i] ?? '');\n updateCells(next);\n // Focus the next empty cell or the last\n const nextEmpty = next.indexOf('');\n focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);\n },\n [pattern, length, updateCells, focusCell]\n );\n\n // -------------------------------------------------------------------------\n // Native: detect paste by checking if onChangeText receives >1 char\n // -------------------------------------------------------------------------\n const handleChangeText = useCallback(\n (text: string, idx: number) => {\n // Native paste might deliver all chars at once\n if (text.length > 1) {\n const filtered = filterValue(text, pattern, length);\n const next = Array.from({ length }, (_, i) => filtered[i] ?? '');\n updateCells(next);\n const nextEmpty = next.indexOf('');\n focusCell(nextEmpty === -1 ? length - 1 : nextEmpty);\n return;\n }\n const char = text.slice(-1); // last char in case of replacement\n if (char && !isAllowed(char, pattern)) {\n return;\n }\n const next = [...cells];\n next[idx] = char;\n updateCells(next);\n if (char) {\n focusCell(idx + 1);\n }\n },\n [cells, pattern, length, updateCells, focusCell]\n );\n\n // -------------------------------------------------------------------------\n // Web: onKeyDown per cell (for backspace + web-only arrow navigation)\n // -------------------------------------------------------------------------\n const handleWebKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>, idx: number) => {\n if (e.key === 'Backspace') {\n if (cells[idx] !== '') {\n const next = [...cells];\n next[idx] = '';\n updateCells(next);\n } else {\n focusCell(idx - 1);\n }\n e.preventDefault();\n } else if (e.key === 'ArrowLeft') {\n focusCell(idx - 1);\n e.preventDefault();\n } else if (e.key === 'ArrowRight') {\n focusCell(idx + 1);\n e.preventDefault();\n } else if (e.key.length === 1 && isAllowed(e.key, pattern)) {\n // Let onChangeText handle it, but clear the cell first so\n // single-char inputs don't accumulate\n const next = [...cells];\n next[idx] = e.key;\n updateCells(next);\n focusCell(idx + 1);\n e.preventDefault();\n }\n },\n [cells, pattern, focusCell, updateCells]\n );\n\n // -------------------------------------------------------------------------\n // Native: onKeyPress for backspace\n // -------------------------------------------------------------------------\n const handleNativeKeyPress = useCallback(\n (e: NativeSyntheticEvent<TextInputKeyPressEventData>, idx: number) => {\n if (e.nativeEvent.key === 'Backspace') {\n if (cells[idx] !== '') {\n const next = [...cells];\n next[idx] = '';\n updateCells(next);\n } else {\n focusCell(idx - 1);\n }\n }\n },\n [cells, focusCell, updateCells]\n );\n\n // -------------------------------------------------------------------------\n // Styles\n // -------------------------------------------------------------------------\n const cellStyle = [\n styles.cell,\n {\n width: px(48),\n height: px(56),\n borderRadius: px(colors.radius.md),\n borderColor: colors.semantic.border.default,\n backgroundColor: colors.semantic.background.elevated,\n color: colors.semantic.text.default,\n fontSize: px(colors.fontSize.xl),\n fontFamily: colors.fontFamily.body,\n },\n disabled ? styles.disabled : null,\n ariaInvalid === true || ariaInvalid === 'true' ? { borderColor: colors.color.danger } : null,\n ];\n\n const isWeb = Platform.OS === 'web';\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n const containerProps = isWeb\n ? {\n onPaste: onContainerPaste,\n role: 'group' as const,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n }\n : {};\n\n return (\n <View\n testID={testID}\n {...(isWeb ? {} : { accessible: true, accessibilityLabel: ariaLabel })}\n {...(containerProps as object)}\n className={cn('flex-row items-center gap-2', className)}\n style={styles.container}\n >\n {Array.from({ length }, (_, idx) => {\n const cellValue = cells[idx] ?? '';\n const isFocused = false; // managed by native focus system\n\n const cellRef = (el: RNTextInput | null) => {\n inputRefs.current[idx] = el;\n };\n\n // Web cell uses a standard HTML input via RN TextInput\n const webProps = isWeb\n ? {\n onKeyDown: (e: unknown) => handleWebKeyDown(e as KeyboardEvent<HTMLInputElement>, idx),\n // id only on the first cell\n ...(idx === 0 && id ? { id, nativeID: id } : {}),\n ...(idx === 0 && name ? { name } : {}),\n ...(idx === 0 && ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),\n ...(idx === 0 && ariaDescribedBy ? { 'aria-describedby': ariaDescribedBy } : {}),\n ...(idx === 0 && ariaInvalid !== undefined ? { 'aria-invalid': ariaInvalid } : {}),\n inputMode: pattern === 'numeric' ? ('numeric' as const) : ('text' as const),\n }\n : {};\n\n // On web, omit native-only props that don't map to DOM attributes\n const nativeOnlyProps = isWeb\n ? {}\n : {\n keyboardType: pattern === 'numeric' ? ('number-pad' as const) : ('default' as const),\n textAlign: 'center' as const,\n selectTextOnFocus: true,\n onKeyPress: (e: NativeSyntheticEvent<TextInputKeyPressEventData>) =>\n handleNativeKeyPress(e, idx),\n };\n\n return (\n <RNTextInput\n // biome-ignore lint/suspicious/noArrayIndexKey: OTP cell index IS its stable slot identity\n key={idx}\n ref={cellRef}\n value={cellValue}\n placeholder={isFocused ? '' : placeholder}\n maxLength={1}\n editable={!disabled}\n autoFocus={autoFocus && idx === 0}\n testID={testID ? `${testID}-cell-${idx}` : undefined}\n onChangeText={(text) => handleChangeText(text, idx)}\n accessibilityLabel={`Digit ${idx + 1} of ${length}`}\n {...nativeOnlyProps}\n {...(webProps as object)}\n style={cellStyle}\n />\n );\n })}\n\n {/* Hidden input for form submission on web */}\n {isWeb && name ? (\n <RNTextInput\n style={styles.hidden}\n value={cells.join('')}\n aria-hidden\n tabIndex={-1}\n {...({ name } as object)}\n />\n ) : null}\n </View>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Styles\n// ---------------------------------------------------------------------------\n\nconst styles = StyleSheet.create({\n container: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n cell: {\n borderWidth: 1,\n textAlign: 'center',\n },\n disabled: {\n opacity: 0.6,\n },\n hidden: {\n position: 'absolute',\n width: 0,\n height: 0,\n opacity: 0,\n },\n});\n"]}
@@ -423,5 +423,5 @@ var Dialog = Object.assign(DialogRoot, {
423
423
  });
424
424
 
425
425
  export { Dialog };
426
- //# sourceMappingURL=chunk-PLQPBMG2.js.map
427
- //# sourceMappingURL=chunk-PLQPBMG2.js.map
426
+ //# sourceMappingURL=chunk-BXZGCOKT.js.map
427
+ //# sourceMappingURL=chunk-BXZGCOKT.js.map