@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 +0,0 @@
1
- {"version":3,"sources":["../src/components/Kanban/Kanban.context.ts","../src/components/Kanban/KanbanCard.tsx","../src/components/Kanban/KanbanColumn.tsx","../src/components/Kanban/KanbanColumnHandle.tsx","../src/components/Kanban/Kanban.tsx"],"names":["createContext","useContext","useCallback","jsx","cn","Children","isValidElement","useState","useRef","useEffect","jsxs","useMemo"],"mappings":"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","file":"chunk-IEQK3LGI.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { KanbanContextValue } from \"./Kanban.types\";\n\nexport const KanbanContext = createContext<KanbanContextValue | null>(null);\n\nexport function useKanban(): KanbanContextValue {\n const ctx = useContext(KanbanContext);\n if (!ctx) {\n throw new Error(\"Kanban compound components must be used within <Kanban>\");\n }\n return ctx;\n}\n\nexport const KanbanColumnContext = createContext<string>(\"\");\n\nexport function useKanbanColumn(): string {\n return useContext(KanbanColumnContext);\n}\n","import { useCallback } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useKanban, useKanbanColumn } from \"./Kanban.context\";\nimport type { KanbanCardProps } from \"./Kanban.types\";\n\nconst DEFAULT_CARD_CLASSES =\n \"rounded-lg border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] p-3 shadow-sm transition-shadow hover:shadow-md dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\";\n\nexport function KanbanCard({ children, id, className, unstyled }: KanbanCardProps) {\n const { setDraggedCard, setDragSource } = useKanban();\n const columnId = useKanbanColumn();\n\n const handleDragStart = useCallback(() => {\n setDraggedCard(id);\n setDragSource(columnId);\n }, [id, columnId, setDraggedCard, setDragSource]);\n\n const handleDragEnd = useCallback(() => {\n setDraggedCard(null);\n setDragSource(null);\n }, [setDraggedCard, setDragSource]);\n\n return (\n <div\n data-react-fancy-kanban-card=\"\"\n draggable\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n className={cn(\n // Drag affordance — kept even when unstyled so users still see grab cursors.\n \"cursor-grab active:cursor-grabbing\",\n !unstyled && DEFAULT_CARD_CLASSES,\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nKanbanCard.displayName = \"KanbanCard\";\n","import { Children, isValidElement, useCallback, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { KanbanCard } from \"./KanbanCard\";\nimport { useKanban, KanbanColumnContext } from \"./Kanban.context\";\nimport type { KanbanColumnProps } from \"./Kanban.types\";\n\nconst DEFAULT_COLUMN_CLASSES =\n \"min-h-[200px] w-72 rounded-xl bg-zinc-50 p-3 dark:bg-zinc-800/50\";\n\n/**\n * Deep-recurse through the children tree counting Kanban.Card descendants\n * regardless of wrapping (Fragment, ContextMenu, motion.div, custom HOCs,\n * etc.). Used by `hideWhenEmpty` and the WIP-limit count chip.\n */\nfunction countCardChildren(children: React.ReactNode): number {\n let n = 0;\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (child.type === KanbanCard) {\n n += 1;\n return;\n }\n const inner = (child.props as { children?: React.ReactNode }).children;\n if (inner !== undefined) n += countCardChildren(inner);\n });\n return n;\n}\n\n/**\n * Find the document-order index of a Kanban.Card with the given id, deep-\n * recursing through wrappers. Used by same-column reorder to compute the\n * post-removal insert position.\n */\nfunction findCardIndex(children: React.ReactNode, cardId: string): number {\n let idx = -1;\n let i = 0;\n function walk(nodes: React.ReactNode): void {\n Children.forEach(nodes, (child) => {\n if (idx !== -1) return;\n if (!isValidElement(child)) return;\n if (child.type === KanbanCard) {\n if ((child.props as { id?: string }).id === cardId) idx = i;\n i += 1;\n return;\n }\n const inner = (child.props as { children?: React.ReactNode }).children;\n if (inner !== undefined) walk(inner);\n });\n }\n walk(children);\n return idx;\n}\n\nexport function KanbanColumn({\n children,\n id,\n title,\n className,\n unstyled,\n wipLimit,\n hideWhenEmpty,\n}: KanbanColumnProps) {\n const { onCardMove, draggedCard, dragSource, registerColumn } = useKanban();\n const [dragOver, setDragOver] = useState(false);\n const [dropIndex, setDropIndex] = useState<number | null>(null);\n const [dropY, setDropY] = useState<number | null>(null);\n const cardsRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => registerColumn(id), [id, registerColumn]);\n\n /**\n * Compute drop position from mouse Y. Walks the *DOM* (not the React\n * tree) and queries `[data-react-fancy-kanban-card]` so wrappers\n * (ContextMenu, custom Card surfaces, motion.div) don't break the\n * indicator placement.\n */\n const updateDrop = useCallback((clientY: number) => {\n const container = cardsRef.current;\n if (!container) {\n setDropIndex(null);\n setDropY(null);\n return;\n }\n\n // Limit to cards belonging to THIS column — important if a card\n // happens to nest a sub-board (rare, but cheap to defend).\n const all = Array.from(\n container.querySelectorAll<HTMLElement>(\n \"[data-react-fancy-kanban-card]\",\n ),\n );\n const cards = all.filter(\n (el) =>\n el.closest(\"[data-react-fancy-kanban-column]\") ===\n cardsRef.current?.closest(\"[data-react-fancy-kanban-column]\"),\n );\n\n const containerRect = container.getBoundingClientRect();\n\n if (cards.length === 0) {\n setDropIndex(0);\n setDropY(0);\n return;\n }\n\n let idx = cards.length;\n let yRel = 0;\n for (let i = 0; i < cards.length; i++) {\n const rect = cards[i]!.getBoundingClientRect();\n if (clientY < rect.top + rect.height / 2) {\n idx = i;\n yRel = rect.top - containerRect.top;\n break;\n }\n }\n if (idx === cards.length) {\n const last = cards[cards.length - 1]!.getBoundingClientRect();\n yRel = last.bottom - containerRect.top;\n }\n\n setDropIndex(idx);\n setDropY(yRel);\n }, []);\n\n const handleDragOver = useCallback(\n (e: React.DragEvent) => {\n // Only react to card drags. Column drags are handled by the root.\n if (!draggedCard) return;\n e.preventDefault();\n e.stopPropagation();\n setDragOver(true);\n updateDrop(e.clientY);\n },\n [draggedCard, updateDrop],\n );\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n if (e.currentTarget.contains(e.relatedTarget as Node | null)) return;\n setDragOver(false);\n setDropIndex(null);\n setDropY(null);\n }, []);\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n if (!draggedCard) return;\n e.preventDefault();\n e.stopPropagation();\n const target = dropIndex ?? 0;\n\n if (dragSource) {\n let finalIdx = target;\n if (dragSource === id) {\n const srcIdx = findCardIndex(children, draggedCard);\n if (srcIdx !== -1 && target > srcIdx) finalIdx = target - 1;\n if (srcIdx === finalIdx) {\n // No-op\n setDragOver(false);\n setDropIndex(null);\n setDropY(null);\n return;\n }\n }\n onCardMove?.(draggedCard, dragSource, id, finalIdx);\n }\n\n setDragOver(false);\n setDropIndex(null);\n setDropY(null);\n },\n [draggedCard, dragSource, dropIndex, id, onCardMove, children],\n );\n\n const cardCount = countCardChildren(children);\n if (hideWhenEmpty && cardCount === 0 && !draggedCard) return null;\n\n const showIndicator =\n draggedCard !== null &&\n dropIndex !== null &&\n dropY !== null &&\n dragOver;\n\n const overWip = wipLimit !== undefined && cardCount > wipLimit;\n\n return (\n <KanbanColumnContext.Provider value={id}>\n <div\n data-react-fancy-kanban-column=\"\"\n data-column-id={id}\n role=\"group\"\n aria-label={title}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n className={cn(\n \"flex flex-col\",\n !unstyled && DEFAULT_COLUMN_CLASSES,\n dragOver && \"ring-2 ring-blue-400 ring-inset\",\n className,\n )}\n >\n {title && (\n <h3 className=\"mb-3 flex items-center gap-2 text-sm font-semibold text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))]\">\n <span className=\"flex-1\">{title}</span>\n <span\n className={cn(\n \"rounded-full px-1.5 py-0.5 text-[10px] font-semibold\",\n overWip\n ? \"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300\"\n : \"bg-[color:var(--fancy-border,var(--color-zinc-200))] text-[color:var(--fancy-text-soft,var(--color-zinc-700))] dark:bg-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:text-[color:var(--fancy-text-soft-dark,var(--color-zinc-300))]\",\n )}\n >\n {cardCount}\n {wipLimit !== undefined ? `/${wipLimit}` : \"\"}\n </span>\n </h3>\n )}\n\n {/* Cards container — `relative` so the drop indicator overlay\n can position itself in the container's coordinate space.\n Children are rendered untouched so any wrapper hierarchy\n (ContextMenu, motion.div, etc.) keeps working. */}\n <div ref={cardsRef} className=\"relative flex flex-1 flex-col gap-2\">\n {children}\n\n {showIndicator && (\n <div\n data-react-fancy-kanban-drop-indicator=\"\"\n style={{ top: dropY }}\n className=\"pointer-events-none absolute left-0 right-0 h-0.5 -translate-y-1/2 rounded-full bg-blue-500/80 shadow-[0_0_0_3px_rgba(59,130,246,0.15)]\"\n />\n )}\n </div>\n </div>\n </KanbanColumnContext.Provider>\n );\n}\n\nKanbanColumn.displayName = \"KanbanColumn\";\n","import { useCallback } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useKanban, useKanbanColumn } from \"./Kanban.context\";\nimport type { KanbanColumnHandleProps } from \"./Kanban.types\";\n\n/**\n * Drag handle for column reordering.\n *\n * Mount inside a `Kanban.Column` to make that column draggable. The\n * column's parent `Kanban` listens for the drop and surfaces the new\n * position via `onColumnMove`. Without a handle, columns are static.\n *\n * Typically wrapped around the column header so users grab the title\n * to reorder; can also be a small grip icon.\n */\nexport function KanbanColumnHandle({\n children,\n className,\n}: KanbanColumnHandleProps) {\n const { setDraggedColumn } = useKanban();\n const columnId = useKanbanColumn();\n\n const handleDragStart = useCallback(\n (e: React.DragEvent) => {\n // Set a dataTransfer payload so the browser permits the drag — some\n // browsers refuse if dataTransfer is empty.\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", columnId);\n e.stopPropagation();\n setDraggedColumn(columnId);\n },\n [columnId, setDraggedColumn],\n );\n\n const handleDragEnd = useCallback(() => {\n setDraggedColumn(null);\n }, [setDraggedColumn]);\n\n return (\n <div\n draggable\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n data-react-fancy-kanban-column-handle=\"\"\n className={cn(\n \"cursor-grab active:cursor-grabbing select-none\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nKanbanColumnHandle.displayName = \"KanbanColumnHandle\";\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { KanbanContext } from \"./Kanban.context\";\nimport { KanbanColumn } from \"./KanbanColumn\";\nimport { KanbanCard } from \"./KanbanCard\";\nimport { KanbanColumnHandle } from \"./KanbanColumnHandle\";\nimport type { KanbanProps } from \"./Kanban.types\";\n\n/**\n * Kanban board.\n *\n * Compound:\n * <Kanban onCardMove={...} onColumnMove={...}>\n * <Kanban.Column id=\"todo\" wipLimit={4}>\n * <Kanban.ColumnHandle>...header...</Kanban.ColumnHandle> // optional\n * <Kanban.Card id=\"...\">...</Kanban.Card>\n * </Kanban.Column>\n * </Kanban>\n *\n * Cards drag between columns AND within a column. Drop position is\n * computed from mouse Y at hover time and surfaced via the `toIndex`\n * argument on `onCardMove`.\n *\n * Columns drag horizontally to reorder when a `<Kanban.ColumnHandle>`\n * is mounted inside them. The root computes the drop index from\n * mouse X and surfaces it via `onColumnMove`.\n */\nfunction KanbanRoot({\n children,\n onCardMove,\n onColumnMove,\n className,\n}: KanbanProps) {\n const [draggedCard, setDraggedCard] = useState<string | null>(null);\n const [dragSource, setDragSource] = useState<string | null>(null);\n const [draggedColumn, setDraggedColumn] = useState<string | null>(null);\n\n const orderRef = useRef<string[]>([]);\n const [columnIds, setColumnIds] = useState<string[]>([]);\n\n const registerColumn = useCallback((id: string) => {\n if (!orderRef.current.includes(id)) {\n orderRef.current = [...orderRef.current, id];\n setColumnIds(orderRef.current);\n }\n return () => {\n orderRef.current = orderRef.current.filter((x) => x !== id);\n setColumnIds(orderRef.current);\n };\n }, []);\n\n const ctx = useMemo(\n () => ({\n draggedCard,\n setDraggedCard,\n dragSource,\n setDragSource,\n draggedColumn,\n setDraggedColumn,\n onCardMove,\n onColumnMove,\n columnIds,\n registerColumn,\n }),\n [\n draggedCard,\n dragSource,\n draggedColumn,\n onCardMove,\n onColumnMove,\n columnIds,\n registerColumn,\n ],\n );\n\n // ── Column-level drop handling ────────────────────────────────────────\n // Root listens only when a column is being dragged. Drop index is\n // computed from mouse X versus each column's horizontal midpoint.\n const containerRef = useRef<HTMLDivElement>(null);\n\n const handleDragOver = useCallback(\n (e: React.DragEvent) => {\n if (!draggedColumn) return;\n e.preventDefault();\n },\n [draggedColumn],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n if (!draggedColumn || !containerRef.current) return;\n e.preventDefault();\n\n const cols = containerRef.current.querySelectorAll<HTMLElement>(\n '[data-react-fancy-kanban-column]',\n );\n const x = e.clientX;\n let dropIdx = cols.length;\n for (let i = 0; i < cols.length; i++) {\n const rect = cols[i]!.getBoundingClientRect();\n if (x < rect.left + rect.width / 2) {\n dropIdx = i;\n break;\n }\n }\n\n const sourceIdx = columnIds.indexOf(draggedColumn);\n // When moving rightward, dropping at index N visually means landing\n // at N - 1 after the source is removed.\n const finalIdx =\n sourceIdx >= 0 && dropIdx > sourceIdx ? dropIdx - 1 : dropIdx;\n\n if (finalIdx !== sourceIdx) {\n onColumnMove?.(draggedColumn, finalIdx);\n }\n setDraggedColumn(null);\n },\n [draggedColumn, columnIds, onColumnMove],\n );\n\n return (\n <KanbanContext.Provider value={ctx}>\n <div\n ref={containerRef}\n data-react-fancy-kanban=\"\"\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n role=\"application\"\n aria-roledescription=\"kanban board\"\n className={cn(\"flex gap-4 overflow-x-auto p-4\", className)}\n >\n {children}\n </div>\n </KanbanContext.Provider>\n );\n}\n\nexport const Kanban = Object.assign(KanbanRoot, {\n Column: KanbanColumn,\n Card: KanbanCard,\n ColumnHandle: KanbanColumnHandle,\n});\n"]}
@@ -1,19 +0,0 @@
1
- import { useEffect } from 'react';
2
-
3
- // src/hooks/use-escape-key.ts
4
- function useEscapeKey(handler, enabled = true) {
5
- useEffect(() => {
6
- if (!enabled) return;
7
- const listener = (event) => {
8
- if (event.key === "Escape") {
9
- handler();
10
- }
11
- };
12
- document.addEventListener("keydown", listener);
13
- return () => document.removeEventListener("keydown", listener);
14
- }, [handler, enabled]);
15
- }
16
-
17
- export { useEscapeKey };
18
- //# sourceMappingURL=chunk-JXE5XID6.js.map
19
- //# sourceMappingURL=chunk-JXE5XID6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-escape-key.ts"],"names":[],"mappings":";;;AAEO,SAAS,YAAA,CACd,OAAA,EACA,OAAA,GAAmB,IAAA,EACb;AACN,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAyB;AACzC,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,QAAQ,CAAA;AAC7C,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,QAAQ,CAAA;AAAA,EAC/D,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AACvB","file":"chunk-JXE5XID6.js","sourcesContent":["import { useEffect } from \"react\";\n\nexport function useEscapeKey(\n handler: () => void,\n enabled: boolean = true,\n): void {\n useEffect(() => {\n if (!enabled) return;\n\n const listener = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n handler();\n }\n };\n\n document.addEventListener(\"keydown\", listener);\n return () => document.removeEventListener(\"keydown\", listener);\n }, [handler, enabled]);\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Tooltip/Tooltip.tsx"],"names":["forwardRef","Tooltip","useState","useRef","useFloatingPosition","useCallback","useMemo","composeRefs","cloneElement","jsxs","Fragment","Portal","cn","jsx"],"mappings":"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","file":"chunk-QXMQVLRQ.cjs","sourcesContent":["import {\n cloneElement,\n forwardRef,\n useCallback,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { composeRefs } from \"../../utils/compose-refs\";\nimport { Portal } from \"../Portal\";\nimport { useFloatingPosition } from \"../../hooks/use-floating-position\";\nimport type { TooltipProps } from \"./Tooltip.types\";\n\nexport const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(\n function Tooltip(\n { children, content, placement = \"top\", delay = 200, offset = 8, className },\n _ref,\n ) {\n const [open, setOpen] = useState(false);\n const anchorRef = useRef<HTMLElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const position = useFloatingPosition(anchorRef, floatingRef, {\n placement,\n offset,\n enabled: open,\n });\n\n const show = useCallback(() => {\n timeoutRef.current = setTimeout(() => setOpen(true), delay);\n }, [delay]);\n\n const hide = useCallback(() => {\n clearTimeout(timeoutRef.current);\n setOpen(false);\n }, []);\n\n // The trigger is the caller's element, so its own ref and handlers have to\n // survive the clone. Overwriting them broke any child that needs its ref:\n // a <MultiSwitch> measures its thumb from it, and rendered with none.\n // className and every other prop are untouched — cloneElement keeps them.\n const child = children as ReactElement<Record<string, unknown>>;\n const childProps = child.props;\n const childRef = childProps.ref as Ref<HTMLElement> | undefined;\n const triggerRef = useMemo(() => composeRefs(childRef, anchorRef), [childRef]);\n const chain =\n (own: unknown, ours: () => void) =>\n (event: unknown) => {\n if (typeof own === \"function\") own(event);\n ours();\n };\n const trigger = cloneElement(child, {\n ref: triggerRef,\n onMouseEnter: chain(childProps.onMouseEnter, show),\n onMouseLeave: chain(childProps.onMouseLeave, hide),\n onFocus: chain(childProps.onFocus, show),\n onBlur: chain(childProps.onBlur, hide),\n });\n\n return (\n <>\n {trigger}\n {open && (\n <Portal>\n <div\n ref={floatingRef}\n data-react-fancy-tooltip=\"\"\n role=\"tooltip\"\n className={cn(\n \"fancy-fade-in pointer-events-none fixed z-50 max-w-xs rounded-lg bg-zinc-900 px-3 py-1.5 text-sm text-white shadow-lg dark:bg-zinc-700 dark:text-zinc-100\",\n className,\n )}\n style={{ left: position.x, top: position.y }}\n >\n {content}\n <div\n className={cn(\n // `bg-inherit`, not a colour of its own: a `className` that\n // restyles the bubble would otherwise leave a dark arrow\n // pointing out of a light one.\n \"absolute h-2 w-2 rotate-45 bg-inherit\",\n position.placement.startsWith(\"top\") &&\n \"bottom-[-4px] left-1/2 -translate-x-1/2\",\n position.placement.startsWith(\"bottom\") &&\n \"top-[-4px] left-1/2 -translate-x-1/2\",\n position.placement.startsWith(\"left\") &&\n \"right-[-4px] top-1/2 -translate-y-1/2\",\n position.placement.startsWith(\"right\") &&\n \"left-[-4px] top-1/2 -translate-y-1/2\",\n )}\n />\n </div>\n </Portal>\n )}\n </>\n );\n },\n);\n\nTooltip.displayName = \"Tooltip\";\n"]}
@@ -1,21 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
-
5
- // src/hooks/use-escape-key.ts
6
- function useEscapeKey(handler, enabled = true) {
7
- react.useEffect(() => {
8
- if (!enabled) return;
9
- const listener = (event) => {
10
- if (event.key === "Escape") {
11
- handler();
12
- }
13
- };
14
- document.addEventListener("keydown", listener);
15
- return () => document.removeEventListener("keydown", listener);
16
- }, [handler, enabled]);
17
- }
18
-
19
- exports.useEscapeKey = useEscapeKey;
20
- //# sourceMappingURL=chunk-RXDRYWVD.cjs.map
21
- //# sourceMappingURL=chunk-RXDRYWVD.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-escape-key.ts"],"names":["useEffect"],"mappings":";;;;;AAEO,SAAS,YAAA,CACd,OAAA,EACA,OAAA,GAAmB,IAAA,EACb;AACN,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAyB;AACzC,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,QAAQ,CAAA;AAC7C,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,QAAQ,CAAA;AAAA,EAC/D,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AACvB","file":"chunk-RXDRYWVD.cjs","sourcesContent":["import { useEffect } from \"react\";\n\nexport function useEscapeKey(\n handler: () => void,\n enabled: boolean = true,\n): void {\n useEffect(() => {\n if (!enabled) return;\n\n const listener = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n handler();\n }\n };\n\n document.addEventListener(\"keydown\", listener);\n return () => document.removeEventListener(\"keydown\", listener);\n }, [handler, enabled]);\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/scroll-lock.ts","../src/hooks/use-full-screen.ts"],"names":["useControllableState","useRef","useState","useCallback","useLayoutEffect","useEffect","layer"],"mappings":"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","file":"chunk-X6TGRSVH.cjs","sourcesContent":["/**\n * Reference-counted body scroll lock.\n *\n * Two surfaces locking independently with the save-and-restore pattern\n * (`const original = body.style.overflow`) only unwind correctly in strict LIFO\n * order. Exit them out of order and the first one out restores `\"\"` while the\n * second is still covering the viewport, so the page scrolls behind it. Counting\n * holders keeps the lock until the last one lets go, and restores the value that\n * was there before the FIRST took it.\n *\n * Call only from an effect: it touches `document`.\n */\nlet holders = 0;\nlet saved = \"\";\n\nexport function lockBodyScroll(): () => void {\n if (holders === 0) {\n saved = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n }\n holders++;\n\n let released = false;\n return () => {\n if (released) return;\n released = true;\n holders--;\n if (holders === 0) document.body.style.overflow = saved;\n };\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent as ReactKeyboardEvent,\n type RefObject,\n} from \"react\";\nimport { useControllableState } from \"./use-controllable-state\";\nimport { lockBodyScroll } from \"../utils/scroll-lock\";\n\n/**\n * How a surface goes full screen.\n *\n * - `\"overlay\"` (default): the element itself becomes `position: fixed` over the\n * viewport, in place. It always works: inside an iframe without\n * `allow=\"fullscreen\"`, inside a dialog, without a user gesture. Nothing is\n * reparented, so an editor keeps its caret, undo stack and DOM.\n * - `\"native\"`: the browser Fullscreen API (`element.requestFullscreen()`),\n * which hides the browser chrome too. The overlay is applied first and stays\n * if the request is rejected or the API is missing, so the user gets full\n * screen either way; `activeMode` reports which one took.\n */\nexport type FullScreenMode = \"overlay\" | \"native\";\n\nexport interface UseFullScreenOptions {\n /** Controlled flag. Pair with `onFullScreenChange`. */\n fullScreen?: boolean;\n /** Initial flag when uncontrolled. @default false */\n defaultFullScreen?: boolean;\n /**\n * Fired with the requested state — from the toggle, Escape, an agent calling\n * `setFullScreen`, or the user leaving the browser's own full screen.\n */\n onFullScreenChange?: (fullScreen: boolean) => void;\n /** @default \"overlay\" */\n mode?: FullScreenMode;\n /** Leave full screen on Escape. @default true */\n closeOnEscape?: boolean;\n /** Stop the page behind from scrolling while active. @default true */\n lockScroll?: boolean;\n /** Stacking order of the overlay. Matches `Modal`. @default 50 */\n zIndex?: number;\n /** Accessible names for the toggle. */\n labels?: { enter?: string; exit?: string };\n}\n\nexport interface FullScreenTargetProps<T extends HTMLElement> {\n ref: RefObject<T | null>;\n \"data-fullscreen\": \"true\" | \"false\";\n \"data-fullscreen-mode\"?: FullScreenMode;\n \"data-fullscreen-layer\"?: FullScreenLayer;\n style?: CSSProperties;\n onKeyDown: (event: ReactKeyboardEvent<T>) => void;\n}\n\nexport interface FullScreenToggleProps {\n type: \"button\";\n onClick: () => void;\n \"aria-pressed\": boolean;\n \"aria-label\": string;\n title: string;\n \"data-react-fancy-fullscreen-toggle\": \"\";\n \"data-fullscreen\": \"true\" | \"false\";\n}\n\nexport interface UseFullScreenResult<T extends HTMLElement = HTMLElement> {\n fullScreen: boolean;\n setFullScreen: (fullScreen: boolean) => void;\n toggle: () => void;\n /** The mechanism in effect while active; `null` when not full screen. */\n activeMode: FullScreenMode | null;\n /**\n * `\"top\"` while the surface is in the browser's top layer (a manual popover,\n * or the native full screen), `\"fixed\"` while it relies on `position: fixed`\n * (no popover API, or the browser refused). `null` when not full screen.\n */\n layer: FullScreenLayer | null;\n /** Attach to the element that goes full screen. Also inside `targetProps`. */\n ref: RefObject<T | null>;\n /**\n * Spread onto the surface's root. Carries the ref, the `data-fullscreen`\n * handle, the overlay style and the Escape/Tab handler. Merge your own\n * `style` / `onKeyDown` if the root has them.\n */\n targetProps: FullScreenTargetProps<T>;\n /** Spread onto a `<button>` to make it the toggle. */\n toggleProps: FullScreenToggleProps;\n /**\n * The element to portal into while active, else `null`. Provide it through\n * `PortalContainerContext` so menus opened inside stay visible.\n */\n portalContainer: HTMLElement | null;\n}\n\nconst FOCUSABLE = [\n \"a[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled])\",\n \"textarea:not([disabled])\",\n \"select:not([disabled])\",\n \"[contenteditable]:not([contenteditable='false'])\",\n \"[tabindex]:not([tabindex='-1'])\",\n].join(\", \");\n\n/** Active surfaces, innermost last. Only the top one answers a stray Escape. */\nconst activeStack: object[] = [];\n\nconst OVERLAY_STYLE: CSSProperties = {\n position: \"fixed\",\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n maxWidth: \"none\",\n maxHeight: \"none\",\n margin: 0,\n borderRadius: 0,\n boxSizing: \"border-box\",\n};\n\n/**\n * Lift `el` into the browser's top layer with `popover=\"manual\"`.\n *\n * Why: `position: fixed` is only fixed to the viewport while no ancestor has a\n * transform, filter, perspective or paint containment. With one, the overlay\n * is fixed to THAT box. In the showcase a surface in a Tabs panel came out\n * 1248x95, because `.fancy-fade-in` held `transform: matrix(1,0,0,1,0,0)` via\n * `animation-fill-mode: both`. Transform-centred dialogs do the same. A\n * top-layer element's containing block is the viewport whatever its ancestors\n * do, and the popover API gets it there without moving it in the DOM.\n *\n * `manual` because `auto` light-dismisses on an outside click and on Escape;\n * Escape stays with the surface's own handler.\n *\n * Returns a release function, or `null` where the API is missing or refuses\n * (the caller keeps the fixed overlay). `onLost` fires if something else\n * closes the popover: a `[popover]` that is not open is `display: none`, so the\n * attribute must go at once or the surface vanishes while still \"full screen\".\n */\n/** Surfaces currently in the top layer through a popover, with a \"re-show\" each. */\nconst promoted = new Map<HTMLElement, () => void>();\n\nfunction promoteToTopLayer(el: HTMLElement, onLost: () => void): (() => void) | null {\n const p = el as HTMLElement & { showPopover?: () => void; hidePopover?: () => void };\n if (typeof p.showPopover !== \"function\" || typeof p.hidePopover !== \"function\") return null;\n // The consumer made it a popover themselves; do not fight over it.\n if (el.hasAttribute(\"popover\")) return null;\n\n el.setAttribute(\"popover\", \"manual\");\n try {\n p.showPopover();\n } catch {\n el.removeAttribute(\"popover\");\n return null;\n }\n\n let open = true;\n let raising = false;\n const onToggle = (e: Event) => {\n if (raising || (e as Event & { newState?: string }).newState !== \"closed\" || !open) return;\n open = false;\n promoted.delete(el);\n el.removeEventListener(\"toggle\", onToggle);\n el.removeAttribute(\"popover\");\n onLost();\n };\n el.addEventListener(\"toggle\", onToggle);\n\n // The top layer stacks in SHOW order. React runs a child's layout effects\n // before its parent's, so a surface nested in another that goes full screen\n // in the same commit is shown first and then buried by its parent. Re-show\n // any promoted descendant so the innermost stays on top.\n for (const [other, raise] of promoted) {\n if (other !== el && el.contains(other)) raise();\n }\n promoted.set(el, () => {\n raising = true;\n try {\n p.hidePopover!();\n p.showPopover!();\n } catch {\n /* leave it where it is */\n } finally {\n raising = false;\n }\n });\n\n return () => {\n promoted.delete(el);\n el.removeEventListener(\"toggle\", onToggle);\n if (open) {\n open = false;\n try {\n p.hidePopover!();\n } catch {\n /* already hidden, e.g. removed from the document */\n }\n }\n el.removeAttribute(\"popover\");\n };\n}\n\n/** Which mechanism keeps the surface over the page. */\nexport type FullScreenLayer = \"top\" | \"fixed\";\n\ninterface ScrollMemo {\n el: Element;\n top: number;\n left: number;\n}\n\n/**\n * A controlled full-screen state for any surface: Editor today, DeckEditor and\n * SheetWorkbook next. Render-time output is pure (no `window`/`document`), so it\n * server-renders; everything that touches the DOM runs in effects.\n */\nexport function useFullScreen<T extends HTMLElement = HTMLElement>(\n options: UseFullScreenOptions = {},\n): UseFullScreenResult<T> {\n const {\n fullScreen: controlled,\n defaultFullScreen = false,\n onFullScreenChange,\n mode = \"overlay\",\n closeOnEscape = true,\n lockScroll = true,\n zIndex = 50,\n labels,\n } = options;\n\n const [fullScreen, setState] = useControllableState(controlled, defaultFullScreen, onFullScreenChange);\n const ref = useRef<T | null>(null);\n const token = useRef({});\n const [nativeActive, setNativeActive] = useState(false);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n // Whether the overlay STYLE is on. It trails `fullScreen` by one synchronous\n // commit on entry, so the layout effect below reads scroll offsets while the\n // surface is still in flow. Read after the style lands and the browser has\n // already clamped every scroll container around it: a panel at 569 read as\n // 342 in Chromium, and that is where the user was sent back to. The re-render\n // happens inside the layout phase, before paint, so nothing flashes.\n // Initialised from `fullScreen` so a surface that starts full screen renders\n // the overlay on the server and on hydration alike.\n const [applied, setApplied] = useState(fullScreen);\n // \"fixed\" until a layout effect has actually promoted the surface, so the\n // server and the hydrating client agree, and a refused promotion reads true.\n const [layer, setLayer] = useState<FullScreenLayer>(\"fixed\");\n const topRelease = useRef<(() => void) | null>(null);\n\n const promote = (el: HTMLElement) => {\n if (topRelease.current) return;\n topRelease.current = promoteToTopLayer(el, () => {\n topRelease.current = null;\n setLayer(\"fixed\");\n });\n setLayer(topRelease.current ? \"top\" : \"fixed\");\n };\n const demote = () => {\n topRelease.current?.();\n topRelease.current = null;\n };\n\n const current = useRef(fullScreen);\n current.current = fullScreen;\n\n // Only report real transitions: Escape on an inactive surface, or a second\n // click racing a re-render, must not fire `onFullScreenChange(false)` twice.\n const setFullScreen = useCallback(\n (next: boolean) => {\n if (current.current === next) return;\n current.current = next;\n setState(next);\n },\n [setState],\n );\n const toggle = useCallback(() => setFullScreen(!current.current), [setFullScreen]);\n\n // Enter / exit bookkeeping. A LAYOUT effect so the cleanup runs after the\n // overlay style has been removed from the DOM but before paint: scroll offsets\n // restored there never flash, and the surface is back in flow to measure.\n useLayoutEffect(() => {\n if (!fullScreen) return;\n const el = ref.current;\n if (!el) return;\n\n // Taking the surface out of flow shrinks every scroll container around it,\n // which clamps their scrollTop. Remember them so exit lands where it began.\n const scrolled: ScrollMemo[] = [];\n for (let p = el.parentElement; p && p !== document.body && p !== document.documentElement; p = p.parentElement) {\n if (p.scrollTop || p.scrollLeft) scrolled.push({ el: p, top: p.scrollTop, left: p.scrollLeft });\n }\n const winX = window.scrollX;\n const winY = window.scrollY;\n\n const release = lockScroll ? lockBodyScroll() : null;\n activeStack.push(token.current);\n setPortalContainer(el);\n setApplied(true);\n\n // Native mode asks the browser first: Chromium rejects requestFullscreen()\n // on an element that is already an open popover (\"already open as a\n // Popover, and therefore cannot be opened via the fullscreen API\"). The\n // native effect promotes on refusal instead.\n const native = mode === \"native\" && typeof el.requestFullscreen === \"function\" && document.fullscreenEnabled !== false;\n if (!native) promote(el);\n\n return () => {\n const i = activeStack.indexOf(token.current);\n if (i >= 0) activeStack.splice(i, 1);\n // Out of the top layer first, so the surface is back in flow before the\n // scroll offsets are put back.\n demote();\n setLayer(\"fixed\");\n release?.();\n for (const m of scrolled) {\n if (m.el.scrollTop !== m.top) m.el.scrollTop = m.top;\n if (m.el.scrollLeft !== m.left) m.el.scrollLeft = m.left;\n }\n if (window.scrollX !== winX || window.scrollY !== winY) window.scrollTo(winX, winY);\n setPortalContainer(null);\n setApplied(false);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fullScreen, lockScroll, mode]);\n\n // Focus in and back out. A PASSIVE effect on purpose: React re-focuses\n // whatever had focus before a commit once the commit's mutations finish, so a\n // focus() issued from a layout-effect cleanup is silently undone.\n useEffect(() => {\n if (!fullScreen) return;\n const el = ref.current;\n if (!el) return;\n\n const opener =\n document.activeElement instanceof HTMLElement && document.activeElement !== document.body\n ? document.activeElement\n : null;\n\n // Focus must not stay behind the overlay, where the user cannot see it.\n if (!el.contains(document.activeElement)) {\n el.querySelector<HTMLElement>(FOCUSABLE)?.focus({ preventScroll: true });\n }\n\n return () => {\n // Give focus back only if it is still ours to give: inside the surface,\n // or lost to <body>. A user who clicked elsewhere keeps their choice.\n const active = document.activeElement;\n if (opener?.isConnected && (!active || active === document.body || el.contains(active))) {\n opener.focus({ preventScroll: true });\n }\n };\n }, [fullScreen]);\n\n // The browser Fullscreen API, on top of the overlay.\n useEffect(() => {\n if (!fullScreen || mode !== \"native\") return;\n const el = ref.current;\n if (!el || typeof el.requestFullscreen !== \"function\" || document.fullscreenEnabled === false) return;\n\n let cancelled = false;\n let entered = false;\n\n const onChange = () => {\n if (document.fullscreenElement === el) {\n entered = true;\n setNativeActive(true);\n // The browser's full screen is the top layer too.\n setLayer(\"top\");\n } else if (entered) {\n // The user left through the browser's own UI (Esc, F11, the close\n // pill). Keep the controlled state honest rather than leaving an\n // overlay up that they believe they dismissed.\n entered = false;\n setNativeActive(false);\n setLayer(\"fixed\");\n if (!cancelled) setFullScreen(false);\n }\n };\n document.addEventListener(\"fullscreenchange\", onChange);\n\n // Blocked requests (iframe without allow=\"fullscreen\", no user gesture, a\n // permissions policy) reject, and some engines throw instead. Either way\n // the user stays full screen in the overlay, lifted into the top layer.\n const refused = () => {\n if (!cancelled && current.current && ref.current === el) promote(el);\n };\n try {\n Promise.resolve(el.requestFullscreen()).then(onChange, refused);\n } catch {\n refused();\n }\n\n return () => {\n cancelled = true;\n document.removeEventListener(\"fullscreenchange\", onChange);\n if (document.fullscreenElement === el) {\n try {\n Promise.resolve(document.exitFullscreen()).catch(() => {});\n } catch {\n /* already left */\n }\n }\n setNativeActive(false);\n };\n }, [fullScreen, mode, setFullScreen]);\n\n // Escape with nothing focused never reaches the surface's own handler.\n useEffect(() => {\n if (!fullScreen || !closeOnEscape) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented) return;\n const t = e.target;\n if (t !== document.body && t !== document.documentElement && t !== document) return;\n if (activeStack[activeStack.length - 1] !== token.current) return;\n setFullScreen(false);\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [fullScreen, closeOnEscape, setFullScreen]);\n\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<T>) => {\n if (!current.current || e.defaultPrevented) return;\n const el = ref.current;\n if (!el) return;\n\n if (e.key === \"Tab\") {\n // Keep Tab inside the surface; what is behind the overlay is invisible.\n const items = Array.from(el.querySelectorAll<HTMLElement>(FOCUSABLE));\n if (items.length === 0) return;\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n if (e.shiftKey && (active === first || active === el)) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n return;\n }\n\n if (e.key !== \"Escape\" || !closeOnEscape) return;\n // An Escape from inside a layer opened FROM this surface (a menu, a\n // popover, a dialog) belongs to that layer. React bubbles portal events\n // through the component tree, so check the DOM: a portal wrapper that\n // does not contain this surface is nested inside it.\n const layer = (e.target as Element).closest?.(\"[data-react-fancy-portal]\");\n if (layer && !layer.contains(el)) return;\n // Stop it here so an enclosing dialog's document listener does not also\n // close: one Escape, one step back.\n e.preventDefault();\n e.stopPropagation();\n setFullScreen(false);\n },\n [closeOnEscape, setFullScreen],\n );\n\n const activeMode: FullScreenMode | null = fullScreen ? (nativeActive ? \"native\" : \"overlay\") : null;\n const enterLabel = labels?.enter ?? \"Enter full screen\";\n const exitLabel = labels?.exit ?? \"Exit full screen\";\n\n return {\n fullScreen,\n setFullScreen,\n toggle,\n activeMode,\n layer: activeMode ? layer : null,\n ref,\n portalContainer,\n targetProps: {\n ref,\n \"data-fullscreen\": fullScreen ? \"true\" : \"false\",\n ...(activeMode ? { \"data-fullscreen-mode\": activeMode, \"data-fullscreen-layer\": layer } : {}),\n ...(fullScreen && applied ? { style: { ...OVERLAY_STYLE, zIndex } } : {}),\n onKeyDown,\n },\n toggleProps: {\n type: \"button\",\n onClick: toggle,\n \"aria-pressed\": fullScreen,\n \"aria-label\": fullScreen ? exitLabel : enterLabel,\n title: fullScreen ? exitLabel : enterLabel,\n \"data-react-fancy-fullscreen-toggle\": \"\",\n \"data-fullscreen\": fullScreen ? \"true\" : \"false\",\n },\n };\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/FullScreen/FullScreen.context.tsx","../src/components/FullScreen/FullScreenToggle.tsx"],"names":["createContext","useContext","jsx","PortalContainerContext","Icon","cn"],"mappings":";;;;;;;;AAIO,IAAM,iBAAA,GAAoBA,oBAA0C,IAAI;AAGxE,SAAS,oBAAA,GAAmD;AACjE,EAAA,OAAOC,iBAAW,iBAAiB,CAAA;AACrC;AAaO,SAAS,kBAAA,CAAmB,EAAE,KAAA,EAAO,QAAA,EAAS,EAA4B;AAC/E,EAAA,uBACEC,cAAA,CAAC,iBAAA,CAAkB,QAAA,EAAlB,EAA2B,KAAA,EAC1B,QAAA,kBAAAA,cAAA,CAACC,wCAAA,CAAuB,QAAA,EAAvB,EAAgC,KAAA,EAAO,KAAA,CAAM,eAAA,EAAkB,UAAS,CAAA,EAC3E,CAAA;AAEJ;ACTO,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,oBAAYD,cAAAA,CAACE,0BAAK,IAAA,EAAM,EAAA,CAAG,aAAa,QAAA,GAAW,SAAA,EAAW,MAAK,IAAA,EAAK,CAAA;AAE9E,EAAA,uBACEF,cAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAG,EAAA,CAAG,WAAA;AAAA,MACP,SAAA,EAAWG,oBAAA;AAAA,QACT,sFAAA;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-ZPBCZPMD.cjs","sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\nimport { PortalContainerContext } from \"../Portal/Portal\";\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 */\nexport function FullScreenProvider({ value, children }: FullScreenProviderProps) {\n return (\n <FullScreenContext.Provider value={value as UseFullScreenResult}>\n <PortalContainerContext.Provider value={value.portalContainer}>{children}</PortalContainerContext.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 \"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"]}