@particle-academy/react-fancy 5.61.1 → 5.63.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 (166) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/autocomplete.cjs +3 -3
  3. package/dist/autocomplete.js +2 -2
  4. package/dist/breadcrumbs.cjs +3 -3
  5. package/dist/breadcrumbs.js +2 -2
  6. package/dist/{chunk-35MF32VQ.js → chunk-2HPADT4X.js} +3 -3
  7. package/dist/chunk-2HPADT4X.js.map +1 -0
  8. package/dist/{chunk-KNKOSMOQ.cjs → chunk-35S5BTZH.cjs} +4 -4
  9. package/dist/{chunk-KNKOSMOQ.cjs.map → chunk-35S5BTZH.cjs.map} +1 -1
  10. package/dist/{chunk-X6TGRSVH.cjs → chunk-4GOOSZEK.cjs} +7 -18
  11. package/dist/chunk-4GOOSZEK.cjs.map +1 -0
  12. package/dist/{chunk-3I6PE2US.cjs → chunk-4XHG6Q42.cjs} +11 -11
  13. package/dist/{chunk-3I6PE2US.cjs.map → chunk-4XHG6Q42.cjs.map} +1 -1
  14. package/dist/{chunk-3AYRLFNO.js → chunk-A67EDGC7.js} +3 -3
  15. package/dist/{chunk-3AYRLFNO.js.map → chunk-A67EDGC7.js.map} +1 -1
  16. package/dist/{chunk-4HUD33OP.cjs → chunk-A6HWKQ4D.cjs} +4 -4
  17. package/dist/{chunk-4HUD33OP.cjs.map → chunk-A6HWKQ4D.cjs.map} +1 -1
  18. package/dist/{chunk-P6V4QWJK.cjs → chunk-AJPYGRLA.cjs} +4 -4
  19. package/dist/{chunk-P6V4QWJK.cjs.map → chunk-AJPYGRLA.cjs.map} +1 -1
  20. package/dist/{chunk-LMOPAY7Q.js → chunk-ARO2DNGS.js} +3 -3
  21. package/dist/{chunk-LMOPAY7Q.js.map → chunk-ARO2DNGS.js.map} +1 -1
  22. package/dist/{chunk-BMVYOVSW.cjs → chunk-ATIDUWY6.cjs} +20 -10
  23. package/dist/chunk-ATIDUWY6.cjs.map +1 -0
  24. package/dist/{chunk-N7KUGFRG.js → chunk-BTNF3QBR.js} +4 -4
  25. package/dist/{chunk-N7KUGFRG.js.map → chunk-BTNF3QBR.js.map} +1 -1
  26. package/dist/{chunk-BLS2IGPY.js → chunk-CAUEKGMR.js} +16 -6
  27. package/dist/chunk-CAUEKGMR.js.map +1 -0
  28. package/dist/{chunk-K6NADZ7O.cjs → chunk-CMC2TOEQ.cjs} +6 -6
  29. package/dist/{chunk-K6NADZ7O.cjs.map → chunk-CMC2TOEQ.cjs.map} +1 -1
  30. package/dist/{chunk-NDLESFUH.js → chunk-ELFTEJBT.js} +3 -3
  31. package/dist/{chunk-NDLESFUH.js.map → chunk-ELFTEJBT.js.map} +1 -1
  32. package/dist/{chunk-PKFEJWVI.js → chunk-EUVWYDFN.js} +3 -3
  33. package/dist/{chunk-PKFEJWVI.js.map → chunk-EUVWYDFN.js.map} +1 -1
  34. package/dist/{chunk-ULG4OA2T.js → chunk-FVI4JDLA.js} +3 -3
  35. package/dist/{chunk-ULG4OA2T.js.map → chunk-FVI4JDLA.js.map} +1 -1
  36. package/dist/{chunk-IY6LVALS.js → chunk-GEQKNV7E.js} +3 -3
  37. package/dist/{chunk-IY6LVALS.js.map → chunk-GEQKNV7E.js.map} +1 -1
  38. package/dist/{chunk-4FJWHVC7.js → chunk-GR2WKBER.js} +4 -2
  39. package/dist/chunk-GR2WKBER.js.map +1 -0
  40. package/dist/{chunk-NFTTNFQR.js → chunk-GZ5Z56QK.js} +4 -4
  41. package/dist/{chunk-NFTTNFQR.js.map → chunk-GZ5Z56QK.js.map} +1 -1
  42. package/dist/{chunk-Z5OTOYWI.cjs → chunk-HANQYZW2.cjs} +4 -4
  43. package/dist/{chunk-Z5OTOYWI.cjs.map → chunk-HANQYZW2.cjs.map} +1 -1
  44. package/dist/{chunk-UBEOB55O.js → chunk-JG2DJK5A.js} +3 -3
  45. package/dist/{chunk-UBEOB55O.js.map → chunk-JG2DJK5A.js.map} +1 -1
  46. package/dist/{chunk-J4FKJ4IR.cjs → chunk-LFC2DL6H.cjs} +4 -4
  47. package/dist/{chunk-J4FKJ4IR.cjs.map → chunk-LFC2DL6H.cjs.map} +1 -1
  48. package/dist/{chunk-FU6K7XXZ.cjs → chunk-MKGWHSNV.cjs} +4 -4
  49. package/dist/{chunk-FU6K7XXZ.cjs.map → chunk-MKGWHSNV.cjs.map} +1 -1
  50. package/dist/{chunk-BHUSI56C.js → chunk-MVVHUTXA.js} +3 -3
  51. package/dist/{chunk-BHUSI56C.js.map → chunk-MVVHUTXA.js.map} +1 -1
  52. package/dist/{chunk-UJZJBHMH.js → chunk-NILA2LZY.js} +3 -3
  53. package/dist/{chunk-UJZJBHMH.js.map → chunk-NILA2LZY.js.map} +1 -1
  54. package/dist/{chunk-SHF44YGG.js → chunk-NSJBVV7R.js} +3 -3
  55. package/dist/{chunk-SHF44YGG.js.map → chunk-NSJBVV7R.js.map} +1 -1
  56. package/dist/{chunk-QXMQVLRQ.cjs → chunk-OASSZI6M.cjs} +4 -2
  57. package/dist/chunk-OASSZI6M.cjs.map +1 -0
  58. package/dist/chunk-OUYC6EIL.cjs +66 -0
  59. package/dist/chunk-OUYC6EIL.cjs.map +1 -0
  60. package/dist/{chunk-5JFA7NYE.js → chunk-PXZRYL5I.js} +3 -3
  61. package/dist/{chunk-5JFA7NYE.js.map → chunk-PXZRYL5I.js.map} +1 -1
  62. package/dist/{chunk-TYTENEJQ.cjs → chunk-QNQNGARW.cjs} +6 -6
  63. package/dist/{chunk-TYTENEJQ.cjs.map → chunk-QNQNGARW.cjs.map} +1 -1
  64. package/dist/{chunk-74MEJWMH.js → chunk-QP35Z2WB.js} +3 -3
  65. package/dist/{chunk-74MEJWMH.js.map → chunk-QP35Z2WB.js.map} +1 -1
  66. package/dist/{chunk-NORVXHRU.js → chunk-QTS4Q2NK.js} +3 -3
  67. package/dist/{chunk-NORVXHRU.js.map → chunk-QTS4Q2NK.js.map} +1 -1
  68. package/dist/{chunk-7KTBVKNO.cjs → chunk-R6URPHEP.cjs} +4 -4
  69. package/dist/{chunk-7KTBVKNO.cjs.map → chunk-R6URPHEP.cjs.map} +1 -1
  70. package/dist/{chunk-4JLFIPHZ.js → chunk-RP43ZFZP.js} +8 -3
  71. package/dist/chunk-RP43ZFZP.js.map +1 -0
  72. package/dist/{chunk-IEQK3LGI.cjs → chunk-S4FXY3B4.cjs} +3 -3
  73. package/dist/chunk-S4FXY3B4.cjs.map +1 -0
  74. package/dist/{chunk-RRMQGTVB.cjs → chunk-SYEHWUM5.cjs} +6 -6
  75. package/dist/{chunk-RRMQGTVB.cjs.map → chunk-SYEHWUM5.cjs.map} +1 -1
  76. package/dist/{chunk-IHQHTJNN.js → chunk-SZH7TFME.js} +4 -4
  77. package/dist/{chunk-IHQHTJNN.js.map → chunk-SZH7TFME.js.map} +1 -1
  78. package/dist/{chunk-JOWAS5A5.cjs → chunk-TQGRXJ74.cjs} +9 -9
  79. package/dist/{chunk-JOWAS5A5.cjs.map → chunk-TQGRXJ74.cjs.map} +1 -1
  80. package/dist/{chunk-6GBO7R25.cjs → chunk-UJRMY54A.cjs} +4 -4
  81. package/dist/{chunk-6GBO7R25.cjs.map → chunk-UJRMY54A.cjs.map} +1 -1
  82. package/dist/{chunk-ZPBCZPMD.cjs → chunk-VQJ5LJJH.cjs} +8 -3
  83. package/dist/chunk-VQJ5LJJH.cjs.map +1 -0
  84. package/dist/{chunk-MSGKIWYX.js → chunk-VZNBTCGA.js} +3 -3
  85. package/dist/{chunk-MSGKIWYX.js.map → chunk-VZNBTCGA.js.map} +1 -1
  86. package/dist/{chunk-M6MGQI6G.cjs → chunk-WKPBCB67.cjs} +4 -4
  87. package/dist/{chunk-M6MGQI6G.cjs.map → chunk-WKPBCB67.cjs.map} +1 -1
  88. package/dist/{chunk-645CRPU6.cjs → chunk-WVSHAJKI.cjs} +7 -7
  89. package/dist/{chunk-645CRPU6.cjs.map → chunk-WVSHAJKI.cjs.map} +1 -1
  90. package/dist/chunk-YX6FTJ6N.js +62 -0
  91. package/dist/chunk-YX6FTJ6N.js.map +1 -0
  92. package/dist/{chunk-HRYM76ZE.cjs → chunk-Z6LYBL5L.cjs} +9 -9
  93. package/dist/{chunk-HRYM76ZE.cjs.map → chunk-Z6LYBL5L.cjs.map} +1 -1
  94. package/dist/{chunk-3DMVK74Q.cjs → chunk-Z7SQMQTF.cjs} +4 -4
  95. package/dist/{chunk-3DMVK74Q.cjs.map → chunk-Z7SQMQTF.cjs.map} +1 -1
  96. package/dist/{chunk-CHQH6M67.js → chunk-ZQ3VXRUY.js} +7 -18
  97. package/dist/chunk-ZQ3VXRUY.js.map +1 -0
  98. package/dist/command.cjs +4 -4
  99. package/dist/command.js +2 -2
  100. package/dist/composer.cjs +6 -6
  101. package/dist/composer.js +4 -4
  102. package/dist/context-menu.cjs +4 -4
  103. package/dist/context-menu.js +2 -2
  104. package/dist/drawer.cjs +4 -4
  105. package/dist/drawer.js +2 -2
  106. package/dist/dropdown.cjs +4 -4
  107. package/dist/dropdown.js +2 -2
  108. package/dist/editor.cjs +6 -6
  109. package/dist/editor.d.cts +12 -2
  110. package/dist/editor.d.ts +12 -2
  111. package/dist/editor.js +4 -4
  112. package/dist/full-screen.cjs +10 -9
  113. package/dist/full-screen.d.cts +5 -2
  114. package/dist/full-screen.d.ts +5 -2
  115. package/dist/full-screen.js +4 -3
  116. package/dist/index.cjs +84 -76
  117. package/dist/index.d.cts +2 -4
  118. package/dist/index.d.ts +2 -4
  119. package/dist/index.js +23 -23
  120. package/dist/input.cjs +5 -5
  121. package/dist/input.js +4 -4
  122. package/dist/inputs.cjs +7 -7
  123. package/dist/inputs.js +5 -5
  124. package/dist/json-editor.cjs +17 -17
  125. package/dist/json-editor.js +6 -6
  126. package/dist/kanban.cjs +3 -3
  127. package/dist/kanban.js +1 -1
  128. package/dist/mobile-menu.cjs +5 -5
  129. package/dist/mobile-menu.js +3 -3
  130. package/dist/modal.cjs +4 -4
  131. package/dist/modal.js +2 -2
  132. package/dist/paste-pills.cjs +16 -16
  133. package/dist/paste-pills.js +3 -3
  134. package/dist/popover.cjs +4 -4
  135. package/dist/popover.js +2 -2
  136. package/dist/prompt-input.cjs +6 -6
  137. package/dist/prompt-input.js +5 -5
  138. package/dist/reason-tag.cjs +4 -4
  139. package/dist/reason-tag.js +3 -3
  140. package/dist/select.cjs +3 -3
  141. package/dist/select.js +2 -2
  142. package/dist/sidebar.cjs +2 -2
  143. package/dist/sidebar.js +2 -2
  144. package/dist/tooltip.cjs +3 -2
  145. package/dist/tooltip.js +2 -1
  146. package/dist/{use-full-screen-BUJ1ujG4.d.ts → use-full-screen-BUke36LI.d.cts} +27 -1
  147. package/dist/{use-full-screen-BUJ1ujG4.d.cts → use-full-screen-BUke36LI.d.ts} +27 -1
  148. package/docs/Editor.md +18 -0
  149. package/docs/FullScreen.md +1 -1
  150. package/docs/Kanban.md +4 -2
  151. package/docs/hooks.md +9 -3
  152. package/package.json +1 -1
  153. package/dist/chunk-35MF32VQ.js.map +0 -1
  154. package/dist/chunk-4FJWHVC7.js.map +0 -1
  155. package/dist/chunk-4JLFIPHZ.js.map +0 -1
  156. package/dist/chunk-BLS2IGPY.js.map +0 -1
  157. package/dist/chunk-BMVYOVSW.cjs.map +0 -1
  158. package/dist/chunk-CHQH6M67.js.map +0 -1
  159. package/dist/chunk-IEQK3LGI.cjs.map +0 -1
  160. package/dist/chunk-JXE5XID6.js +0 -19
  161. package/dist/chunk-JXE5XID6.js.map +0 -1
  162. package/dist/chunk-QXMQVLRQ.cjs.map +0 -1
  163. package/dist/chunk-RXDRYWVD.cjs +0 -21
  164. package/dist/chunk-RXDRYWVD.cjs.map +0 -1
  165. package/dist/chunk-X6TGRSVH.cjs.map +0 -1
  166. package/dist/chunk-ZPBCZPMD.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkTYTENEJQ_cjs = require('./chunk-TYTENEJQ.cjs');
