@particle-academy/react-fancy 5.53.0 → 5.53.1

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 (105) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +3 -1
  3. package/dist/accordion.cjs +3 -3
  4. package/dist/accordion.js +1 -1
  5. package/dist/autocomplete.cjs +2 -2
  6. package/dist/autocomplete.js +1 -1
  7. package/dist/chart.cjs +2 -2
  8. package/dist/chart.js +1 -1
  9. package/dist/{chunk-PRP5N7NY.js → chunk-35MF32VQ.js} +3 -3
  10. package/dist/{chunk-PRP5N7NY.js.map → chunk-35MF32VQ.js.map} +1 -1
  11. package/dist/{chunk-TJTC4WNY.cjs → chunk-4DGXL6JC.cjs} +3 -3
  12. package/dist/{chunk-TJTC4WNY.cjs.map → chunk-4DGXL6JC.cjs.map} +1 -1
  13. package/dist/{chunk-QAKIG43N.cjs → chunk-5IWKZ2WK.cjs} +3 -3
  14. package/dist/{chunk-QAKIG43N.cjs.map → chunk-5IWKZ2WK.cjs.map} +1 -1
  15. package/dist/{chunk-546K5LRX.cjs → chunk-CVDL6C2O.cjs} +3 -3
  16. package/dist/{chunk-546K5LRX.cjs.map → chunk-CVDL6C2O.cjs.map} +1 -1
  17. package/dist/{chunk-ZULMMW5W.js → chunk-EEFWVFKO.js} +3 -3
  18. package/dist/{chunk-ZULMMW5W.js.map → chunk-EEFWVFKO.js.map} +1 -1
  19. package/dist/{chunk-SONXLQPJ.cjs → chunk-EZA6GWZL.cjs} +7 -7
  20. package/dist/chunk-EZA6GWZL.cjs.map +1 -0
  21. package/dist/{chunk-45FDQ3R5.js → chunk-FRWOWDGX.js} +3 -3
  22. package/dist/{chunk-45FDQ3R5.js.map → chunk-FRWOWDGX.js.map} +1 -1
  23. package/dist/{chunk-36HG5JK6.cjs → chunk-GISORLGW.cjs} +3 -3
  24. package/dist/{chunk-36HG5JK6.cjs.map → chunk-GISORLGW.cjs.map} +1 -1
  25. package/dist/{chunk-BDUL42VO.cjs → chunk-GLGUQGAQ.cjs} +3 -3
  26. package/dist/{chunk-BDUL42VO.cjs.map → chunk-GLGUQGAQ.cjs.map} +1 -1
  27. package/dist/{chunk-A5DN2XNM.cjs → chunk-HTNQ5XUR.cjs} +3 -3
  28. package/dist/{chunk-A5DN2XNM.cjs.map → chunk-HTNQ5XUR.cjs.map} +1 -1
  29. package/dist/{chunk-ZKJLDBXA.cjs → chunk-ICI33QMY.cjs} +9 -9
  30. package/dist/{chunk-ZKJLDBXA.cjs.map → chunk-ICI33QMY.cjs.map} +1 -1
  31. package/dist/{chunk-JUQZMNPR.cjs → chunk-IEQK3LGI.cjs} +3 -3
  32. package/dist/{chunk-JUQZMNPR.cjs.map → chunk-IEQK3LGI.cjs.map} +1 -1
  33. package/dist/{chunk-MV6BK4WG.js → chunk-IUCYRQ4J.js} +6 -6
  34. package/dist/{chunk-MV6BK4WG.js.map → chunk-IUCYRQ4J.js.map} +1 -1
  35. package/dist/{chunk-N5XMBHX7.js → chunk-JXXUTPDH.js} +3 -3
  36. package/dist/{chunk-N5XMBHX7.js.map → chunk-JXXUTPDH.js.map} +1 -1
  37. package/dist/{chunk-WONP337S.cjs → chunk-JY7HPFOE.cjs} +6 -6
  38. package/dist/{chunk-WONP337S.cjs.map → chunk-JY7HPFOE.cjs.map} +1 -1
  39. package/dist/{chunk-4TVAHZ35.js → chunk-LZHGXRFD.js} +3 -3
  40. package/dist/{chunk-4TVAHZ35.js.map → chunk-LZHGXRFD.js.map} +1 -1
  41. package/dist/{chunk-Y7UE37QZ.js → chunk-NHGU2BWT.js} +3 -3
  42. package/dist/{chunk-Y7UE37QZ.js.map → chunk-NHGU2BWT.js.map} +1 -1
  43. package/dist/{chunk-VOHTL6WN.js → chunk-OC5OUZSD.js} +3 -3
  44. package/dist/{chunk-VOHTL6WN.js.map → chunk-OC5OUZSD.js.map} +1 -1
  45. package/dist/{chunk-3EWO5EBI.js → chunk-QGY5FPVM.js} +4 -4
  46. package/dist/{chunk-3EWO5EBI.js.map → chunk-QGY5FPVM.js.map} +1 -1
  47. package/dist/{chunk-OFNA5HS5.js → chunk-T45LBTXH.js} +3 -3
  48. package/dist/{chunk-OFNA5HS5.js.map → chunk-T45LBTXH.js.map} +1 -1
  49. package/dist/{chunk-XOYRJFMU.js → chunk-TKGMH5PA.js} +3 -3
  50. package/dist/{chunk-XOYRJFMU.js.map → chunk-TKGMH5PA.js.map} +1 -1
  51. package/dist/{chunk-A5RTALZJ.js → chunk-U4Y7ZXME.js} +7 -7
  52. package/dist/chunk-U4Y7ZXME.js.map +1 -0
  53. package/dist/{chunk-S3V2C4DW.cjs → chunk-UXYFM2XT.cjs} +4 -4
  54. package/dist/{chunk-S3V2C4DW.cjs.map → chunk-UXYFM2XT.cjs.map} +1 -1
  55. package/dist/{chunk-SW2MDI2E.cjs → chunk-VP7MT7LH.cjs} +5 -5
  56. package/dist/{chunk-SW2MDI2E.cjs.map → chunk-VP7MT7LH.cjs.map} +1 -1
  57. package/dist/{chunk-5DG4CAWS.js → chunk-YAPGHVBZ.js} +3 -3
  58. package/dist/{chunk-5DG4CAWS.js.map → chunk-YAPGHVBZ.js.map} +1 -1
  59. package/dist/{chunk-UVMIJCY3.js → chunk-YJHP5FVA.js} +7 -7
  60. package/dist/chunk-YJHP5FVA.js.map +1 -0
  61. package/dist/{chunk-3YA6FDVN.cjs → chunk-YJXP6AOL.cjs} +3 -3
  62. package/dist/{chunk-3YA6FDVN.cjs.map → chunk-YJXP6AOL.cjs.map} +1 -1
  63. package/dist/{chunk-QHN63FRP.cjs → chunk-YVTFODCJ.cjs} +3 -3
  64. package/dist/{chunk-QHN63FRP.cjs.map → chunk-YVTFODCJ.cjs.map} +1 -1
  65. package/dist/{chunk-3NIXNJ3I.js → chunk-ZASX5GO4.js} +3 -3
  66. package/dist/{chunk-3NIXNJ3I.js.map → chunk-ZASX5GO4.js.map} +1 -1
  67. package/dist/{chunk-LX23ZJDM.cjs → chunk-ZGDOWJKL.cjs} +7 -7
  68. package/dist/chunk-ZGDOWJKL.cjs.map +1 -0
  69. package/dist/content-renderer.cjs +4 -4
  70. package/dist/content-renderer.js +1 -1
  71. package/dist/editor.cjs +4 -4
  72. package/dist/editor.js +2 -2
  73. package/dist/index.cjs +66 -51
  74. package/dist/index.cjs.map +1 -1
  75. package/dist/index.d.cts +14 -0
  76. package/dist/index.d.ts +14 -0
  77. package/dist/index.js +30 -15
  78. package/dist/index.js.map +1 -1
  79. package/dist/inputs.cjs +4 -4
  80. package/dist/inputs.js +2 -2
  81. package/dist/json-editor.cjs +13 -13
  82. package/dist/json-editor.js +2 -2
  83. package/dist/kanban.cjs +3 -3
  84. package/dist/kanban.js +1 -1
  85. package/dist/menu.cjs +3 -3
  86. package/dist/menu.js +1 -1
  87. package/dist/mobile-menu.cjs +3 -3
  88. package/dist/mobile-menu.js +1 -1
  89. package/dist/multi-switch.cjs +2 -2
  90. package/dist/multi-switch.js +1 -1
  91. package/dist/navbar.cjs +3 -3
  92. package/dist/navbar.js +1 -1
  93. package/dist/select.cjs +2 -2
  94. package/dist/select.js +1 -1
  95. package/dist/sidebar.cjs +3 -3
  96. package/dist/sidebar.js +1 -1
  97. package/dist/table.cjs +11 -11
  98. package/dist/table.js +1 -1
  99. package/dist/timeline.cjs +4 -4
  100. package/dist/timeline.js +1 -1
  101. package/package.json +1 -1
  102. package/dist/chunk-A5RTALZJ.js.map +0 -1
  103. package/dist/chunk-LX23ZJDM.cjs.map +0 -1
  104. package/dist/chunk-SONXLQPJ.cjs.map +0 -1
  105. package/dist/chunk-UVMIJCY3.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -11,6 +11,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [5.53.1] - 2026-10-21