3
+ var chunkQNQNGARW_cjs = require('./chunk-QNQNGARW.cjs');
4
4
  var chunkSNHU2AI4_cjs = require('./chunk-SNHU2AI4.cjs');
5
5
  var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
6
6
  var react = require('react');
@@ -37,7 +37,7 @@ var Composer = react.forwardRef(
37
37
  );
38
38
  const textareaRef = react.useRef(null);
39
39
  const editorRef = react.useRef(null);
40
- const paste = chunkTYTENEJQ_cjs.useInlinePaste({
40
+ const paste = chunkQNQNGARW_cjs.useInlinePaste({
41
41
  pasteThreshold,
42
42
  pasteImages,
43
43
  previewChars,
@@ -131,7 +131,7 @@ ${text}` : text);
131
131
  "data-react-fancy-composer-paste-pill": paste2.id,
132
132
  onClick: () => insertPaste(paste2),
133
133
  disabled,
134
- "aria-label": `Insert this pasted text, ${chunkTYTENEJQ_cjs.withSeparators(paste2.text.length)} characters`,
134
+ "aria-label": `Insert this pasted text, ${chunkQNQNGARW_cjs.withSeparators(paste2.text.length)} characters`,
135
135
  "aria-describedby": `${paste2.id}-preview`,
136
136
  className: chunkZU5Q77OT_cjs.cn(
137
137
  "inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700",
@@ -140,7 +140,7 @@ ${text}` : text);
140
140
  ),
141
141
  children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
142
142
  "Pasted text \xB7 ",
143
- chunkTYTENEJQ_cjs.withSeparators(paste2.text.length),
143
+ chunkQNQNGARW_cjs.withSeparators(paste2.text.length),
144
144
  " characters"
145
145
  ] })
146
146
  }
@@ -170,7 +170,7 @@ ${text}` : text);
170
170
  "pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900",
171
171
  classNames?.preview
172
172
  ),
173
- children: renderPastePreview?.({ kind: "text", paste: paste2 }) ?? chunkTYTENEJQ_cjs.endsOf(paste2.text, previewChars)
173
+ children: renderPastePreview?.({ kind: "text", paste: paste2 }) ?? chunkQNQNGARW_cjs.endsOf(paste2.text, previewChars)
174
174
  }
175
175
  )
176
176
  ] }, paste2.id)
@@ -179,7 +179,7 @@ ${text}` : text);
179
179
  ),
180
180
  inline ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
181
181
  /* @__PURE__ */ jsxRuntime.jsx(
182
- chunkTYTENEJQ_cjs.InlinePasteEditor,
182
+ chunkQNQNGARW_cjs.InlinePasteEditor,
183
183
  {
184
184
  ref: editorRef,
185
185
  value,
@@ -194,7 +194,7 @@ ${text}` : text);
194
194
  }
195
195
  ),
196
196
  paste.portals,
197
- pasteImages && pasteFilesName && /* @__PURE__ */ jsxRuntime.jsx(chunkTYTENEJQ_cjs.PastedFilesInput, { name: pasteFilesName, files: pastedFiles })
197
+ pasteImages && pasteFilesName && /* @__PURE__ */ jsxRuntime.jsx(chunkQNQNGARW_cjs.PastedFilesInput, { name: pasteFilesName, files: pastedFiles })
198
198
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(
199
199
  "textarea",
200
200
  {
@@ -233,5 +233,5 @@ ${text}` : text);
233
233
  Composer.displayName = "Composer";
234
234
 
235
235
  exports.Composer = Composer;
236
- //# sourceMappingURL=chunk-JOWAS5A5.cjs.map
237
- //# sourceMappingURL=chunk-JOWAS5A5.cjs.map
236
+ //# sourceMappingURL=chunk-TQGRXJ74.cjs.map
237
+ //# sourceMappingURL=chunk-TQGRXJ74.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Composer/Composer.tsx"],"names":["forwardRef","Composer","useControllableState","useRef","useInlinePaste","useMemo","useCallback","jsxs","cn","jsx","paste","withSeparators","endsOf","Fragment","InlinePasteEditor","PastedFilesInput"],"mappings":"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","file":"chunk-JOWAS5A5.cjs","sourcesContent":["import { forwardRef, useCallback, useMemo, useRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport {\n endsOf,\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n withSeparators,\n type HeldPaste,\n type InlinePasteEditorHandle,\n} from \"../PastePills\";\nimport type { ComposerProps } from \"./Composer.types\";\n\n/** Characters of a held paste shown at each end of the hover preview, unless `previewChars` says otherwise. */\nconst PREVIEW_CHARS = 20;\n\nexport const Composer = forwardRef<HTMLDivElement, ComposerProps>(\n function Composer(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSubmit,\n placeholder = \"Type a message...\",\n actions,\n disabled = false,\n className,\n pasteThreshold,\n pastePlacement = \"above\",\n pasteImages = false,\n previewChars = PREVIEW_CHARS,\n renderPastePreview,\n classNames,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n pasteFilesName,\n },\n ref,\n ) {\n const inline = pastePlacement === \"inline\";\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n /*\n * The holding logic lives in `usePastePills`, wrapped by `useInlinePaste` for\n * the inline placement — which `PromptInput` shares, so the two components\n * cannot disagree about what a pill means. The rule that must not drift is\n * the one below: a send with pills still closed carries the text.\n */\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames,\n disabled,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n editorRef,\n });\n const pills = paste.pills;\n const heldPastes = paste.heldPastes;\n const pastedFiles = useMemo(\n () => (inline && pasteImages ? paste.imagesIn(value).map((i) => i.file) : []),\n [inline, pasteImages, paste, value],\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n // Composable by design, so this reads as a question rather than a handover.\n // Nothing else here wants the paste, so the answer is simply ignored.\n pills.handlePaste(e);\n },\n [pills],\n );\n\n const handleInlineChange = useCallback(\n (next: string) => {\n setValue(next);\n paste.prune(next);\n },\n [setValue, paste],\n );\n\n /** Everything the person believes they are sending, in the order they built it. */\n const composeOutgoing = useCallback(() => {\n if (inline) return paste.expand(value);\n\n return [value, ...heldPastes.map((p) => p.text)].filter(Boolean).join(\"\\n\\n\");\n }, [inline, value, heldPastes, paste]);\n\n const hasContent = value.trim().length > 0 || (!inline && heldPastes.length > 0);\n\n const focusInput = useCallback(() => {\n if (inline) editorRef.current?.focus();\n else textareaRef.current?.focus();\n }, [inline]);\n\n const handleSubmit = useCallback(() => {\n if (!hasContent || disabled) return;\n\n /*\n * THE DANGEROUS STATE, and the reason this feature needed a spec rather than\n * a guess. A pill reads as \"your paste is attached\" — so a send that drops it\n * means asking a question about a document without the document, and nobody\n * can tell: the sender believes it went, the receiver sees a question about\n * nothing.\n *\n * Above the input, held pastes go out in arrival order after what was typed,\n * because people type the question BEFORE pasting the thing it is about.\n * Inline, every pill goes out exactly where it sits.\n */\n const images = inline ? paste.imagesIn(value) : [];\n\n onSubmit?.(composeOutgoing(), { images });\n setValue(\"\");\n paste.clear();\n focusInput();\n }, [hasContent, disabled, value, inline, paste, onSubmit, composeOutgoing, setValue, focusInput]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n /** Above the input: click a pill to dump it in, APPENDED to what is already typed. */\n const insertPaste = useCallback(\n (held: HeldPaste) => {\n // `expand` removes it and hands back the text; inserting is this\n // component's job because the hook owns no DOM.\n const text = pills.expand(held.id);\n\n if (text === undefined) return;\n\n setValue((current) => (current ? `${current}\\n\\n${text}` : text));\n textareaRef.current?.focus();\n },\n [pills, setValue],\n );\n\n return (\n <div\n data-react-fancy-composer=\"\"\n ref={ref}\n className={cn(\n \"rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n disabled && \"opacity-50\",\n className,\n )}\n >\n {!inline && heldPastes.length > 0 && (\n <div\n data-react-fancy-composer-paste-pills=\"\"\n className=\"flex flex-wrap gap-1.5 px-3 pt-3\"\n >\n {heldPastes.map((paste) => (\n // `group` + `group-hover` rather than hover state: the preview is\n // presentation, and a useState for it would be one more thing an\n // agent could desynchronise.\n <span key={paste.id} className=\"group relative inline-flex\">\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill={paste.id}\n onClick={() => insertPaste(paste)}\n disabled={disabled}\n // No `title`. A native tooltip plus the hover preview below\n // renders TWO tooltips on the same hover, at different delays.\n // The label says what clicking does; the preview says what the\n // text is, and it is linked rather than merely adjacent so a\n // screen reader reaches it too.\n aria-label={`Insert this pasted text, ${withSeparators(paste.text.length)} characters`}\n aria-describedby={`${paste.id}-preview`}\n // `pr-7` leaves room for the absolutely-positioned × that sits\n // over this button's right edge. With a smaller right padding the\n // × lands on top of the label.\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700\",\n classNames?.pill,\n classNames?.textPill,\n )}\n >\n <span>\n Pasted text · {withSeparators(paste.text.length)} characters\n </span>\n </button>\n\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill-remove={paste.id}\n onClick={() => pills.remove(paste.id)}\n disabled={disabled}\n aria-label=\"Discard this pasted text\"\n className={cn(\n \"absolute right-1 top-1/2 -translate-y-1/2 rounded-full px-1 text-xs text-zinc-400 transition-colors hover:text-zinc-700 dark:hover:text-zinc-100\",\n classNames?.remove,\n )}\n >\n ×\n </button>\n\n <span\n id={`${paste.id}-preview`}\n data-react-fancy-composer-paste-pill-preview={paste.id}\n role=\"tooltip\"\n className={cn(\n \"pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900\",\n classNames?.preview,\n )}\n >\n {renderPastePreview?.({ kind: \"text\", paste }) ??\n endsOf(paste.text, previewChars)}\n </span>\n </span>\n ))}\n </div>\n )}\n\n {inline ? (\n <>\n <InlinePasteEditor\n ref={editorRef}\n value={value}\n known={paste.known}\n onChange={handleInlineChange}\n onSubmit={handleSubmit}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={placeholder}\n disabled={disabled}\n className={classNames?.input}\n />\n {paste.portals}\n {pasteImages && pasteFilesName && (\n <PastedFilesInput name={pasteFilesName} files={pastedFiles} />\n )}\n </>\n ) : (\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none bg-transparent px-4 pt-3 text-sm outline-none placeholder:text-zinc-400\",\n classNames?.input,\n )}\n />\n )}\n <div className=\"flex items-center justify-between border-t border-zinc-100 px-3 py-2 dark:border-zinc-800\">\n <div className=\"flex items-center gap-1\">{actions}</div>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || !hasContent}\n className=\"rounded-lg bg-zinc-900 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 disabled:opacity-50 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100\"\n >\n Send\n </button>\n </div>\n </div>\n );\n },\n);\n\nComposer.displayName = \"Composer\";\n"]}
1
+ {"version":3,"sources":["../src/components/Composer/Composer.tsx"],"names":["forwardRef","Composer","useControllableState","useRef","useInlinePaste","useMemo","useCallback","jsxs","cn","jsx","paste","withSeparators","endsOf","Fragment","InlinePasteEditor","PastedFilesInput"],"mappings":"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","file":"chunk-TQGRXJ74.cjs","sourcesContent":["import { forwardRef, useCallback, useMemo, useRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport {\n endsOf,\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n withSeparators,\n type HeldPaste,\n type InlinePasteEditorHandle,\n} from \"../PastePills\";\nimport type { ComposerProps } from \"./Composer.types\";\n\n/** Characters of a held paste shown at each end of the hover preview, unless `previewChars` says otherwise. */\nconst PREVIEW_CHARS = 20;\n\nexport const Composer = forwardRef<HTMLDivElement, ComposerProps>(\n function Composer(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSubmit,\n placeholder = \"Type a message...\",\n actions,\n disabled = false,\n className,\n pasteThreshold,\n pastePlacement = \"above\",\n pasteImages = false,\n previewChars = PREVIEW_CHARS,\n renderPastePreview,\n classNames,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n pasteFilesName,\n },\n ref,\n ) {\n const inline = pastePlacement === \"inline\";\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n /*\n * The holding logic lives in `usePastePills`, wrapped by `useInlinePaste` for\n * the inline placement — which `PromptInput` shares, so the two components\n * cannot disagree about what a pill means. The rule that must not drift is\n * the one below: a send with pills still closed carries the text.\n */\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames,\n disabled,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n editorRef,\n });\n const pills = paste.pills;\n const heldPastes = paste.heldPastes;\n const pastedFiles = useMemo(\n () => (inline && pasteImages ? paste.imagesIn(value).map((i) => i.file) : []),\n [inline, pasteImages, paste, value],\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n // Composable by design, so this reads as a question rather than a handover.\n // Nothing else here wants the paste, so the answer is simply ignored.\n pills.handlePaste(e);\n },\n [pills],\n );\n\n const handleInlineChange = useCallback(\n (next: string) => {\n setValue(next);\n paste.prune(next);\n },\n [setValue, paste],\n );\n\n /** Everything the person believes they are sending, in the order they built it. */\n const composeOutgoing = useCallback(() => {\n if (inline) return paste.expand(value);\n\n return [value, ...heldPastes.map((p) => p.text)].filter(Boolean).join(\"\\n\\n\");\n }, [inline, value, heldPastes, paste]);\n\n const hasContent = value.trim().length > 0 || (!inline && heldPastes.length > 0);\n\n const focusInput = useCallback(() => {\n if (inline) editorRef.current?.focus();\n else textareaRef.current?.focus();\n }, [inline]);\n\n const handleSubmit = useCallback(() => {\n if (!hasContent || disabled) return;\n\n /*\n * THE DANGEROUS STATE, and the reason this feature needed a spec rather than\n * a guess. A pill reads as \"your paste is attached\" — so a send that drops it\n * means asking a question about a document without the document, and nobody\n * can tell: the sender believes it went, the receiver sees a question about\n * nothing.\n *\n * Above the input, held pastes go out in arrival order after what was typed,\n * because people type the question BEFORE pasting the thing it is about.\n * Inline, every pill goes out exactly where it sits.\n */\n const images = inline ? paste.imagesIn(value) : [];\n\n onSubmit?.(composeOutgoing(), { images });\n setValue(\"\");\n paste.clear();\n focusInput();\n }, [hasContent, disabled, value, inline, paste, onSubmit, composeOutgoing, setValue, focusInput]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n /** Above the input: click a pill to dump it in, APPENDED to what is already typed. */\n const insertPaste = useCallback(\n (held: HeldPaste) => {\n // `expand` removes it and hands back the text; inserting is this\n // component's job because the hook owns no DOM.\n const text = pills.expand(held.id);\n\n if (text === undefined) return;\n\n setValue((current) => (current ? `${current}\\n\\n${text}` : text));\n textareaRef.current?.focus();\n },\n [pills, setValue],\n );\n\n return (\n <div\n data-react-fancy-composer=\"\"\n ref={ref}\n className={cn(\n \"rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n disabled && \"opacity-50\",\n className,\n )}\n >\n {!inline && heldPastes.length > 0 && (\n <div\n data-react-fancy-composer-paste-pills=\"\"\n className=\"flex flex-wrap gap-1.5 px-3 pt-3\"\n >\n {heldPastes.map((paste) => (\n // `group` + `group-hover` rather than hover state: the preview is\n // presentation, and a useState for it would be one more thing an\n // agent could desynchronise.\n <span key={paste.id} className=\"group relative inline-flex\">\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill={paste.id}\n onClick={() => insertPaste(paste)}\n disabled={disabled}\n // No `title`. A native tooltip plus the hover preview below\n // renders TWO tooltips on the same hover, at different delays.\n // The label says what clicking does; the preview says what the\n // text is, and it is linked rather than merely adjacent so a\n // screen reader reaches it too.\n aria-label={`Insert this pasted text, ${withSeparators(paste.text.length)} characters`}\n aria-describedby={`${paste.id}-preview`}\n // `pr-7` leaves room for the absolutely-positioned × that sits\n // over this button's right edge. With a smaller right padding the\n // × lands on top of the label.\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700\",\n classNames?.pill,\n classNames?.textPill,\n )}\n >\n <span>\n Pasted text · {withSeparators(paste.text.length)} characters\n </span>\n </button>\n\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill-remove={paste.id}\n onClick={() => pills.remove(paste.id)}\n disabled={disabled}\n aria-label=\"Discard this pasted text\"\n className={cn(\n \"absolute right-1 top-1/2 -translate-y-1/2 rounded-full px-1 text-xs text-zinc-400 transition-colors hover:text-zinc-700 dark:hover:text-zinc-100\",\n classNames?.remove,\n )}\n >\n ×\n </button>\n\n <span\n id={`${paste.id}-preview`}\n data-react-fancy-composer-paste-pill-preview={paste.id}\n role=\"tooltip\"\n className={cn(\n \"pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900\",\n classNames?.preview,\n )}\n >\n {renderPastePreview?.({ kind: \"text\", paste }) ??\n endsOf(paste.text, previewChars)}\n </span>\n </span>\n ))}\n </div>\n )}\n\n {inline ? (\n <>\n <InlinePasteEditor\n ref={editorRef}\n value={value}\n known={paste.known}\n onChange={handleInlineChange}\n onSubmit={handleSubmit}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={placeholder}\n disabled={disabled}\n className={classNames?.input}\n />\n {paste.portals}\n {pasteImages && pasteFilesName && (\n <PastedFilesInput name={pasteFilesName} files={pastedFiles} />\n )}\n </>\n ) : (\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none bg-transparent px-4 pt-3 text-sm outline-none placeholder:text-zinc-400\",\n classNames?.input,\n )}\n />\n )}\n <div className=\"flex items-center justify-between border-t border-zinc-100 px-3 py-2 dark:border-zinc-800\">\n <div className=\"flex items-center gap-1\">{actions}</div>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || !hasContent}\n className=\"rounded-lg bg-zinc-900 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 disabled:opacity-50 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100\"\n >\n Send\n </button>\n </div>\n </div>\n );\n },\n);\n\nComposer.displayName = \"Composer\";\n"]}
@@ -3,7 +3,7 @@
3
3
  var chunkTXTRTTG7_cjs = require('./chunk-TXTRTTG7.cjs');
4
4
  var chunkFQZE5N2N_cjs = require('./chunk-FQZE5N2N.cjs');
5
5
  var chunkTI7D4QDM_cjs = require('./chunk-TI7D4QDM.cjs');
6
- var chunkRXDRYWVD_cjs = require('./chunk-RXDRYWVD.cjs');
6
+ var chunkOUYC6EIL_cjs = require('./chunk-OUYC6EIL.cjs');
7
7
  var chunkSNHU2AI4_cjs = require('./chunk-SNHU2AI4.cjs');
8
8
  var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
9
9
  var react = require('react');
@@ -147,7 +147,7 @@ function CommandRoot({
147
147
  setQuery("");
148
148
  setActiveIndex(-1);
149
149
  }, [onClose]);
150
- chunkRXDRYWVD_cjs.useEscapeKey(close, open);
150
+ chunkOUYC6EIL_cjs.useEscapeKey(close, open);
151
151
  chunkTXTRTTG7_cjs.useFocusTrap(panelRef, open);
152
152
  react.useEffect(() => {
153
153
  if (open) {
@@ -260,5 +260,5 @@ var Command = Object.assign(CommandRoot, {
260
260
 
261
261
  exports.Command = Command;
262
262
  exports.useCommand = useCommand;
263
- //# sourceMappingURL=chunk-6GBO7R25.cjs.map
264
- //# sourceMappingURL=chunk-6GBO7R25.cjs.map
263
+ //# sourceMappingURL=chunk-UJRMY54A.cjs.map
264
+ //# sourceMappingURL=chunk-UJRMY54A.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Command/Command.context.ts","../src/components/Command/CommandInput.tsx","../src/components/Command/CommandList.tsx","../src/components/Command/CommandItem.tsx","../src/components/Command/CommandGroup.tsx","../src/components/Command/CommandEmpty.tsx","../src/components/Command/Command.tsx"],"names":["createContext","useContext","jsxs","jsx","Search","cn","useId","useControllableState","useState","useRef","useCallback","useEscapeKey","useFocusTrap","useEffect","useLayoutEffect","useAnimation","useMemo","Portal"],"mappings":"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","file":"chunk-6GBO7R25.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { CommandContextValue } from \"./Command.types\";\n\nexport const CommandContext = createContext<CommandContextValue | null>(null);\n\nexport function useCommand(): CommandContextValue {\n const ctx = useContext(CommandContext);\n if (!ctx) {\n throw new Error(\n \"Command compound components must be used within <Command>\",\n );\n }\n return ctx;\n}\n","import { Search } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useCommand } from \"./Command.context\";\nimport type { CommandInputProps } from \"./Command.types\";\n\nexport function CommandInput({\n placeholder = \"Type a command or search...\",\n className,\n}: CommandInputProps) {\n const { query, setQuery, listId } = useCommand();\n\n return (\n <div data-react-fancy-command-input=\"\" className=\"flex items-center border-b border-[color:var(--fancy-border,var(--color-zinc-200))] px-4 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\">\n <Search size={16} className=\"shrink-0 text-zinc-400\" />\n <input\n type=\"text\"\n // A combobox: focus stays here while the arrows move the active option,\n // which Command announces through aria-activedescendant.\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={placeholder}\n className={cn(\n \"flex-1 bg-transparent px-3 py-3 text-sm outline-none placeholder:text-zinc-400\",\n className,\n )}\n autoFocus\n />\n </div>\n );\n}\n\nCommandInput.displayName = \"CommandInput\";\n","import { cn } from \"../../utils/cn\";\nimport { useCommand } from \"./Command.context\";\nimport type { CommandListProps } from \"./Command.types\";\n\nexport function CommandList({ children, className }: CommandListProps) {\n const { listId } = useCommand();\n\n return (\n <div\n id={listId}\n data-react-fancy-command-list=\"\"\n role=\"listbox\"\n className={cn(\"max-h-72 overflow-y-auto p-2\", className)}\n >\n {children}\n </div>\n );\n}\n\nCommandList.displayName = \"CommandList\";\n","import { useId } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useCommand } from \"./Command.context\";\nimport type { CommandItemProps } from \"./Command.types\";\n\nexport function CommandItem({\n children,\n value,\n onSelect,\n className,\n}: CommandItemProps) {\n const { query, close, shouldFilter, setActiveIndex } = useCommand();\n // Called before the filter's early return, so the hook order never changes.\n const id = useId();\n\n // Filter by query — unless the caller filters for itself (`shouldFilter={false}`).\n const text = value ?? (typeof children === \"string\" ? children : \"\");\n if (shouldFilter && query && !text.toLowerCase().includes(query.toLowerCase())) {\n return null;\n }\n\n return (\n <button\n id={id}\n data-react-fancy-command-item=\"\"\n type=\"button\"\n role=\"option\"\n // Marked active by Command itself (aria-selected + data-active), since an\n // item cannot know its own position among the rendered options.\n aria-selected={false}\n // Keyboard focus stays in the input; the items are reached with the arrows.\n tabIndex={-1}\n onMouseEnter={(e) => {\n const options = e.currentTarget\n .closest(\"[data-react-fancy-command]\")\n ?.querySelectorAll('[role=\"option\"]');\n if (options) setActiveIndex(Array.from(options).indexOf(e.currentTarget));\n }}\n className={cn(\n \"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm transition-colors\",\n \"text-[color:var(--fancy-text-soft,var(--color-zinc-700))] hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] data-[active]:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:data-[active]:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n onClick={() => {\n onSelect?.();\n close();\n }}\n >\n {children}\n </button>\n );\n}\n\nCommandItem.displayName = \"CommandItem\";\n","import { cn } from \"../../utils/cn\";\nimport type { CommandGroupProps } from \"./Command.types\";\n\nexport function CommandGroup({\n children,\n heading,\n className,\n}: CommandGroupProps) {\n return (\n <div data-react-fancy-command-group=\"\" role=\"group\" className={cn(\"py-1\", className)}>\n {heading && (\n <div className=\"px-3 py-1.5 text-xs font-medium text-zinc-400\">\n {heading}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nCommandGroup.displayName = \"CommandGroup\";\n","import { cn } from \"../../utils/cn\";\nimport type { CommandEmptyProps } from \"./Command.types\";\n\nexport function CommandEmpty({\n children = \"No results found.\",\n className,\n}: CommandEmptyProps) {\n return (\n <div\n data-react-fancy-command-empty=\"\"\n className={cn(\n \"py-6 text-center text-sm text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nCommandEmpty.displayName = \"CommandEmpty\";\n","import {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Portal } from \"../Portal\";\nimport { CommandContext } from \"./Command.context\";\nimport { CommandInput } from \"./CommandInput\";\nimport { CommandList } from \"./CommandList\";\nimport { CommandItem } from \"./CommandItem\";\nimport { CommandGroup } from \"./CommandGroup\";\nimport { CommandEmpty } from \"./CommandEmpty\";\nimport { useFocusTrap } from \"../../hooks/use-focus-trap\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\nimport { useAnimation } from \"../../hooks/use-animation\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport type { CommandProps } from \"./Command.types\";\n\nfunction CommandRoot({\n children,\n open,\n onClose,\n className,\n shouldFilter = true,\n query: controlledQuery,\n onQueryChange,\n}: CommandProps) {\n const [query, setQuery] = useControllableState(controlledQuery, \"\", onQueryChange);\n const [activeIndex, setActiveIndex] = useState(-1);\n const panelRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n\n const close = useCallback(() => {\n onClose();\n setQuery(\"\");\n setActiveIndex(-1);\n }, [onClose]);\n\n useEscapeKey(close, open);\n useFocusTrap(panelRef, open);\n\n // Cmd+K global shortcut is handled by the consumer\n useEffect(() => {\n if (open) {\n const original = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = original;\n };\n }\n }, [open]);\n\n /*\n * Keyboard navigation, as a combobox: the arrows move the ACTIVE item while\n * focus stays in the input (announced through aria-activedescendant), and\n * Enter picks the active item — or the first visible one when none is active.\n *\n * Focus used to move onto the items, and Enter was handled nowhere, so typing\n * a query and pressing Enter did nothing: only a focused item took Enter, as a\n * native click. Found by Genie 2's real-window test.\n */\n useEffect(() => {\n if (!open) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const items = panelRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"option\"]',\n );\n if (!items?.length) return;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex(activeIndex < items.length - 1 ? activeIndex + 1 : 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex(activeIndex > 0 ? activeIndex - 1 : items.length - 1);\n } else if (e.key === \"Enter\") {\n // A focused item takes Enter natively, as a click; picking here as well\n // would select it twice.\n if ((e.target as HTMLElement | null)?.getAttribute(\"role\") === \"option\") return;\n const pick = items[activeIndex] ?? items[0];\n e.preventDefault();\n pick.click();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, activeIndex]);\n\n /*\n * Mark the active item and point the input at it. Done on the DOM after each\n * render because an item cannot know its own index — that is its position\n * among the options currently rendered, which filtering changes.\n */\n useLayoutEffect(() => {\n const panel = panelRef.current;\n if (!panel) return;\n\n const items = Array.from(panel.querySelectorAll<HTMLElement>('[role=\"option\"]'));\n const active = items[activeIndex];\n items.forEach((item) => {\n const on = item === active;\n item.setAttribute(\"aria-selected\", on ? \"true\" : \"false\");\n if (on) item.setAttribute(\"data-active\", \"\");\n else item.removeAttribute(\"data-active\");\n });\n\n const input = panel.querySelector<HTMLInputElement>(\"[data-react-fancy-command-input] input\");\n if (active?.id) input?.setAttribute(\"aria-activedescendant\", active.id);\n else input?.removeAttribute(\"aria-activedescendant\");\n active?.scrollIntoView?.({ block: \"nearest\" });\n });\n\n // A new query is a new list: nothing in it is active yet, so Enter picks the first match.\n const changeQuery = useCallback(\n (next: string) => {\n setQuery(next);\n setActiveIndex(-1);\n },\n [setQuery],\n );\n\n const { mounted, className: animClass, ref: animRef } = useAnimation({\n open,\n enterClass: \"fancy-slide-up\",\n exitClass: \"fancy-fade-out\",\n });\n\n const ctx = useMemo(\n () => ({\n open,\n close,\n query,\n setQuery: changeQuery,\n activeIndex,\n setActiveIndex,\n shouldFilter,\n listId,\n }),\n [open, close, query, changeQuery, activeIndex, shouldFilter, listId],\n );\n\n if (!mounted) return null;\n\n return (\n <CommandContext.Provider value={ctx}>\n <Portal>\n <div className=\"fixed inset-0 z-50 flex items-start justify-center pt-[20vh]\">\n <div\n className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\"\n onClick={close}\n aria-hidden=\"true\"\n />\n <div\n ref={(node) => {\n panelRef.current = node;\n (animRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n }}\n data-react-fancy-command=\"\"\n className={cn(\n \"relative w-full max-w-lg overflow-hidden rounded-2xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] shadow-2xl dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n animClass,\n className,\n )}\n >\n {children}\n </div>\n </div>\n </Portal>\n </CommandContext.Provider>\n );\n}\n\nexport const Command = Object.assign(CommandRoot, {\n Input: CommandInput,\n List: CommandList,\n Item: CommandItem,\n Group: CommandGroup,\n Empty: CommandEmpty,\n});\n"]}
1
+ {"version":3,"sources":["../src/components/Command/Command.context.ts","../src/components/Command/CommandInput.tsx","../src/components/Command/CommandList.tsx","../src/components/Command/CommandItem.tsx","../src/components/Command/CommandGroup.tsx","../src/components/Command/CommandEmpty.tsx","../src/components/Command/Command.tsx"],"names":["createContext","useContext","jsxs","jsx","Search","cn","useId","useControllableState","useState","useRef","useCallback","useEscapeKey","useFocusTrap","useEffect","useLayoutEffect","useAnimation","useMemo","Portal"],"mappings":"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","file":"chunk-UJRMY54A.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { CommandContextValue } from \"./Command.types\";\n\nexport const CommandContext = createContext<CommandContextValue | null>(null);\n\nexport function useCommand(): CommandContextValue {\n const ctx = useContext(CommandContext);\n if (!ctx) {\n throw new Error(\n \"Command compound components must be used within <Command>\",\n );\n }\n return ctx;\n}\n","import { Search } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useCommand } from \"./Command.context\";\nimport type { CommandInputProps } from \"./Command.types\";\n\nexport function CommandInput({\n placeholder = \"Type a command or search...\",\n className,\n}: CommandInputProps) {\n const { query, setQuery, listId } = useCommand();\n\n return (\n <div data-react-fancy-command-input=\"\" className=\"flex items-center border-b border-[color:var(--fancy-border,var(--color-zinc-200))] px-4 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\">\n <Search size={16} className=\"shrink-0 text-zinc-400\" />\n <input\n type=\"text\"\n // A combobox: focus stays here while the arrows move the active option,\n // which Command announces through aria-activedescendant.\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={placeholder}\n className={cn(\n \"flex-1 bg-transparent px-3 py-3 text-sm outline-none placeholder:text-zinc-400\",\n className,\n )}\n autoFocus\n />\n </div>\n );\n}\n\nCommandInput.displayName = \"CommandInput\";\n","import { cn } from \"../../utils/cn\";\nimport { useCommand } from \"./Command.context\";\nimport type { CommandListProps } from \"./Command.types\";\n\nexport function CommandList({ children, className }: CommandListProps) {\n const { listId } = useCommand();\n\n return (\n <div\n id={listId}\n data-react-fancy-command-list=\"\"\n role=\"listbox\"\n className={cn(\"max-h-72 overflow-y-auto p-2\", className)}\n >\n {children}\n </div>\n );\n}\n\nCommandList.displayName = \"CommandList\";\n","import { useId } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useCommand } from \"./Command.context\";\nimport type { CommandItemProps } from \"./Command.types\";\n\nexport function CommandItem({\n children,\n value,\n onSelect,\n className,\n}: CommandItemProps) {\n const { query, close, shouldFilter, setActiveIndex } = useCommand();\n // Called before the filter's early return, so the hook order never changes.\n const id = useId();\n\n // Filter by query — unless the caller filters for itself (`shouldFilter={false}`).\n const text = value ?? (typeof children === \"string\" ? children : \"\");\n if (shouldFilter && query && !text.toLowerCase().includes(query.toLowerCase())) {\n return null;\n }\n\n return (\n <button\n id={id}\n data-react-fancy-command-item=\"\"\n type=\"button\"\n role=\"option\"\n // Marked active by Command itself (aria-selected + data-active), since an\n // item cannot know its own position among the rendered options.\n aria-selected={false}\n // Keyboard focus stays in the input; the items are reached with the arrows.\n tabIndex={-1}\n onMouseEnter={(e) => {\n const options = e.currentTarget\n .closest(\"[data-react-fancy-command]\")\n ?.querySelectorAll('[role=\"option\"]');\n if (options) setActiveIndex(Array.from(options).indexOf(e.currentTarget));\n }}\n className={cn(\n \"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm transition-colors\",\n \"text-[color:var(--fancy-text-soft,var(--color-zinc-700))] hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] data-[active]:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))] dark:data-[active]:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n onClick={() => {\n onSelect?.();\n close();\n }}\n >\n {children}\n </button>\n );\n}\n\nCommandItem.displayName = \"CommandItem\";\n","import { cn } from \"../../utils/cn\";\nimport type { CommandGroupProps } from \"./Command.types\";\n\nexport function CommandGroup({\n children,\n heading,\n className,\n}: CommandGroupProps) {\n return (\n <div data-react-fancy-command-group=\"\" role=\"group\" className={cn(\"py-1\", className)}>\n {heading && (\n <div className=\"px-3 py-1.5 text-xs font-medium text-zinc-400\">\n {heading}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nCommandGroup.displayName = \"CommandGroup\";\n","import { cn } from \"../../utils/cn\";\nimport type { CommandEmptyProps } from \"./Command.types\";\n\nexport function CommandEmpty({\n children = \"No results found.\",\n className,\n}: CommandEmptyProps) {\n return (\n <div\n data-react-fancy-command-empty=\"\"\n className={cn(\n \"py-6 text-center text-sm text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nCommandEmpty.displayName = \"CommandEmpty\";\n","import {\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Portal } from \"../Portal\";\nimport { CommandContext } from \"./Command.context\";\nimport { CommandInput } from \"./CommandInput\";\nimport { CommandList } from \"./CommandList\";\nimport { CommandItem } from \"./CommandItem\";\nimport { CommandGroup } from \"./CommandGroup\";\nimport { CommandEmpty } from \"./CommandEmpty\";\nimport { useFocusTrap } from \"../../hooks/use-focus-trap\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\nimport { useAnimation } from \"../../hooks/use-animation\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport type { CommandProps } from \"./Command.types\";\n\nfunction CommandRoot({\n children,\n open,\n onClose,\n className,\n shouldFilter = true,\n query: controlledQuery,\n onQueryChange,\n}: CommandProps) {\n const [query, setQuery] = useControllableState(controlledQuery, \"\", onQueryChange);\n const [activeIndex, setActiveIndex] = useState(-1);\n const panelRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n\n const close = useCallback(() => {\n onClose();\n setQuery(\"\");\n setActiveIndex(-1);\n }, [onClose]);\n\n useEscapeKey(close, open);\n useFocusTrap(panelRef, open);\n\n // Cmd+K global shortcut is handled by the consumer\n useEffect(() => {\n if (open) {\n const original = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = original;\n };\n }\n }, [open]);\n\n /*\n * Keyboard navigation, as a combobox: the arrows move the ACTIVE item while\n * focus stays in the input (announced through aria-activedescendant), and\n * Enter picks the active item — or the first visible one when none is active.\n *\n * Focus used to move onto the items, and Enter was handled nowhere, so typing\n * a query and pressing Enter did nothing: only a focused item took Enter, as a\n * native click. Found by Genie 2's real-window test.\n */\n useEffect(() => {\n if (!open) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const items = panelRef.current?.querySelectorAll<HTMLElement>(\n '[role=\"option\"]',\n );\n if (!items?.length) return;\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex(activeIndex < items.length - 1 ? activeIndex + 1 : 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex(activeIndex > 0 ? activeIndex - 1 : items.length - 1);\n } else if (e.key === \"Enter\") {\n // A focused item takes Enter natively, as a click; picking here as well\n // would select it twice.\n if ((e.target as HTMLElement | null)?.getAttribute(\"role\") === \"option\") return;\n const pick = items[activeIndex] ?? items[0];\n e.preventDefault();\n pick.click();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, activeIndex]);\n\n /*\n * Mark the active item and point the input at it. Done on the DOM after each\n * render because an item cannot know its own index — that is its position\n * among the options currently rendered, which filtering changes.\n */\n useLayoutEffect(() => {\n const panel = panelRef.current;\n if (!panel) return;\n\n const items = Array.from(panel.querySelectorAll<HTMLElement>('[role=\"option\"]'));\n const active = items[activeIndex];\n items.forEach((item) => {\n const on = item === active;\n item.setAttribute(\"aria-selected\", on ? \"true\" : \"false\");\n if (on) item.setAttribute(\"data-active\", \"\");\n else item.removeAttribute(\"data-active\");\n });\n\n const input = panel.querySelector<HTMLInputElement>(\"[data-react-fancy-command-input] input\");\n if (active?.id) input?.setAttribute(\"aria-activedescendant\", active.id);\n else input?.removeAttribute(\"aria-activedescendant\");\n active?.scrollIntoView?.({ block: \"nearest\" });\n });\n\n // A new query is a new list: nothing in it is active yet, so Enter picks the first match.\n const changeQuery = useCallback(\n (next: string) => {\n setQuery(next);\n setActiveIndex(-1);\n },\n [setQuery],\n );\n\n const { mounted, className: animClass, ref: animRef } = useAnimation({\n open,\n enterClass: \"fancy-slide-up\",\n exitClass: \"fancy-fade-out\",\n });\n\n const ctx = useMemo(\n () => ({\n open,\n close,\n query,\n setQuery: changeQuery,\n activeIndex,\n setActiveIndex,\n shouldFilter,\n listId,\n }),\n [open, close, query, changeQuery, activeIndex, shouldFilter, listId],\n );\n\n if (!mounted) return null;\n\n return (\n <CommandContext.Provider value={ctx}>\n <Portal>\n <div className=\"fixed inset-0 z-50 flex items-start justify-center pt-[20vh]\">\n <div\n className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\"\n onClick={close}\n aria-hidden=\"true\"\n />\n <div\n ref={(node) => {\n panelRef.current = node;\n (animRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n }}\n data-react-fancy-command=\"\"\n className={cn(\n \"relative w-full max-w-lg overflow-hidden rounded-2xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] shadow-2xl dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n animClass,\n className,\n )}\n >\n {children}\n </div>\n </div>\n </Portal>\n </CommandContext.Provider>\n );\n}\n\nexport const Command = Object.assign(CommandRoot, {\n Input: CommandInput,\n List: CommandList,\n Item: CommandItem,\n Group: CommandGroup,\n Empty: CommandEmpty,\n});\n"]}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkTI7D4QDM_cjs = require('./chunk-TI7D4QDM.cjs');
4
+ var chunkOUYC6EIL_cjs = require('./chunk-OUYC6EIL.cjs');
4
5
  var chunkMXWR3T3N_cjs = require('./chunk-MXWR3T3N.cjs');
5
6
  var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
6
7
  var react = require('react');
@@ -11,7 +12,7 @@ function useFullScreenContext() {
11
12
  return react.useContext(FullScreenContext);
12
13
  }
13
14
  function FullScreenProvider({ value, children }) {
14
- return /* @__PURE__ */ jsxRuntime.jsx(FullScreenContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(chunkTI7D4QDM_cjs.PortalContainerContext.Provider, { value: value.portalContainer, children }) });
15
+ return /* @__PURE__ */ jsxRuntime.jsx(FullScreenContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(chunkOUYC6EIL_cjs.EscapeLayerContext.Provider, { value: value.escapeScope, children: /* @__PURE__ */ jsxRuntime.jsx(chunkTI7D4QDM_cjs.PortalContainerContext.Provider, { value: value.portalContainer, children }) }) });
15
16
  }
16
17
  function FullScreenToggle({
17
18
  enterIcon = "maximize-2",
@@ -30,6 +31,10 @@ function FullScreenToggle({
30
31
  ...fs.toggleProps,
31
32
  className: chunkZU5Q77OT_cjs.cn(
32
33
  "inline-flex h-8 w-8 items-center justify-center rounded-md text-sm transition-colors",
34
+ // Its own text colour, like the kit's other icon buttons. Inheriting
35
+ // left it black on a dark toolbar whenever the page's colour was dark
36
+ // text. Plain utilities, so a consumer's `text-*` replaces them.
37
+ "text-[color:var(--fancy-text-muted,var(--color-zinc-500))] hover:text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))] dark:hover:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]",
33
38
  "hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]",
34
39
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-brand,var(--color-blue-500))]",
35
40
  className
@@ -44,5 +49,5 @@ exports.FullScreenContext = FullScreenContext;
44
49
  exports.FullScreenProvider = FullScreenProvider;
45
50
  exports.FullScreenToggle = FullScreenToggle;
46
51
  exports.useFullScreenContext = useFullScreenContext;
47
- //# sourceMappingURL=chunk-ZPBCZPMD.cjs.map
48
- //# sourceMappingURL=chunk-ZPBCZPMD.cjs.map
52
+ //# sourceMappingURL=chunk-VQJ5LJJH.cjs.map
53
+ //# sourceMappingURL=chunk-VQJ5LJJH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/FullScreen/FullScreen.context.tsx","../src/components/FullScreen/FullScreenToggle.tsx"],"names":["createContext","useContext","jsx","EscapeLayerContext","PortalContainerContext","Icon","cn"],"mappings":";;;;;;;;;AAKO,IAAM,iBAAA,GAAoBA,oBAA0C,IAAI;AAGxE,SAAS,oBAAA,GAAmD;AACjE,EAAA,OAAOC,iBAAW,iBAAiB,CAAA;AACrC;AAgBO,SAAS,kBAAA,CAAmB,EAAE,KAAA,EAAO,QAAA,EAAS,EAA4B;AAC/E,EAAA,uBACEC,cAAA,CAAC,kBAAkB,QAAA,EAAlB,EAA2B,OAC1B,QAAA,kBAAAA,cAAA,CAACC,oCAAA,CAAmB,UAAnB,EAA4B,KAAA,EAAO,MAAM,WAAA,EACxC,QAAA,kBAAAD,cAAA,CAACE,yCAAuB,QAAA,EAAvB,EAAgC,OAAO,KAAA,CAAM,eAAA,EAAkB,QAAA,EAAS,CAAA,EAC3E,CAAA,EACF,CAAA;AAEJ;ACfO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,SAAA,GAAY,YAAA;AAAA,EACZ,QAAA,GAAW,YAAA;AAAA,EACX,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA0B;AACxB,EAAA,MAAM,KAAK,oBAAA,EAAqB;AAChC,EAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAEhB,EAAA,MAAM,UACJ,OAAO,QAAA,KAAa,aAChB,QAAA,CAAS,EAAA,CAAG,UAAU,CAAA,GACtB,QAAA,oBAAYF,cAAAA,CAACG,0BAAK,IAAA,EAAM,EAAA,CAAG,aAAa,QAAA,GAAW,SAAA,EAAW,MAAK,IAAA,EAAK,CAAA;AAE9E,EAAA,uBACEH,cAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAG,EAAA,CAAG,WAAA;AAAA,MACP,SAAA,EAAWI,oBAAA;AAAA,QACT,sFAAA;AAAA;AAAA;AAAA;AAAA,QAIA,2QAAA;AAAA,QACA,+IAAA;AAAA,QACA,+HAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ;AAEA,gBAAA,CAAiB,WAAA,GAAc,kBAAA","file":"chunk-VQJ5LJJH.cjs","sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\nimport { PortalContainerContext } from \"../Portal/Portal\";\nimport { EscapeLayerContext } from \"../../hooks/use-escape-key\";\nimport type { UseFullScreenResult } from \"../../hooks/use-full-screen\";\n\nexport const FullScreenContext = createContext<UseFullScreenResult | null>(null);\n\n/** The nearest full-screen surface's state, or `null` outside one. */\nexport function useFullScreenContext(): UseFullScreenResult | null {\n return useContext(FullScreenContext);\n}\n\nexport interface FullScreenProviderProps {\n /** What `useFullScreen()` returned for the surface. */\n value: UseFullScreenResult<HTMLElement> | UseFullScreenResult<HTMLDivElement>;\n children?: ReactNode;\n}\n\n/**\n * For a surface that owns its root and calls `useFullScreen()` itself (Editor,\n * DeckEditor, SheetWorkbook). Makes `<FullScreen.Toggle />` work anywhere inside\n * and redirects descendant `<Portal>`s into the surface while it is active.\n * It also marks everything inside as belonging to this surface for Escape, so\n * an open menu, listbox, popover or tooltip inside closes before the surface\n * exits. A surface that skips the provider loses that, as well as the portals.\n */\nexport function FullScreenProvider({ value, children }: FullScreenProviderProps) {\n return (\n <FullScreenContext.Provider value={value as UseFullScreenResult}>\n <EscapeLayerContext.Provider value={value.escapeScope}>\n <PortalContainerContext.Provider value={value.portalContainer}>{children}</PortalContainerContext.Provider>\n </EscapeLayerContext.Provider>\n </FullScreenContext.Provider>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Icon } from \"../Icon\";\nimport { useFullScreenContext } from \"./FullScreen.context\";\n\nexport interface FullScreenToggleProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\" | \"onClick\" | \"children\"> {\n /** Lucide name shown while NOT full screen. @default \"maximize-2\" */\n enterIcon?: string;\n /** Lucide name shown while full screen. @default \"minimize-2\" */\n exitIcon?: string;\n /** Replace the icon entirely. Receives the current state. */\n children?: ReactNode | ((fullScreen: boolean) => ReactNode);\n}\n\n/**\n * The toggle for the nearest `<FullScreen>` / `<FullScreenProvider>`. Renders\n * nothing outside one, so a shared toolbar can include it unconditionally.\n */\nexport function FullScreenToggle({\n enterIcon = \"maximize-2\",\n exitIcon = \"minimize-2\",\n children,\n className,\n ...rest\n}: FullScreenToggleProps) {\n const fs = useFullScreenContext();\n if (!fs) return null;\n\n const content =\n typeof children === \"function\"\n ? children(fs.fullScreen)\n : children ?? <Icon name={fs.fullScreen ? exitIcon : enterIcon} size=\"sm\" />;\n\n return (\n <button\n {...rest}\n {...fs.toggleProps}\n className={cn(\n \"inline-flex h-8 w-8 items-center justify-center rounded-md text-sm transition-colors\",\n // Its own text colour, like the kit's other icon buttons. Inheriting\n // left it black on a dark toolbar whenever the page's colour was dark\n // text. Plain utilities, so a consumer's `text-*` replaces them.\n \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] hover:text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))] dark:hover:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]\",\n \"hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-brand,var(--color-blue-500))]\",\n className,\n )}\n >\n {content}\n </button>\n );\n}\n\nFullScreenToggle.displayName = \"FullScreenToggle\";\n"]}
@@ -3,7 +3,7 @@ import { useFieldMode } from './chunk-NRXK42LO.js';
3
3
  import { useFloatingPosition } from './chunk-MQ6VGG62.js';
4
4
  import { Portal } from './chunk-RBCMKPBX.js';
5
5
  import { useOutsideClick } from './chunk-RGANGU7X.js';
6
- import { useEscapeKey } from './chunk-JXE5XID6.js';
6
+ import { useEscapeKey } from './chunk-YX6FTJ6N.js';
7
7
  import { useControllableState } from './chunk-EDYAXGUM.js';
8
8
  import { cn } from './chunk-MMW2JGKZ.js';
9
9
  import { forwardRef, useState, useRef, useCallback, useEffect } from 'react';
@@ -196,5 +196,5 @@ function HighlightMatch({ text, query }) {
196
196
  Autocomplete.displayName = "Autocomplete";
197
197
 
198
198
  export { Autocomplete };
199
- //# sourceMappingURL=chunk-MSGKIWYX.js.map
200
- //# sourceMappingURL=chunk-MSGKIWYX.js.map
199
+ //# sourceMappingURL=chunk-VZNBTCGA.js.map
200
+ //# sourceMappingURL=chunk-VZNBTCGA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Autocomplete/Autocomplete.tsx"],"names":["Autocomplete"],"mappings":"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","file":"chunk-MSGKIWYX.js","sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Portal } from \"../Portal\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport { useFloatingPosition } from \"../../hooks/use-floating-position\";\nimport { useOutsideClick } from \"../../hooks/use-outside-click\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\nimport { useFieldMode } from \"../inputs/mode/FieldMode.context\";\nimport { useInlineEdit } from \"../inputs/mode/useInlineEdit\";\nimport type { AutocompleteProps } from \"./Autocomplete.types\";\n\nexport const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(\n function Autocomplete(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSearch,\n options,\n placeholder,\n loading = false,\n emptyMessage = \"No results found.\",\n disabled = false,\n className,\n mode,\n },\n ref,\n ) {\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n const [query, setQuery] = useState(value);\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n\n const anchorRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n const position = useFloatingPosition(anchorRef, listRef, {\n placement: \"bottom-start\",\n offset: 4,\n enabled: open,\n });\n\n const close = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n }, []);\n\n useOutsideClick(wrapperRef, close, open);\n useEscapeKey(close, open);\n\n const filtered = options.filter((o) =>\n o.label.toLowerCase().includes(query.toLowerCase()),\n );\n\n const select = useCallback(\n (val: string) => {\n setValue(val);\n const opt = options.find((o) => o.value === val);\n setQuery(opt?.label ?? val);\n close();\n },\n [setValue, options, close],\n );\n\n useEffect(() => {\n onSearch?.(query);\n }, [query, onSearch]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!open) {\n if (e.key === \"ArrowDown\") {\n setOpen(true);\n return;\n }\n return;\n }\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => Math.max(i - 1, 0));\n } else if (e.key === \"Enter\" && activeIndex >= 0) {\n e.preventDefault();\n const item = filtered[activeIndex];\n if (item && !item.disabled) select(item.value);\n }\n };\n\n if (!showControl) {\n const matched = options.find((o) => o.value === value);\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n data-mode=\"view\"\n ref={wrapperRef}\n role={interactive ? \"button\" : undefined}\n tabIndex={interactive ? 0 : undefined}\n title={interactive ? \"Click to edit\" : undefined}\n onClick={interactive ? enterEdit : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n enterEdit();\n }\n }\n : undefined\n }\n className={cn(\n \"text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n !value && \"text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\",\n interactive &&\n \"cursor-pointer rounded-md outline-none transition-colors hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n >\n {matched?.label ?? value ?? \"—\"}\n </div>\n );\n }\n\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n ref={wrapperRef}\n className={cn(\"relative\", className)}\n onBlur={(e) => {\n // Options live in a Portal; only exit when closed and focus left.\n if (interactive && !open && !e.currentTarget.contains(e.relatedTarget as Node)) {\n exitEdit();\n }\n }}\n >\n <input\n ref={(node) => {\n (anchorRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }}\n type=\"text\"\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n setActiveIndex(-1);\n }}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={interactive}\n role=\"combobox\"\n aria-expanded={open}\n aria-autocomplete=\"list\"\n className=\"w-full rounded-lg border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-input,var(--color-white))] px-3 py-2 text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] placeholder:text-[color:var(--fancy-text-faint,var(--color-zinc-400))] outline-none transition-[border-color,box-shadow] duration-150 focus:border-[color:var(--fancy-focus,var(--color-blue-500))] focus:ring-2 focus:ring-[color:var(--fancy-focus,var(--color-blue-500))]/40 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-input-dark,#1e1e24)] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))] dark:placeholder:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:focus:border-[color:var(--fancy-focus-dark,var(--color-blue-400))] dark:focus:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))]/20\"\n />\n {open && (\n <Portal>\n <div\n ref={listRef}\n role=\"listbox\"\n className=\"fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-1 shadow-lg dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:shadow-zinc-950/50 fancy-scale-in\"\n style={{\n left: position.x,\n top: position.y,\n width: anchorRef.current?.offsetWidth,\n }}\n >\n {loading ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">Loading...</div>\n ) : filtered.length === 0 ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">\n {emptyMessage}\n </div>\n ) : (\n filtered.map((option, i) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"option\"\n aria-selected={i === activeIndex}\n disabled={option.disabled}\n onClick={() => select(option.value)}\n className={cn(\n \"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-zinc-700 transition-colors dark:text-zinc-200\",\n i === activeIndex\n ? \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n : \"hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))]\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <HighlightMatch text={option.label} query={query} />\n </button>\n ))\n )}\n </div>\n </Portal>\n )}\n </div>\n );\n },\n);\n\nfunction HighlightMatch({ text, query }: { text: string; query: string }) {\n if (!query) return <>{text}</>;\n\n const idx = text.toLowerCase().indexOf(query.toLowerCase());\n if (idx === -1) return <>{text}</>;\n\n return (\n <>\n {text.slice(0, idx)}\n <span className=\"font-semibold text-zinc-900 dark:text-white\">\n {text.slice(idx, idx + query.length)}\n </span>\n {text.slice(idx + query.length)}\n </>\n );\n}\n\nAutocomplete.displayName = \"Autocomplete\";\n"]}
1
+ {"version":3,"sources":["../src/components/Autocomplete/Autocomplete.tsx"],"names":["Autocomplete"],"mappings":"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","file":"chunk-VZNBTCGA.js","sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Portal } from \"../Portal\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport { useFloatingPosition } from \"../../hooks/use-floating-position\";\nimport { useOutsideClick } from \"../../hooks/use-outside-click\";\nimport { useEscapeKey } from \"../../hooks/use-escape-key\";\nimport { useFieldMode } from \"../inputs/mode/FieldMode.context\";\nimport { useInlineEdit } from \"../inputs/mode/useInlineEdit\";\nimport type { AutocompleteProps } from \"./Autocomplete.types\";\n\nexport const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(\n function Autocomplete(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSearch,\n options,\n placeholder,\n loading = false,\n emptyMessage = \"No results found.\",\n disabled = false,\n className,\n mode,\n },\n ref,\n ) {\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n const [query, setQuery] = useState(value);\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n\n const anchorRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n const position = useFloatingPosition(anchorRef, listRef, {\n placement: \"bottom-start\",\n offset: 4,\n enabled: open,\n });\n\n const close = useCallback(() => {\n setOpen(false);\n setActiveIndex(-1);\n }, []);\n\n useOutsideClick(wrapperRef, close, open);\n useEscapeKey(close, open);\n\n const filtered = options.filter((o) =>\n o.label.toLowerCase().includes(query.toLowerCase()),\n );\n\n const select = useCallback(\n (val: string) => {\n setValue(val);\n const opt = options.find((o) => o.value === val);\n setQuery(opt?.label ?? val);\n close();\n },\n [setValue, options, close],\n );\n\n useEffect(() => {\n onSearch?.(query);\n }, [query, onSearch]);\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (!open) {\n if (e.key === \"ArrowDown\") {\n setOpen(true);\n return;\n }\n return;\n }\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => Math.max(i - 1, 0));\n } else if (e.key === \"Enter\" && activeIndex >= 0) {\n e.preventDefault();\n const item = filtered[activeIndex];\n if (item && !item.disabled) select(item.value);\n }\n };\n\n if (!showControl) {\n const matched = options.find((o) => o.value === value);\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n data-mode=\"view\"\n ref={wrapperRef}\n role={interactive ? \"button\" : undefined}\n tabIndex={interactive ? 0 : undefined}\n title={interactive ? \"Click to edit\" : undefined}\n onClick={interactive ? enterEdit : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n enterEdit();\n }\n }\n : undefined\n }\n className={cn(\n \"text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\",\n !value && \"text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\",\n interactive &&\n \"cursor-pointer rounded-md outline-none transition-colors hover:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n className,\n )}\n >\n {matched?.label ?? value ?? \"—\"}\n </div>\n );\n }\n\n return (\n <div\n data-react-fancy-autocomplete=\"\"\n ref={wrapperRef}\n className={cn(\"relative\", className)}\n onBlur={(e) => {\n // Options live in a Portal; only exit when closed and focus left.\n if (interactive && !open && !e.currentTarget.contains(e.relatedTarget as Node)) {\n exitEdit();\n }\n }}\n >\n <input\n ref={(node) => {\n (anchorRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }}\n type=\"text\"\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n setActiveIndex(-1);\n }}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={interactive}\n role=\"combobox\"\n aria-expanded={open}\n aria-autocomplete=\"list\"\n className=\"w-full rounded-lg border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-input,var(--color-white))] px-3 py-2 text-sm text-[color:var(--fancy-text,var(--color-zinc-900))] placeholder:text-[color:var(--fancy-text-faint,var(--color-zinc-400))] outline-none transition-[border-color,box-shadow] duration-150 focus:border-[color:var(--fancy-focus,var(--color-blue-500))] focus:ring-2 focus:ring-[color:var(--fancy-focus,var(--color-blue-500))]/40 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-input-dark,#1e1e24)] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))] dark:placeholder:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:focus:border-[color:var(--fancy-focus-dark,var(--color-blue-400))] dark:focus:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))]/20\"\n />\n {open && (\n <Portal>\n <div\n ref={listRef}\n role=\"listbox\"\n className=\"fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-1 shadow-lg dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))] dark:shadow-zinc-950/50 fancy-scale-in\"\n style={{\n left: position.x,\n top: position.y,\n width: anchorRef.current?.offsetWidth,\n }}\n >\n {loading ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">Loading...</div>\n ) : filtered.length === 0 ? (\n <div className=\"px-3 py-2 text-sm text-zinc-400\">\n {emptyMessage}\n </div>\n ) : (\n filtered.map((option, i) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"option\"\n aria-selected={i === activeIndex}\n disabled={option.disabled}\n onClick={() => select(option.value)}\n className={cn(\n \"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-zinc-700 transition-colors dark:text-zinc-200\",\n i === activeIndex\n ? \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\"\n : \"hover:bg-[color:var(--fancy-surface-hover,var(--color-zinc-50))] dark:hover:bg-[color:var(--fancy-surface-hover-dark,color-mix(in_oklab,var(--color-zinc-800)_50%,transparent))]\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <HighlightMatch text={option.label} query={query} />\n </button>\n ))\n )}\n </div>\n </Portal>\n )}\n </div>\n );\n },\n);\n\nfunction HighlightMatch({ text, query }: { text: string; query: string }) {\n if (!query) return <>{text}</>;\n\n const idx = text.toLowerCase().indexOf(query.toLowerCase());\n if (idx === -1) return <>{text}</>;\n\n return (\n <>\n {text.slice(0, idx)}\n <span className=\"font-semibold text-zinc-900 dark:text-white\">\n {text.slice(idx, idx + query.length)}\n </span>\n {text.slice(idx + query.length)}\n </>\n );\n}\n\nAutocomplete.displayName = \"Autocomplete\";\n"]}
@@ -9,7 +9,7 @@ var chunkL3V3BYVS_cjs = require('./chunk-L3V3BYVS.cjs');
9
9
  var chunkJ2DI6RMR_cjs = require('./chunk-J2DI6RMR.cjs');
10
10
  var chunkTI7D4QDM_cjs = require('./chunk-TI7D4QDM.cjs');
11
11
  var chunk57FQGQJK_cjs = require('./chunk-57FQGQJK.cjs');
12
- var chunkRXDRYWVD_cjs = require('./chunk-RXDRYWVD.cjs');
12
+ var chunkOUYC6EIL_cjs = require('./chunk-OUYC6EIL.cjs');
13
13
  var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
14
14
  var react = require('react');
15
15
  var jsxRuntime = require('react/jsx-runtime');
@@ -236,7 +236,7 @@ var ListboxSelect = react.forwardRef(
236
236
  setActiveIndex(-1);
237
237
  }, []);
238
238
  chunk57FQGQJK_cjs.useOutsideClick(listRef, close, open, anchorRef);
239
- chunkRXDRYWVD_cjs.useEscapeKey(close, open);
239
+ chunkOUYC6EIL_cjs.useEscapeKey(close, open);
240
240
  react.useEffect(() => {
241
241
  if (open && textInputEnabled) {
242
242
  requestAnimationFrame(() => searchRef.current?.focus());
@@ -526,5 +526,5 @@ var Select = react.forwardRef(
526
526
  Select.displayName = "Select";
527
527
 
528
528
  exports.Select = Select;
529
- //# sourceMappingURL=chunk-M6MGQI6G.cjs.map
530
- //# sourceMappingURL=chunk-M6MGQI6G.cjs.map
529
+ //# sourceMappingURL=chunk-WKPBCB67.cjs.map
530
+ //# sourceMappingURL=chunk-WKPBCB67.cjs.map