15
+
16
+ ### Fixed
17
+
18
+ - **Inactive nav labels and their hover fill ignored a host palette.**
19
+ TribeShare's runtime audit against 5.53.0 found the following still on raw
20
+ zinc, and beating its tokens in dark mode, so it was overriding them per
21
+ instance:
22
+ - MultiSwitch's unselected option label: `text-zinc-600 dark:text-zinc-400`.
23
+ - Sidebar.Item's inactive label (the same pair) and its hover fill:
24
+ `hover:bg-zinc-50 dark:hover:bg-zinc-800/50`.
25
+
26
+ None of the ten 5.52.0 roles reproduced either pair exactly, so there are
27
+ **two new roles**:
28
+ - `text-subtle` (`--fancy-text-subtle` / `-dark`): zinc-600 / zinc-400.
29
+ - `surface-hover` (`--fancy-surface-hover` / `-dark`): zinc-50 / zinc-800
30
+ at 50%. The dark default is written out as
31
+ `color-mix(in oklab, var(--color-zinc-800) 50%, transparent)`, so a value
32
+ you set is used as-is, not at half strength.
33
+
34
+ Both roles now cover every exact occurrence in the kit, not just the two
35
+ that were reported. That is 24 pairs in 19 files: MultiSwitch, Sidebar.Item,
36
+ Sidebar.Submenu, Menu.Item, Menu.Submenu, MobileMenu.Item, Navbar.Item, the
37
+ Select and Autocomplete option hover, Table row hover, Kanban, Accordion
38
+ content, the Chart axis and labels, Timeline, and the Editor's blockquote.
39
+ Their active and hover text uses the existing `text` role.
40
+ - **What to do:** if you set nothing, nothing changes. Light and `.dark`
41
+ screenshots, including Sidebar, Menu and MultiSwitch, are byte-identical to
42
+ 5.51.2, and the computed hover colours of Sidebar.Item and Menu.Item match in
43
+ both modes. If you were overriding these per instance, you can delete those
44
+ overrides and set the two new tokens instead.
45
+ - **Still on zinc, because no token matches them exactly:**
46
+ - Navbar.Item's hover fill (`hover:bg-zinc-50 / dark:hover:bg-zinc-800`, which
47
+ is opaque rather than 50%).
48
+ - The active Tabs and Navbar label (`text-zinc-900 / dark:text-white`).
49
+ - SidebarToggle's hover text (`zinc-600 / zinc-300`).
50
+
14
51
  ## [5.53.0] - 2026-10-21
15
52
 
16
53
  ### Added
package/README.md CHANGED
@@ -278,7 +278,7 @@ is the one they hit first.
278
278
  ## Semantic tokens
279
279
 
280
280
  The kit's neutral chrome -- surfaces, outlines, text, form fields, focus -- reads
281
- ten semantic tokens, so you can repaint it with your own palette without
281
+ twelve semantic tokens, so you can repaint it with your own palette without
282
282
  remapping Tailwind's `zinc`. Each role is two variables: one per mode.
283
283
 
284
284
  | Role | Light variable | Dark variable | Default (light / dark) | Used for |
@@ -293,6 +293,8 @@ remapping Tailwind's `zinc`. Each role is two variables: one per mode.
293
293
  | `text-muted` | `--fancy-text-muted` | `--fancy-text-muted-dark` | zinc-500 / zinc-400 | descriptions, captions |
294
294
  | `text-faint` | `--fancy-text-faint` | `--fancy-text-faint-dark` | zinc-400 / zinc-500 | placeholders, decorative icons |
295
295
  | `focus` | `--fancy-focus` | `--fancy-focus-dark` | blue-500 / blue-400 | focus border + ring on fields |
296
+ | `text-subtle` | `--fancy-text-subtle` | `--fancy-text-subtle-dark` | zinc-600 / zinc-400 | inactive nav labels (Sidebar, Menu, Navbar, MultiSwitch) |
297
+ | `surface-hover` | `--fancy-surface-hover` | `--fancy-surface-hover-dark` | zinc-50 / zinc-800 at 50% | hover fill on nav items, options, rows |
296
298
 
297
299
  ```css
298
300
  /* A cream/terracotta light theme and a blue-grey dark one. */
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var chunk546K5LRX_cjs = require('./chunk-546K5LRX.cjs');
3
+ var chunkCVDL6C2O_cjs = require('./chunk-CVDL6C2O.cjs');
4
4
  require('./chunk-ZU5Q77OT.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "Accordion", {
9
9
  enumerable: true,
10
- get: function () { return chunk546K5LRX_cjs.Accordion; }
10
+ get: function () { return chunkCVDL6C2O_cjs.Accordion; }
11
11
  });
12
12
  Object.defineProperty(exports, "useAccordion", {
13
13
  enumerable: true,
14
- get: function () { return chunk546K5LRX_cjs.useAccordion; }
14
+ get: function () { return chunkCVDL6C2O_cjs.useAccordion; }
15
15
  });
16
16
  //# sourceMappingURL=accordion.cjs.map
17
17
  //# sourceMappingURL=accordion.cjs.map
package/dist/accordion.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Accordion, useAccordion } from './chunk-45FDQ3R5.js';
1
+ export { Accordion, useAccordion } from './chunk-FRWOWDGX.js';
2
2
  import './chunk-MMW2JGKZ.js';
3
3
  //# sourceMappingURL=accordion.js.map
4
4
  //# sourceMappingURL=accordion.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkTJTC4WNY_cjs = require('./chunk-TJTC4WNY.cjs');
3
+ var chunk4DGXL6JC_cjs = require('./chunk-4DGXL6JC.cjs');
4
4
  require('./chunk-KJ22KE56.cjs');
5
5
  require('./chunk-L3V3BYVS.cjs');
6
6
  require('./chunk-J2DI6RMR.cjs');
@@ -14,7 +14,7 @@ require('./chunk-ZU5Q77OT.cjs');
14
14
 
15
15
  Object.defineProperty(exports, "Autocomplete", {
16
16
  enumerable: true,
17
- get: function () { return chunkTJTC4WNY_cjs.Autocomplete; }
17
+ get: function () { return chunk4DGXL6JC_cjs.Autocomplete; }
18
18
  });
19
19
  //# sourceMappingURL=autocomplete.cjs.map
20
20
  //# sourceMappingURL=autocomplete.cjs.map
@@ -1,4 +1,4 @@
1
- export { Autocomplete } from './chunk-Y7UE37QZ.js';
1
+ export { Autocomplete } from './chunk-NHGU2BWT.js';
2
2
  import './chunk-OL53XYHF.js';
3
3
  import './chunk-NRXK42LO.js';
4
4
  import './chunk-MQ6VGG62.js';
package/dist/chart.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunkWONP337S_cjs = require('./chunk-WONP337S.cjs');
3
+ var chunkJY7HPFOE_cjs = require('./chunk-JY7HPFOE.cjs');
4
4
  require('./chunk-ZU5Q77OT.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "Chart", {
9
9
  enumerable: true,
10
- get: function () { return chunkWONP337S_cjs.Chart; }
10
+ get: function () { return chunkJY7HPFOE_cjs.Chart; }
11
11
  });
12
12
  //# sourceMappingURL=chart.cjs.map
13
13
  //# sourceMappingURL=chart.cjs.map
package/dist/chart.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Chart } from './chunk-MV6BK4WG.js';
1
+ export { Chart } from './chunk-IUCYRQ4J.js';
2
2
  import './chunk-MMW2JGKZ.js';
3
3
  //# sourceMappingURL=chart.js.map
4
4
  //# sourceMappingURL=chart.js.map
@@ -193,7 +193,7 @@ function KanbanColumn({
193
193
  className
194
194
  ),
195
195
  children: [
196
- title && /* @__PURE__ */ jsxs("h3", { className: "mb-3 flex items-center gap-2 text-sm font-semibold text-zinc-600 dark:text-zinc-400", children: [
196
+ title && /* @__PURE__ */ jsxs("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))]", children: [
197
197
  /* @__PURE__ */ jsx("span", { className: "flex-1", children: title }),
198
198
  /* @__PURE__ */ jsxs(
199
199
  "span",
@@ -357,5 +357,5 @@ var Kanban = Object.assign(KanbanRoot, {
357
357
  });
358
358
 
359
359
  export { Kanban, useKanban };
360
- //# sourceMappingURL=chunk-PRP5N7NY.js.map
361
- //# sourceMappingURL=chunk-PRP5N7NY.js.map
360
+ //# sourceMappingURL=chunk-35MF32VQ.js.map
361
+ //# sourceMappingURL=chunk-35MF32VQ.js.map
@@ -1 +1 @@
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":["useCallback","jsx","useState","useRef"],"mappings":"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","file":"chunk-PRP5N7NY.js","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-zinc-600 dark:text-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
+ {"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":["useCallback","jsx","useState","useRef"],"mappings":"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","file":"chunk-35MF32VQ.js","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"]}
@@ -171,7 +171,7 @@ var Autocomplete = react.forwardRef(
171
171
  onClick: () => select(option.value),
172
172
  className: chunkZU5Q77OT_cjs.cn(
173
173
  "flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-zinc-700 transition-colors dark:text-zinc-200",
174
- i === activeIndex ? "bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]" : "hover:bg-zinc-50 dark:hover:bg-zinc-800/50",
174
+ i === activeIndex ? "bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]" : "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))]",
175
175
  option.disabled && "cursor-not-allowed opacity-50"
176
176
  ),
177
177
  children: /* @__PURE__ */ jsxRuntime.jsx(HighlightMatch, { text: option.label, query })
@@ -198,5 +198,5 @@ function HighlightMatch({ text, query }) {
198
198
  Autocomplete.displayName = "Autocomplete";
199
199
 
200
200
  exports.Autocomplete = Autocomplete;
201
- //# sourceMappingURL=chunk-TJTC4WNY.cjs.map
202
- //# sourceMappingURL=chunk-TJTC4WNY.cjs.map
201
+ //# sourceMappingURL=chunk-4DGXL6JC.cjs.map
202
+ //# sourceMappingURL=chunk-4DGXL6JC.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Autocomplete/Autocomplete.tsx"],"names":["forwardRef","Autocomplete","useControllableState","useFieldMode","useInlineEdit","useState","useRef","useFloatingPosition","useCallback","useOutsideClick","useEscapeKey","useEffect","jsx","cn","jsxs","Portal","Fragment"],"mappings":";;;;;;;;;;;;;AAWO,IAAM,YAAA,GAAeA,gBAAA;AAAA,EAC1B,SAASC,aAAAA,CACP;AAAA,IACE,KAAA,EAAO,eAAA;AAAA,IACP,YAAA,GAAe,EAAA;AAAA,IACf,QAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,YAAA,GAAe,mBAAA;AAAA,IACf,QAAA,GAAW,KAAA;AAAA,IACX,SAAA;AAAA,IACA;AAAA,KAEF,GAAA,EACA;AACA,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,sCAAA;AAAA,MACxB,eAAA;AAAA,MACA,YAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,YAAA,GAAeC,+BAAa,IAAI,CAAA;AACtC,IAAA,MAAM,EAAE,aAAa,WAAA,EAAa,SAAA,EAAW,UAAS,GAAIC,+BAAA,CAAc,cAAc,QAAQ,CAAA;AAC9F,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,eAAS,KAAK,CAAA;AACxC,IAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAS,KAAK,CAAA;AACtC,IAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAS,EAAE,CAAA;AAEjD,IAAA,MAAM,SAAA,GAAYC,aAAyB,IAAI,CAAA;AAC/C,IAAA,MAAM,OAAA,GAAUA,aAAuB,IAAI,CAAA;AAC3C,IAAA,MAAM,UAAA,GAAaA,aAAuB,IAAI,CAAA;AAE9C,IAAA,MAAM,QAAA,GAAWC,qCAAA,CAAoB,SAAA,EAAW,OAAA,EAAS;AAAA,MACvD,SAAA,EAAW,cAAA;AAAA,MACX,MAAA,EAAQ,CAAA;AAAA,MACR,OAAA,EAAS;AAAA,KACV,CAAA;AAED,IAAA,MAAM,KAAA,GAAQC,kBAAY,MAAM;AAC9B,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,cAAA,CAAe,EAAE,CAAA;AAAA,IACnB,CAAA,EAAG,EAAE,CAAA;AAEL,IAAAC,iCAAA,CAAgB,UAAA,EAAY,OAAO,IAAI,CAAA;AACvC,IAAAC,8BAAA,CAAa,OAAO,IAAI,CAAA;AAExB,IAAA,MAAM,WAAW,OAAA,CAAQ,MAAA;AAAA,MAAO,CAAC,MAC/B,CAAA,CAAE,KAAA,CAAM,aAAY,CAAE,QAAA,CAAS,KAAA,CAAM,WAAA,EAAa;AAAA,KACpD;AAEA,IAAA,MAAM,MAAA,GAASF,iBAAA;AAAA,MACb,CAAC,GAAA,KAAgB;AACf,QAAA,QAAA,CAAS,GAAG,CAAA;AACZ,QAAA,MAAM,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,GAAG,CAAA;AAC/C,QAAA,QAAA,CAAS,GAAA,EAAK,SAAS,GAAG,CAAA;AAC1B,QAAA,KAAA,EAAM;AAAA,MACR,CAAA;AAAA,MACA,CAAC,QAAA,EAAU,OAAA,EAAS,KAAK;AAAA,KAC3B;AAEA,IAAAG,eAAA,CAAU,MAAM;AACd,MAAA,QAAA,GAAW,KAAK,CAAA;AAAA,IAClB,CAAA,EAAG,CAAC,KAAA,EAAO,QAAQ,CAAC,CAAA;AAEpB,IAAA,MAAM,aAAA,GAAgB,CAAC,CAAA,KAA2B;AAChD,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,IAAI,CAAA,CAAE,QAAQ,WAAA,EAAa;AACzB,UAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,UAAA;AAAA,QACF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,CAAA,CAAE,QAAQ,WAAA,EAAa;AACzB,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,cAAA,CAAe,CAAC,MAAM,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG,QAAA,CAAS,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,MAC5D,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,SAAA,EAAW;AAC9B,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,cAAA,CAAe,CAAC,CAAA,KAAM,IAAA,CAAK,IAAI,CAAA,GAAI,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,MAC1C,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,eAAe,CAAA,EAAG;AAChD,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,MAAM,IAAA,GAAO,SAAS,WAAW,CAAA;AACjC,QAAA,IAAI,QAAQ,CAAC,IAAA,CAAK,QAAA,EAAU,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,MAC/C;AAAA,IACF,CAAA;AAEA,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,KAAK,CAAA;AACrD,MAAA,uBACEC,cAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,+BAAA,EAA8B,EAAA;AAAA,UAC9B,WAAA,EAAU,MAAA;AAAA,UACV,GAAA,EAAK,UAAA;AAAA,UACL,IAAA,EAAM,cAAc,QAAA,GAAW,MAAA;AAAA,UAC/B,QAAA,EAAU,cAAc,CAAA,GAAI,MAAA;AAAA,UAC5B,KAAA,EAAO,cAAc,eAAA,GAAkB,MAAA;AAAA,UACvC,OAAA,EAAS,cAAc,SAAA,GAAY,MAAA;AAAA,UACnC,SAAA,EACE,WAAA,GACI,CAAC,CAAA,KAAM;AACL,YAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAA,CAAE,QAAQ,GAAA,EAAK;AACtC,cAAA,CAAA,CAAE,cAAA,EAAe;AACjB,cAAA,SAAA,EAAU;AAAA,YACZ;AAAA,UACF,CAAA,GACA,MAAA;AAAA,UAEN,SAAA,EAAWC,oBAAA;AAAA,YACT,6HAAA;AAAA,YACA,CAAC,KAAA,IAAS,iIAAA;AAAA,YACV,WAAA,IACE,4PAAA;AAAA,YACF;AAAA,WACF;AAAA,UAEC,QAAA,EAAA,OAAA,EAAS,SAAS,KAAA,IAAS;AAAA;AAAA,OAC9B;AAAA,IAEJ;AAEA,IAAA,uBACEC,eAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,+BAAA,EAA8B,EAAA;AAAA,QAC9B,GAAA,EAAK,UAAA;AAAA,QACL,SAAA,EAAWD,oBAAA,CAAG,UAAA,EAAY,SAAS,CAAA;AAAA,QACnC,MAAA,EAAQ,CAAC,CAAA,KAAM;AAEb,UAAA,IAAI,WAAA,IAAe,CAAC,IAAA,IAAQ,CAAC,EAAE,aAAA,CAAc,QAAA,CAAS,CAAA,CAAE,aAAqB,CAAA,EAAG;AAC9E,YAAA,QAAA,EAAS;AAAA,UACX;AAAA,QACF,CAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,cAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,CAAC,IAAA,KAAS;AACb,gBAAC,UAA8D,OAAA,GAAU,IAAA;AACzE,gBAAA,IAAI,OAAO,GAAA,KAAQ,UAAA,EAAY,GAAA,CAAI,IAAI,CAAA;AAAA,qBAAA,IAC9B,GAAA,EAAM,GAAA,CAAwD,OAAA,GAAU,IAAA;AAAA,cACnF,CAAA;AAAA,cACA,IAAA,EAAK,MAAA;AAAA,cACL,KAAA,EAAO,KAAA;AAAA,cACP,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,gBAAA,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AACvB,gBAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,gBAAA,cAAA,CAAe,EAAE,CAAA;AAAA,cACnB,CAAA;AAAA,cACA,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,cAC3B,SAAA,EAAW,aAAA;AAAA,cACX,WAAA;AAAA,cACA,QAAA;AAAA,cACA,SAAA,EAAW,WAAA;AAAA,cACX,IAAA,EAAK,UAAA;AAAA,cACL,eAAA,EAAe,IAAA;AAAA,cACf,mBAAA,EAAkB,MAAA;AAAA,cAClB,SAAA,EAAU;AAAA;AAAA,WACZ;AAAA,UACC,IAAA,mCACEG,wBAAA,EAAA,EACC,QAAA,kBAAAH,cAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,OAAA;AAAA,cACL,IAAA,EAAK,SAAA;AAAA,cACL,SAAA,EAAU,wWAAA;AAAA,cACV,KAAA,EAAO;AAAA,gBACL,MAAM,QAAA,CAAS,CAAA;AAAA,gBACf,KAAK,QAAA,CAAS,CAAA;AAAA,gBACd,KAAA,EAAO,UAAU,OAAA,EAAS;AAAA,eAC5B;AAAA,cAEC,QAAA,EAAA,OAAA,kCACE,KAAA,EAAA,EAAI,SAAA,EAAU,mCAAkC,QAAA,EAAA,YAAA,EAAU,CAAA,GACzD,SAAS,MAAA,KAAW,CAAA,kCACrB,KAAA,EAAA,EAAI,SAAA,EAAU,mCACZ,QAAA,EAAA,YAAA,EACH,CAAA,GAEA,SAAS,GAAA,CAAI,CAAC,QAAQ,CAAA,qBACpBA,cAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAEC,IAAA,EAAK,QAAA;AAAA,kBACL,IAAA,EAAK,QAAA;AAAA,kBACL,iBAAe,CAAA,KAAM,WAAA;AAAA,kBACrB,UAAU,MAAA,CAAO,QAAA;AAAA,kBACjB,OAAA,EAAS,MAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,kBAClC,SAAA,EAAWC,oBAAA;AAAA,oBACT,oHAAA;AAAA,oBACA,CAAA,KAAM,cACF,mIAAA,GACA,4CAAA;AAAA,oBACJ,OAAO,QAAA,IAAY;AAAA,mBACrB;AAAA,kBAEA,QAAA,kBAAAD,cAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAM,MAAA,CAAO,OAAO,KAAA,EAAc;AAAA,iBAAA;AAAA,gBAd7C,MAAA,CAAO;AAAA,eAgBf;AAAA;AAAA,WAEL,EACF;AAAA;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AAEA,SAAS,cAAA,CAAe,EAAE,IAAA,EAAM,KAAA,EAAM,EAAoC;AACxE,EAAA,IAAI,CAAC,KAAA,EAAO,uBAAOA,cAAA,CAAAI,mBAAA,EAAA,EAAG,QAAA,EAAA,IAAA,EAAK,CAAA;AAE3B,EAAA,MAAM,MAAM,IAAA,CAAK,WAAA,GAAc,OAAA,CAAQ,KAAA,CAAM,aAAa,CAAA;AAC1D,EAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,uBAAOJ,cAAA,CAAAI,mBAAA,EAAA,EAAG,QAAA,EAAA,IAAA,EAAK,CAAA;AAE/B,EAAA,uBACEF,eAAA,CAAAE,mBAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,IAAA,CAAK,KAAA,CAAM,GAAG,GAAG,CAAA;AAAA,oBAClBJ,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6CAAA,EACb,QAAA,EAAA,IAAA,CAAK,MAAM,GAAA,EAAK,GAAA,GAAM,KAAA,CAAM,MAAM,CAAA,EACrC,CAAA;AAAA,IACC,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,KAAA,CAAM,MAAM;AAAA,GAAA,EAChC,CAAA;AAEJ;AAEA,YAAA,CAAa,WAAA,GAAc,cAAA","file":"chunk-TJTC4WNY.cjs","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-zinc-50 dark:hover:bg-zinc-800/50\",\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":["forwardRef","Autocomplete","useControllableState","useFieldMode","useInlineEdit","useState","useRef","useFloatingPosition","useCallback","useOutsideClick","useEscapeKey","useEffect","jsx","cn","jsxs","Portal","Fragment"],"mappings":"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","file":"chunk-4DGXL6JC.cjs","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"]}
@@ -100,7 +100,7 @@ var proseClasses = [
100
100
  "[&_a]:text-blue-500 [&_a]:underline",
101
101
  "[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5",
102
102
  "[&_li]:mb-1",
103
- "[&_blockquote]:border-l-4 [&_blockquote]:border-zinc-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:text-zinc-600 dark:[&_blockquote]:border-zinc-600 dark:[&_blockquote]:text-zinc-400",
103
+ "[&_blockquote]:border-l-4 [&_blockquote]:border-zinc-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] dark:[&_blockquote]:border-zinc-600 dark:[&_blockquote]:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))]",
104
104
  "[&_code]:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] [&_code]:px-1 [&_code]:rounded [&_code]:text-sm dark:[&_code]:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]",
105
105
  "[&_pre]:bg-zinc-950 [&_pre]:text-zinc-100 [&_pre]:p-4 [&_pre]:rounded-lg [&_pre]:overflow-x-auto",
106
106
  "[&_pre_code]:bg-transparent [&_pre_code]:px-0",
@@ -356,5 +356,5 @@ exports.proseClasses = proseClasses;
356
356
  exports.registerExtension = registerExtension;
357
357
  exports.registerExtensions = registerExtensions;
358
358
  exports.renderMarkdown = renderMarkdown;
359
- //# sourceMappingURL=chunk-QAKIG43N.cjs.map
360
- //# sourceMappingURL=chunk-QAKIG43N.cjs.map
359
+ //# sourceMappingURL=chunk-5IWKZ2WK.cjs.map
360
+ //# sourceMappingURL=chunk-5IWKZ2WK.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ContentRenderer/extensions.ts","../src/utils/markdown.ts","../src/components/Editor/editor.utils.ts","../src/components/ContentRenderer/RenderedContent.tsx","../src/components/ContentRenderer/ContentRenderer.tsx"],"names":["marked","sanitizeHtml","useMemo","jsx","Fragment","cn"],"mappings":"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","file":"chunk-QAKIG43N.cjs","sourcesContent":["import type { ComponentType } from \"react\";\n\n/** Props passed to every render-extension component. */\nexport interface RenderExtensionProps {\n /** The inner content of the custom tag (raw string). */\n content: string;\n /** Parsed HTML attributes from the opening tag. */\n attributes: Record<string, string>;\n}\n\n/** Registers a custom tag with a React component for rendering. */\nexport interface RenderExtension {\n /** Tag name to match, e.g. \"questions\", \"thinking\". Case-insensitive. */\n tag: string;\n /** React component that renders the matched tag. */\n component: ComponentType<RenderExtensionProps>;\n /**\n * Whether this is a block-level element.\n * Block extensions are wrapped in a `<div>`, inline in a `<span>`.\n * @default true\n */\n block?: boolean;\n}\n\n/** A parsed segment — either raw HTML or a matched extension tag. */\nexport type ContentSegment =\n | { type: \"html\"; content: string }\n | { type: \"extension\"; tag: string; content: string; attributes: Record<string, string> };\n\n// ---------------------------------------------------------------------------\n// Global extension registry\n// ---------------------------------------------------------------------------\n\nconst globalRegistry: RenderExtension[] = [];\n\n/** Register a single render extension globally (available to all ContentRenderer and Editor instances). */\nexport function registerExtension(extension: RenderExtension): void {\n const idx = globalRegistry.findIndex(\n (e) => e.tag.toLowerCase() === extension.tag.toLowerCase(),\n );\n if (idx >= 0) {\n globalRegistry[idx] = extension;\n } else {\n globalRegistry.push(extension);\n }\n}\n\n/** Register multiple render extensions globally. */\nexport function registerExtensions(extensions: RenderExtension[]): void {\n for (const ext of extensions) {\n registerExtension(ext);\n }\n}\n\n/** Get a snapshot of the current global registry. */\nexport function getGlobalExtensions(): RenderExtension[] {\n return [...globalRegistry];\n}\n\n// ---------------------------------------------------------------------------\n// Parsing\n// ---------------------------------------------------------------------------\n\n/** Parse attributes from an opening tag string like `tag foo=\"bar\" baz=\"qux\"`. */\nfunction parseAttributes(attrString: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const re = /(\\w[\\w-]*)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|(\\S+)))?/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(attrString)) !== null) {\n attrs[m[1]] = m[2] ?? m[3] ?? m[4] ?? \"\";\n }\n return attrs;\n}\n\n/**\n * Split an HTML string into segments of plain HTML and matched extension tags.\n *\n * Handles:\n * - `<tag>content</tag>`\n * - `<tag attr=\"val\">content</tag>`\n * - Nested different-tags inside the content (preserved as raw HTML)\n * - Self-nesting of the same tag (greedy — matches outermost)\n */\nexport function parseSegments(\n html: string,\n extensions: RenderExtension[],\n): ContentSegment[] {\n if (extensions.length === 0) {\n return html ? [{ type: \"html\", content: html }] : [];\n }\n\n const tagNames = extensions.map((e) => e.tag).join(\"|\");\n // Match opening tag with optional attributes, then content, then closing tag.\n // Uses a non-greedy match for content — if same-tag nesting is needed the\n // consumer should use distinct tag names.\n const pattern = new RegExp(\n `<(${tagNames})((?:\\\\s+[^>]*)?)>([\\\\s\\\\S]*?)<\\\\/\\\\1>`,\n \"gi\",\n );\n\n const segments: ContentSegment[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(html)) !== null) {\n // Push any HTML before this match\n if (match.index > lastIndex) {\n segments.push({ type: \"html\", content: html.slice(lastIndex, match.index) });\n }\n\n const tag = match[1].toLowerCase();\n const rawAttrs = match[2] ? match[2].trim() : \"\";\n const innerContent = match[3];\n\n segments.push({\n type: \"extension\",\n tag,\n content: innerContent,\n attributes: rawAttrs ? parseAttributes(rawAttrs) : {},\n });\n\n lastIndex = match.index + match[0].length;\n }\n\n // Push any trailing HTML\n if (lastIndex < html.length) {\n segments.push({ type: \"html\", content: html.slice(lastIndex) });\n }\n\n return segments;\n}\n\n/**\n * Merge per-instance extensions with the global registry.\n * Instance extensions override globals with the same tag name.\n */\nexport function mergeExtensions(\n instanceExtensions?: RenderExtension[],\n): RenderExtension[] {\n const globals = getGlobalExtensions();\n if (!instanceExtensions || instanceExtensions.length === 0) return globals;\n if (globals.length === 0) return instanceExtensions;\n\n const merged = [...globals];\n for (const ext of instanceExtensions) {\n const idx = merged.findIndex(\n (e) => e.tag.toLowerCase() === ext.tag.toLowerCase(),\n );\n if (idx >= 0) {\n merged[idx] = ext;\n } else {\n merged.push(ext);\n }\n }\n return merged;\n}\n","import { marked } from \"marked\";\nimport { sanitizeHtml, type SanitizeHtmlOptions } from \"./sanitize\";\n\n/**\n * Parse markdown to HTML WITHOUT sanitising. Internal: ContentRenderer's\n * `unsafe` path needs the raw output; everything public goes through\n * {@link renderMarkdown}.\n */\nexport function markdownToRawHtml(markdown: string | null | undefined): string {\n // marked.parse throws on nullish input; treat missing content as empty.\n return marked.parse(markdown ?? \"\", { async: false }) as string;\n}\n\n/**\n * Render markdown (GitHub-flavoured) to sanitised HTML — the same parser and\n * output `ContentRenderer` uses, so a host never has to import the parser\n * itself.\n *\n * With no `sanitize` options the default blocklist of {@link sanitizeHtml} is\n * applied; pass allowlist options to keep only what you list:\n *\n * ```ts\n * renderMarkdown(md, { allowedTags: [\"p\", \"strong\", \"a\"], allowedAttributes: [\"href\"] })\n * ```\n */\nexport function renderMarkdown(\n markdown: string,\n sanitize?: SanitizeHtmlOptions,\n): string {\n return sanitizeHtml(markdownToRawHtml(markdown), sanitize);\n}\n","import type { RenderExtension } from \"../ContentRenderer/extensions\";\n\n/**\n * Shared prose typography classes for Editor.Content and ContentRenderer.\n * Hand-rolled since we don't depend on @tailwindcss/typography.\n */\nexport const proseClasses = [\n \"[&_h1]:text-2xl [&_h1]:font-bold [&_h1]:mt-4 [&_h1]:mb-2\",\n \"[&_h2]:text-xl [&_h2]:font-semibold [&_h2]:mt-3 [&_h2]:mb-2\",\n \"[&_h3]:text-lg [&_h3]:font-semibold [&_h3]:mt-2 [&_h3]:mb-1\",\n \"[&_p]:mb-2\",\n \"[&_a]:text-blue-500 [&_a]:underline\",\n \"[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5\",\n \"[&_li]:mb-1\",\n \"[&_blockquote]:border-l-4 [&_blockquote]:border-zinc-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:text-zinc-600 dark:[&_blockquote]:border-zinc-600 dark:[&_blockquote]:text-zinc-400\",\n \"[&_code]:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] [&_code]:px-1 [&_code]:rounded [&_code]:text-sm dark:[&_code]:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n \"[&_pre]:bg-zinc-950 [&_pre]:text-zinc-100 [&_pre]:p-4 [&_pre]:rounded-lg [&_pre]:overflow-x-auto\",\n \"[&_pre_code]:bg-transparent [&_pre_code]:px-0\",\n \"[&_strong]:font-bold [&_em]:italic\",\n].join(\" \");\n\nconst HTML_TAG_PATTERN = /<(p|div|br|h[1-6]|ul|ol|strong|em|a |img |table|pre|code|blockquote)[>\\s/]/i;\n\n/** Detect whether a string is likely HTML or Markdown. */\nexport function detectFormat(value: string): \"html\" | \"markdown\" {\n return HTML_TAG_PATTERN.test(value) ? \"html\" : \"markdown\";\n}\n\n/**\n * Build a set of known HTML tag names. Extension tags are excluded\n * so that the \"strip remaining tags\" step preserves them.\n */\nconst STANDARD_HTML_TAGS = new Set([\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\",\n \"b\", \"base\", \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\",\n \"canvas\", \"caption\", \"cite\", \"code\", \"col\", \"colgroup\",\n \"data\", \"datalist\", \"dd\", \"del\", \"details\", \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\",\n \"em\", \"embed\",\n \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\",\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hgroup\", \"hr\", \"html\",\n \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\",\n \"label\", \"legend\", \"li\", \"link\",\n \"main\", \"map\", \"mark\", \"menu\", \"meta\", \"meter\",\n \"nav\", \"noscript\",\n \"object\", \"ol\", \"optgroup\", \"option\", \"output\",\n \"p\", \"param\", \"picture\", \"pre\", \"progress\",\n \"q\",\n \"rp\", \"rt\", \"ruby\",\n \"s\", \"samp\", \"script\", \"section\", \"select\", \"slot\", \"small\", \"source\", \"span\",\n \"strike\", \"strong\", \"style\", \"sub\", \"summary\", \"sup\",\n \"table\", \"tbody\", \"td\", \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\", \"time\", \"title\", \"tr\", \"track\",\n \"u\", \"ul\",\n \"var\", \"video\",\n \"wbr\",\n]);\n\n/**\n * Lightweight HTML-to-Markdown converter for editor output.\n * Handles the most common inline/block formatting produced by contentEditable.\n * Custom extension tags are preserved as-is in the output.\n */\nexport function htmlToMarkdown(html: string): string {\n let md = html;\n\n // Block elements first\n md = md.replace(/<h1[^>]*>(.*?)<\\/h1>/gi, \"# $1\\n\");\n md = md.replace(/<h2[^>]*>(.*?)<\\/h2>/gi, \"## $1\\n\");\n md = md.replace(/<h3[^>]*>(.*?)<\\/h3>/gi, \"### $1\\n\");\n md = md.replace(/<h4[^>]*>(.*?)<\\/h4>/gi, \"#### $1\\n\");\n md = md.replace(/<h5[^>]*>(.*?)<\\/h5>/gi, \"##### $1\\n\");\n md = md.replace(/<h6[^>]*>(.*?)<\\/h6>/gi, \"###### $1\\n\");\n\n // Lists\n md = md.replace(/<li[^>]*>(.*?)<\\/li>/gi, \"- $1\\n\");\n md = md.replace(/<\\/?[uo]l[^>]*>/gi, \"\\n\");\n\n // Inline formatting\n md = md.replace(/<strong[^>]*>(.*?)<\\/strong>/gi, \"**$1**\");\n md = md.replace(/<b[^>]*>(.*?)<\\/b>/gi, \"**$1**\");\n md = md.replace(/<em[^>]*>(.*?)<\\/em>/gi, \"*$1*\");\n md = md.replace(/<i[^>]*>(.*?)<\\/i>/gi, \"*$1*\");\n md = md.replace(/<u[^>]*>(.*?)<\\/u>/gi, \"$1\");\n md = md.replace(/<s[^>]*>(.*?)<\\/s>/gi, \"~~$1~~\");\n md = md.replace(/<strike[^>]*>(.*?)<\\/strike>/gi, \"~~$1~~\");\n md = md.replace(/<del[^>]*>(.*?)<\\/del>/gi, \"~~$1~~\");\n md = md.replace(/<code[^>]*>(.*?)<\\/code>/gi, \"`$1`\");\n\n // Links\n md = md.replace(/<a[^>]*href=\"([^\"]*)\"[^>]*>(.*?)<\\/a>/gi, \"[$2]($1)\");\n\n // Blockquotes\n md = md.replace(/<blockquote[^>]*>(.*?)<\\/blockquote>/gi, \"> $1\\n\");\n\n // Line breaks and paragraphs\n md = md.replace(/<br\\s*\\/?>/gi, \"\\n\");\n md = md.replace(/<p[^>]*>(.*?)<\\/p>/gi, \"$1\\n\\n\");\n md = md.replace(/<div[^>]*>(.*?)<\\/div>/gi, \"$1\\n\");\n\n // Strip only standard HTML tags — preserve unknown/custom tags\n md = md.replace(/<\\/?([a-z][a-z0-9]*)\\b[^>]*>/gi, (match, tagName: string) => {\n return STANDARD_HTML_TAGS.has(tagName.toLowerCase()) ? \"\" : match;\n });\n\n // Decode common HTML entities. Decode &amp; LAST so we never double-unescape:\n // e.g. \"&amp;lt;\" must decode to the literal \"&lt;\", not to \"<\".\n md = md.replace(/&lt;/g, \"<\");\n md = md.replace(/&gt;/g, \">\");\n md = md.replace(/&quot;/g, '\"');\n md = md.replace(/&#39;/g, \"'\");\n md = md.replace(/&nbsp;/g, \" \");\n md = md.replace(/&amp;/g, \"&\");\n\n // Clean up extra whitespace\n md = md.replace(/\\n{3,}/g, \"\\n\\n\");\n md = md.trim();\n\n return md;\n}\n\n/**\n * Generate CSS classes to visually distinguish custom extension tags\n * inside the contentEditable area. Returns Tailwind-style descendant selectors.\n */\nexport function extensionEditorClasses(extensions: RenderExtension[]): string {\n if (extensions.length === 0) return \"\";\n\n return extensions\n .map((ext) => {\n const tag = ext.tag.toLowerCase();\n return [\n `[&_${tag}]:block`,\n `[&_${tag}]:my-2`,\n `[&_${tag}]:rounded-lg`,\n `[&_${tag}]:border`,\n `[&_${tag}]:border-dashed`,\n `[&_${tag}]:border-zinc-300`,\n `[&_${tag}]:bg-zinc-50`,\n `[&_${tag}]:p-3`,\n `[&_${tag}]:text-xs`,\n `dark:[&_${tag}]:border-zinc-600`,\n `dark:[&_${tag}]:bg-zinc-800/50`,\n ].join(\" \");\n })\n .join(\" \");\n}\n","import { useMemo } from \"react\";\nimport { sanitizeHtml } from \"../../utils/sanitize\";\nimport type { RenderExtension } from \"./extensions\";\nimport { parseSegments, mergeExtensions } from \"./extensions\";\n\ninterface RenderedContentProps {\n html: string;\n extensions?: RenderExtension[];\n /**\n * If true, html is rendered as-is without per-segment sanitization. Caller\n * (ContentRenderer) is expected to have already sanitized — or explicitly\n * opted out — at the top level.\n */\n unsafe?: boolean;\n}\n\n/**\n * Internal component that renders an HTML string with extension support.\n * Plain HTML segments use dangerouslySetInnerHTML; custom-tag segments\n * are rendered via their registered React component.\n */\nexport function RenderedContent({\n html,\n extensions: instanceExtensions,\n unsafe = false,\n}: RenderedContentProps) {\n const extensions = useMemo(\n () => mergeExtensions(instanceExtensions),\n [instanceExtensions],\n );\n\n const segments = useMemo(\n () => parseSegments(html, extensions),\n [html, extensions],\n );\n\n const renderHtml = (content: string): string =>\n unsafe ? content : sanitizeHtml(content);\n\n // Fast path: no extensions matched — single dangerouslySetInnerHTML\n if (segments.length === 1 && segments[0].type === \"html\") {\n return <div dangerouslySetInnerHTML={{ __html: renderHtml(segments[0].content) }} />;\n }\n\n // No content at all\n if (segments.length === 0) {\n return null;\n }\n\n return (\n <>\n {segments.map((segment, i) => {\n if (segment.type === \"html\") {\n return segment.content ? (\n <div key={i} dangerouslySetInnerHTML={{ __html: renderHtml(segment.content) }} />\n ) : null;\n }\n\n const ext = extensions.find(\n (e) => e.tag.toLowerCase() === segment.tag,\n );\n if (!ext) return null;\n\n const Component = ext.component;\n const isBlock = ext.block !== false;\n const Wrapper = isBlock ? \"div\" : \"span\";\n\n return (\n <Wrapper key={i} data-render-extension={segment.tag}>\n <Component content={segment.content} attributes={segment.attributes} />\n </Wrapper>\n );\n })}\n </>\n );\n}\n\nRenderedContent.displayName = \"RenderedContent\";\n","import { useMemo } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { markdownToRawHtml } from \"../../utils/markdown\";\nimport { sanitizeHtml } from \"../../utils/sanitize\";\nimport { proseClasses, detectFormat } from \"../Editor/editor.utils\";\nimport { mergeExtensions } from \"./extensions\";\nimport { RenderedContent } from \"./RenderedContent\";\nimport type { ContentRendererProps } from \"./ContentRenderer.types\";\n\nexport function ContentRenderer({\n value,\n format = \"auto\",\n lineSpacing = 1.6,\n className,\n extensions: instanceExtensions,\n unsafe = false,\n}: ContentRendererProps) {\n const extensions = useMemo(\n () => mergeExtensions(instanceExtensions),\n [instanceExtensions],\n );\n\n const html = useMemo(() => {\n // Guard nullish input: marked.parse throws \"input parameter is undefined\n // or null\", which (inside this useMemo during render) would crash the whole\n // React tree. Treat missing content as empty.\n const safe = value ?? \"\";\n const resolvedFormat = format === \"auto\" ? detectFormat(safe) : format;\n const raw = resolvedFormat === \"markdown\" ? markdownToRawHtml(safe) : safe;\n return unsafe ? raw : sanitizeHtml(raw);\n }, [value, format, unsafe]);\n\n const hasExtensions = extensions.length > 0;\n\n return (\n <div\n data-react-fancy-content-renderer=\"\"\n style={{ lineHeight: lineSpacing }}\n className={cn(\"text-sm\", proseClasses, className)}\n >\n {hasExtensions ? (\n <RenderedContent html={html} extensions={extensions} unsafe={unsafe} />\n ) : (\n <div dangerouslySetInnerHTML={{ __html: html }} />\n )}\n </div>\n );\n}\n\nContentRenderer.displayName = \"ContentRenderer\";\n"]}
1
+ {"version":3,"sources":["../src/components/ContentRenderer/extensions.ts","../src/utils/markdown.ts","../src/components/Editor/editor.utils.ts","../src/components/ContentRenderer/RenderedContent.tsx","../src/components/ContentRenderer/ContentRenderer.tsx"],"names":["marked","sanitizeHtml","useMemo","jsx","Fragment","cn"],"mappings":"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","file":"chunk-5IWKZ2WK.cjs","sourcesContent":["import type { ComponentType } from \"react\";\n\n/** Props passed to every render-extension component. */\nexport interface RenderExtensionProps {\n /** The inner content of the custom tag (raw string). */\n content: string;\n /** Parsed HTML attributes from the opening tag. */\n attributes: Record<string, string>;\n}\n\n/** Registers a custom tag with a React component for rendering. */\nexport interface RenderExtension {\n /** Tag name to match, e.g. \"questions\", \"thinking\". Case-insensitive. */\n tag: string;\n /** React component that renders the matched tag. */\n component: ComponentType<RenderExtensionProps>;\n /**\n * Whether this is a block-level element.\n * Block extensions are wrapped in a `<div>`, inline in a `<span>`.\n * @default true\n */\n block?: boolean;\n}\n\n/** A parsed segment — either raw HTML or a matched extension tag. */\nexport type ContentSegment =\n | { type: \"html\"; content: string }\n | { type: \"extension\"; tag: string; content: string; attributes: Record<string, string> };\n\n// ---------------------------------------------------------------------------\n// Global extension registry\n// ---------------------------------------------------------------------------\n\nconst globalRegistry: RenderExtension[] = [];\n\n/** Register a single render extension globally (available to all ContentRenderer and Editor instances). */\nexport function registerExtension(extension: RenderExtension): void {\n const idx = globalRegistry.findIndex(\n (e) => e.tag.toLowerCase() === extension.tag.toLowerCase(),\n );\n if (idx >= 0) {\n globalRegistry[idx] = extension;\n } else {\n globalRegistry.push(extension);\n }\n}\n\n/** Register multiple render extensions globally. */\nexport function registerExtensions(extensions: RenderExtension[]): void {\n for (const ext of extensions) {\n registerExtension(ext);\n }\n}\n\n/** Get a snapshot of the current global registry. */\nexport function getGlobalExtensions(): RenderExtension[] {\n return [...globalRegistry];\n}\n\n// ---------------------------------------------------------------------------\n// Parsing\n// ---------------------------------------------------------------------------\n\n/** Parse attributes from an opening tag string like `tag foo=\"bar\" baz=\"qux\"`. */\nfunction parseAttributes(attrString: string): Record<string, string> {\n const attrs: Record<string, string> = {};\n const re = /(\\w[\\w-]*)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|(\\S+)))?/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(attrString)) !== null) {\n attrs[m[1]] = m[2] ?? m[3] ?? m[4] ?? \"\";\n }\n return attrs;\n}\n\n/**\n * Split an HTML string into segments of plain HTML and matched extension tags.\n *\n * Handles:\n * - `<tag>content</tag>`\n * - `<tag attr=\"val\">content</tag>`\n * - Nested different-tags inside the content (preserved as raw HTML)\n * - Self-nesting of the same tag (greedy — matches outermost)\n */\nexport function parseSegments(\n html: string,\n extensions: RenderExtension[],\n): ContentSegment[] {\n if (extensions.length === 0) {\n return html ? [{ type: \"html\", content: html }] : [];\n }\n\n const tagNames = extensions.map((e) => e.tag).join(\"|\");\n // Match opening tag with optional attributes, then content, then closing tag.\n // Uses a non-greedy match for content — if same-tag nesting is needed the\n // consumer should use distinct tag names.\n const pattern = new RegExp(\n `<(${tagNames})((?:\\\\s+[^>]*)?)>([\\\\s\\\\S]*?)<\\\\/\\\\1>`,\n \"gi\",\n );\n\n const segments: ContentSegment[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(html)) !== null) {\n // Push any HTML before this match\n if (match.index > lastIndex) {\n segments.push({ type: \"html\", content: html.slice(lastIndex, match.index) });\n }\n\n const tag = match[1].toLowerCase();\n const rawAttrs = match[2] ? match[2].trim() : \"\";\n const innerContent = match[3];\n\n segments.push({\n type: \"extension\",\n tag,\n content: innerContent,\n attributes: rawAttrs ? parseAttributes(rawAttrs) : {},\n });\n\n lastIndex = match.index + match[0].length;\n }\n\n // Push any trailing HTML\n if (lastIndex < html.length) {\n segments.push({ type: \"html\", content: html.slice(lastIndex) });\n }\n\n return segments;\n}\n\n/**\n * Merge per-instance extensions with the global registry.\n * Instance extensions override globals with the same tag name.\n */\nexport function mergeExtensions(\n instanceExtensions?: RenderExtension[],\n): RenderExtension[] {\n const globals = getGlobalExtensions();\n if (!instanceExtensions || instanceExtensions.length === 0) return globals;\n if (globals.length === 0) return instanceExtensions;\n\n const merged = [...globals];\n for (const ext of instanceExtensions) {\n const idx = merged.findIndex(\n (e) => e.tag.toLowerCase() === ext.tag.toLowerCase(),\n );\n if (idx >= 0) {\n merged[idx] = ext;\n } else {\n merged.push(ext);\n }\n }\n return merged;\n}\n","import { marked } from \"marked\";\nimport { sanitizeHtml, type SanitizeHtmlOptions } from \"./sanitize\";\n\n/**\n * Parse markdown to HTML WITHOUT sanitising. Internal: ContentRenderer's\n * `unsafe` path needs the raw output; everything public goes through\n * {@link renderMarkdown}.\n */\nexport function markdownToRawHtml(markdown: string | null | undefined): string {\n // marked.parse throws on nullish input; treat missing content as empty.\n return marked.parse(markdown ?? \"\", { async: false }) as string;\n}\n\n/**\n * Render markdown (GitHub-flavoured) to sanitised HTML — the same parser and\n * output `ContentRenderer` uses, so a host never has to import the parser\n * itself.\n *\n * With no `sanitize` options the default blocklist of {@link sanitizeHtml} is\n * applied; pass allowlist options to keep only what you list:\n *\n * ```ts\n * renderMarkdown(md, { allowedTags: [\"p\", \"strong\", \"a\"], allowedAttributes: [\"href\"] })\n * ```\n */\nexport function renderMarkdown(\n markdown: string,\n sanitize?: SanitizeHtmlOptions,\n): string {\n return sanitizeHtml(markdownToRawHtml(markdown), sanitize);\n}\n","import type { RenderExtension } from \"../ContentRenderer/extensions\";\n\n/**\n * Shared prose typography classes for Editor.Content and ContentRenderer.\n * Hand-rolled since we don't depend on @tailwindcss/typography.\n */\nexport const proseClasses = [\n \"[&_h1]:text-2xl [&_h1]:font-bold [&_h1]:mt-4 [&_h1]:mb-2\",\n \"[&_h2]:text-xl [&_h2]:font-semibold [&_h2]:mt-3 [&_h2]:mb-2\",\n \"[&_h3]:text-lg [&_h3]:font-semibold [&_h3]:mt-2 [&_h3]:mb-1\",\n \"[&_p]:mb-2\",\n \"[&_a]:text-blue-500 [&_a]:underline\",\n \"[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5\",\n \"[&_li]:mb-1\",\n \"[&_blockquote]:border-l-4 [&_blockquote]:border-zinc-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] dark:[&_blockquote]:border-zinc-600 dark:[&_blockquote]:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))]\",\n \"[&_code]:bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] [&_code]:px-1 [&_code]:rounded [&_code]:text-sm dark:[&_code]:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\",\n \"[&_pre]:bg-zinc-950 [&_pre]:text-zinc-100 [&_pre]:p-4 [&_pre]:rounded-lg [&_pre]:overflow-x-auto\",\n \"[&_pre_code]:bg-transparent [&_pre_code]:px-0\",\n \"[&_strong]:font-bold [&_em]:italic\",\n].join(\" \");\n\nconst HTML_TAG_PATTERN = /<(p|div|br|h[1-6]|ul|ol|strong|em|a |img |table|pre|code|blockquote)[>\\s/]/i;\n\n/** Detect whether a string is likely HTML or Markdown. */\nexport function detectFormat(value: string): \"html\" | \"markdown\" {\n return HTML_TAG_PATTERN.test(value) ? \"html\" : \"markdown\";\n}\n\n/**\n * Build a set of known HTML tag names. Extension tags are excluded\n * so that the \"strip remaining tags\" step preserves them.\n */\nconst STANDARD_HTML_TAGS = new Set([\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\",\n \"b\", \"base\", \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\",\n \"canvas\", \"caption\", \"cite\", \"code\", \"col\", \"colgroup\",\n \"data\", \"datalist\", \"dd\", \"del\", \"details\", \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\",\n \"em\", \"embed\",\n \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\",\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hgroup\", \"hr\", \"html\",\n \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\",\n \"label\", \"legend\", \"li\", \"link\",\n \"main\", \"map\", \"mark\", \"menu\", \"meta\", \"meter\",\n \"nav\", \"noscript\",\n \"object\", \"ol\", \"optgroup\", \"option\", \"output\",\n \"p\", \"param\", \"picture\", \"pre\", \"progress\",\n \"q\",\n \"rp\", \"rt\", \"ruby\",\n \"s\", \"samp\", \"script\", \"section\", \"select\", \"slot\", \"small\", \"source\", \"span\",\n \"strike\", \"strong\", \"style\", \"sub\", \"summary\", \"sup\",\n \"table\", \"tbody\", \"td\", \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\", \"time\", \"title\", \"tr\", \"track\",\n \"u\", \"ul\",\n \"var\", \"video\",\n \"wbr\",\n]);\n\n/**\n * Lightweight HTML-to-Markdown converter for editor output.\n * Handles the most common inline/block formatting produced by contentEditable.\n * Custom extension tags are preserved as-is in the output.\n */\nexport function htmlToMarkdown(html: string): string {\n let md = html;\n\n // Block elements first\n md = md.replace(/<h1[^>]*>(.*?)<\\/h1>/gi, \"# $1\\n\");\n md = md.replace(/<h2[^>]*>(.*?)<\\/h2>/gi, \"## $1\\n\");\n md = md.replace(/<h3[^>]*>(.*?)<\\/h3>/gi, \"### $1\\n\");\n md = md.replace(/<h4[^>]*>(.*?)<\\/h4>/gi, \"#### $1\\n\");\n md = md.replace(/<h5[^>]*>(.*?)<\\/h5>/gi, \"##### $1\\n\");\n md = md.replace(/<h6[^>]*>(.*?)<\\/h6>/gi, \"###### $1\\n\");\n\n // Lists\n md = md.replace(/<li[^>]*>(.*?)<\\/li>/gi, \"- $1\\n\");\n md = md.replace(/<\\/?[uo]l[^>]*>/gi, \"\\n\");\n\n // Inline formatting\n md = md.replace(/<strong[^>]*>(.*?)<\\/strong>/gi, \"**$1**\");\n md = md.replace(/<b[^>]*>(.*?)<\\/b>/gi, \"**$1**\");\n md = md.replace(/<em[^>]*>(.*?)<\\/em>/gi, \"*$1*\");\n md = md.replace(/<i[^>]*>(.*?)<\\/i>/gi, \"*$1*\");\n md = md.replace(/<u[^>]*>(.*?)<\\/u>/gi, \"$1\");\n md = md.replace(/<s[^>]*>(.*?)<\\/s>/gi, \"~~$1~~\");\n md = md.replace(/<strike[^>]*>(.*?)<\\/strike>/gi, \"~~$1~~\");\n md = md.replace(/<del[^>]*>(.*?)<\\/del>/gi, \"~~$1~~\");\n md = md.replace(/<code[^>]*>(.*?)<\\/code>/gi, \"`$1`\");\n\n // Links\n md = md.replace(/<a[^>]*href=\"([^\"]*)\"[^>]*>(.*?)<\\/a>/gi, \"[$2]($1)\");\n\n // Blockquotes\n md = md.replace(/<blockquote[^>]*>(.*?)<\\/blockquote>/gi, \"> $1\\n\");\n\n // Line breaks and paragraphs\n md = md.replace(/<br\\s*\\/?>/gi, \"\\n\");\n md = md.replace(/<p[^>]*>(.*?)<\\/p>/gi, \"$1\\n\\n\");\n md = md.replace(/<div[^>]*>(.*?)<\\/div>/gi, \"$1\\n\");\n\n // Strip only standard HTML tags — preserve unknown/custom tags\n md = md.replace(/<\\/?([a-z][a-z0-9]*)\\b[^>]*>/gi, (match, tagName: string) => {\n return STANDARD_HTML_TAGS.has(tagName.toLowerCase()) ? \"\" : match;\n });\n\n // Decode common HTML entities. Decode &amp; LAST so we never double-unescape:\n // e.g. \"&amp;lt;\" must decode to the literal \"&lt;\", not to \"<\".\n md = md.replace(/&lt;/g, \"<\");\n md = md.replace(/&gt;/g, \">\");\n md = md.replace(/&quot;/g, '\"');\n md = md.replace(/&#39;/g, \"'\");\n md = md.replace(/&nbsp;/g, \" \");\n md = md.replace(/&amp;/g, \"&\");\n\n // Clean up extra whitespace\n md = md.replace(/\\n{3,}/g, \"\\n\\n\");\n md = md.trim();\n\n return md;\n}\n\n/**\n * Generate CSS classes to visually distinguish custom extension tags\n * inside the contentEditable area. Returns Tailwind-style descendant selectors.\n */\nexport function extensionEditorClasses(extensions: RenderExtension[]): string {\n if (extensions.length === 0) return \"\";\n\n return extensions\n .map((ext) => {\n const tag = ext.tag.toLowerCase();\n return [\n `[&_${tag}]:block`,\n `[&_${tag}]:my-2`,\n `[&_${tag}]:rounded-lg`,\n `[&_${tag}]:border`,\n `[&_${tag}]:border-dashed`,\n `[&_${tag}]:border-zinc-300`,\n `[&_${tag}]:bg-zinc-50`,\n `[&_${tag}]:p-3`,\n `[&_${tag}]:text-xs`,\n `dark:[&_${tag}]:border-zinc-600`,\n `dark:[&_${tag}]:bg-zinc-800/50`,\n ].join(\" \");\n })\n .join(\" \");\n}\n","import { useMemo } from \"react\";\nimport { sanitizeHtml } from \"../../utils/sanitize\";\nimport type { RenderExtension } from \"./extensions\";\nimport { parseSegments, mergeExtensions } from \"./extensions\";\n\ninterface RenderedContentProps {\n html: string;\n extensions?: RenderExtension[];\n /**\n * If true, html is rendered as-is without per-segment sanitization. Caller\n * (ContentRenderer) is expected to have already sanitized — or explicitly\n * opted out — at the top level.\n */\n unsafe?: boolean;\n}\n\n/**\n * Internal component that renders an HTML string with extension support.\n * Plain HTML segments use dangerouslySetInnerHTML; custom-tag segments\n * are rendered via their registered React component.\n */\nexport function RenderedContent({\n html,\n extensions: instanceExtensions,\n unsafe = false,\n}: RenderedContentProps) {\n const extensions = useMemo(\n () => mergeExtensions(instanceExtensions),\n [instanceExtensions],\n );\n\n const segments = useMemo(\n () => parseSegments(html, extensions),\n [html, extensions],\n );\n\n const renderHtml = (content: string): string =>\n unsafe ? content : sanitizeHtml(content);\n\n // Fast path: no extensions matched — single dangerouslySetInnerHTML\n if (segments.length === 1 && segments[0].type === \"html\") {\n return <div dangerouslySetInnerHTML={{ __html: renderHtml(segments[0].content) }} />;\n }\n\n // No content at all\n if (segments.length === 0) {\n return null;\n }\n\n return (\n <>\n {segments.map((segment, i) => {\n if (segment.type === \"html\") {\n return segment.content ? (\n <div key={i} dangerouslySetInnerHTML={{ __html: renderHtml(segment.content) }} />\n ) : null;\n }\n\n const ext = extensions.find(\n (e) => e.tag.toLowerCase() === segment.tag,\n );\n if (!ext) return null;\n\n const Component = ext.component;\n const isBlock = ext.block !== false;\n const Wrapper = isBlock ? \"div\" : \"span\";\n\n return (\n <Wrapper key={i} data-render-extension={segment.tag}>\n <Component content={segment.content} attributes={segment.attributes} />\n </Wrapper>\n );\n })}\n </>\n );\n}\n\nRenderedContent.displayName = \"RenderedContent\";\n","import { useMemo } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { markdownToRawHtml } from \"../../utils/markdown\";\nimport { sanitizeHtml } from \"../../utils/sanitize\";\nimport { proseClasses, detectFormat } from \"../Editor/editor.utils\";\nimport { mergeExtensions } from \"./extensions\";\nimport { RenderedContent } from \"./RenderedContent\";\nimport type { ContentRendererProps } from \"./ContentRenderer.types\";\n\nexport function ContentRenderer({\n value,\n format = \"auto\",\n lineSpacing = 1.6,\n className,\n extensions: instanceExtensions,\n unsafe = false,\n}: ContentRendererProps) {\n const extensions = useMemo(\n () => mergeExtensions(instanceExtensions),\n [instanceExtensions],\n );\n\n const html = useMemo(() => {\n // Guard nullish input: marked.parse throws \"input parameter is undefined\n // or null\", which (inside this useMemo during render) would crash the whole\n // React tree. Treat missing content as empty.\n const safe = value ?? \"\";\n const resolvedFormat = format === \"auto\" ? detectFormat(safe) : format;\n const raw = resolvedFormat === \"markdown\" ? markdownToRawHtml(safe) : safe;\n return unsafe ? raw : sanitizeHtml(raw);\n }, [value, format, unsafe]);\n\n const hasExtensions = extensions.length > 0;\n\n return (\n <div\n data-react-fancy-content-renderer=\"\"\n style={{ lineHeight: lineSpacing }}\n className={cn(\"text-sm\", proseClasses, className)}\n >\n {hasExtensions ? (\n <RenderedContent html={html} extensions={extensions} unsafe={unsafe} />\n ) : (\n <div dangerouslySetInnerHTML={{ __html: html }} />\n )}\n </div>\n );\n}\n\nContentRenderer.displayName = \"ContentRenderer\";\n"]}
@@ -80,7 +80,7 @@ function AccordionContent({
80
80
  "grid transition-all duration-200",
81
81
  isOpen ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
82
82
  ),
83
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkZU5Q77OT_cjs.cn("pb-4 text-sm text-zinc-600 dark:text-zinc-400", className), children }) })
83
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkZU5Q77OT_cjs.cn("pb-4 text-sm text-[color:var(--fancy-text-subtle,var(--color-zinc-600))] dark:text-[color:var(--fancy-text-subtle-dark,var(--color-zinc-400))]", className), children }) })
84
84
  }
85
85
  );
86
86
  }
@@ -118,5 +118,5 @@ var Accordion = Object.assign(AccordionRoot, {
118
118
 
119
119
  exports.Accordion = Accordion;
120
120
  exports.useAccordion = useAccordion;
121
- //# sourceMappingURL=chunk-546K5LRX.cjs.map
122
- //# sourceMappingURL=chunk-546K5LRX.cjs.map
121
+ //# sourceMappingURL=chunk-CVDL6C2O.cjs.map
122
+ //# sourceMappingURL=chunk-CVDL6C2O.cjs.map