@mieweb/ui 0.11.0-dev.44 → 0.11.0-dev.46

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 (208) hide show
  1. package/dist/{EncounterMdyEditor-L7RBLE7B.js → EncounterMdyEditor-ATNWXQ72.js} +3 -3
  2. package/dist/{EncounterMdyEditor-L7RBLE7B.js.map → EncounterMdyEditor-ATNWXQ72.js.map} +1 -1
  3. package/dist/{EncounterMdyEditor-46WMYRFI.cjs → EncounterMdyEditor-XA7HLLVD.cjs} +6 -6
  4. package/dist/{EncounterMdyEditor-46WMYRFI.cjs.map → EncounterMdyEditor-XA7HLLVD.cjs.map} +1 -1
  5. package/dist/ag-grid.cjs +2 -2
  6. package/dist/ag-grid.js +1 -1
  7. package/dist/{chunk-L3CAWGBU.js → chunk-2D6TFO2Y.js} +3 -3
  8. package/dist/{chunk-L3CAWGBU.js.map → chunk-2D6TFO2Y.js.map} +1 -1
  9. package/dist/{chunk-AHYDJN4H.cjs → chunk-2XHPPOXY.cjs} +32 -32
  10. package/dist/{chunk-AHYDJN4H.cjs.map → chunk-2XHPPOXY.cjs.map} +1 -1
  11. package/dist/{chunk-3IKIRGHI.cjs → chunk-3H6BQV2D.cjs} +6 -6
  12. package/dist/{chunk-3IKIRGHI.cjs.map → chunk-3H6BQV2D.cjs.map} +1 -1
  13. package/dist/{chunk-IIV5GNSK.cjs → chunk-3PT4B4JT.cjs} +4 -4
  14. package/dist/{chunk-IIV5GNSK.cjs.map → chunk-3PT4B4JT.cjs.map} +1 -1
  15. package/dist/{chunk-GLG6UE2H.cjs → chunk-3SEQVGLH.cjs} +4 -4
  16. package/dist/{chunk-GLG6UE2H.cjs.map → chunk-3SEQVGLH.cjs.map} +1 -1
  17. package/dist/{chunk-JUY2JLFL.js → chunk-3XDU7XIC.js} +3 -3
  18. package/dist/{chunk-JUY2JLFL.js.map → chunk-3XDU7XIC.js.map} +1 -1
  19. package/dist/{chunk-LQ22CY7X.js → chunk-46ZUORUE.js} +5 -5
  20. package/dist/{chunk-LQ22CY7X.js.map → chunk-46ZUORUE.js.map} +1 -1
  21. package/dist/{chunk-CKECOCYJ.js → chunk-4IOIDS2Z.js} +3 -3
  22. package/dist/{chunk-CKECOCYJ.js.map → chunk-4IOIDS2Z.js.map} +1 -1
  23. package/dist/{chunk-NCG7NJAW.cjs → chunk-5O54NWAL.cjs} +83 -9
  24. package/dist/chunk-5O54NWAL.cjs.map +1 -0
  25. package/dist/{chunk-XX6PNPF2.cjs → chunk-5UKGOBCZ.cjs} +16 -2
  26. package/dist/chunk-5UKGOBCZ.cjs.map +1 -0
  27. package/dist/{chunk-HH7PWD5I.cjs → chunk-6I2G26AX.cjs} +27 -23
  28. package/dist/chunk-6I2G26AX.cjs.map +1 -0
  29. package/dist/{chunk-F7SZSOB3.js → chunk-6PCA5H47.js} +3 -3
  30. package/dist/{chunk-F7SZSOB3.js.map → chunk-6PCA5H47.js.map} +1 -1
  31. package/dist/{chunk-ULEX7OOJ.js → chunk-6Y6W5DUY.js} +4 -4
  32. package/dist/{chunk-ULEX7OOJ.js.map → chunk-6Y6W5DUY.js.map} +1 -1
  33. package/dist/{chunk-S7AMZ4RD.cjs → chunk-7K6SW4VB.cjs} +4 -4
  34. package/dist/{chunk-S7AMZ4RD.cjs.map → chunk-7K6SW4VB.cjs.map} +1 -1
  35. package/dist/{chunk-KY67AMQ5.cjs → chunk-7MF3O3BU.cjs} +4 -4
  36. package/dist/{chunk-KY67AMQ5.cjs.map → chunk-7MF3O3BU.cjs.map} +1 -1
  37. package/dist/{chunk-Z3WMDVMR.cjs → chunk-7QNBPB7F.cjs} +9 -5
  38. package/dist/chunk-7QNBPB7F.cjs.map +1 -0
  39. package/dist/{chunk-YFWDS6MX.js → chunk-AB24H2RM.js} +3 -3
  40. package/dist/{chunk-YFWDS6MX.js.map → chunk-AB24H2RM.js.map} +1 -1
  41. package/dist/{chunk-2W73UQ3T.js → chunk-BPYI7BDC.js} +3 -3
  42. package/dist/{chunk-2W73UQ3T.js.map → chunk-BPYI7BDC.js.map} +1 -1
  43. package/dist/{chunk-EAAVFTKI.cjs → chunk-BUM72SAI.cjs} +35 -17
  44. package/dist/chunk-BUM72SAI.cjs.map +1 -0
  45. package/dist/{chunk-AHT2HRHC.cjs → chunk-CFT3P5KP.cjs} +16 -16
  46. package/dist/{chunk-AHT2HRHC.cjs.map → chunk-CFT3P5KP.cjs.map} +1 -1
  47. package/dist/{chunk-7U7SONM5.js → chunk-CVCUQ2MZ.js} +3 -3
  48. package/dist/{chunk-7U7SONM5.js.map → chunk-CVCUQ2MZ.js.map} +1 -1
  49. package/dist/{chunk-PWXDRFJL.cjs → chunk-DHEOWRIE.cjs} +6 -6
  50. package/dist/{chunk-PWXDRFJL.cjs.map → chunk-DHEOWRIE.cjs.map} +1 -1
  51. package/dist/{chunk-2KK4WZ7Y.cjs → chunk-F6ZTKNAL.cjs} +4 -4
  52. package/dist/{chunk-2KK4WZ7Y.cjs.map → chunk-F6ZTKNAL.cjs.map} +1 -1
  53. package/dist/{chunk-OYUIEJPN.js → chunk-GTRYDFMT.js} +38 -10
  54. package/dist/chunk-GTRYDFMT.js.map +1 -0
  55. package/dist/{chunk-2FZYZ4HT.cjs → chunk-HDSYYQYM.cjs} +4 -4
  56. package/dist/{chunk-2FZYZ4HT.cjs.map → chunk-HDSYYQYM.cjs.map} +1 -1
  57. package/dist/{chunk-JCIQIR5V.js → chunk-IGUDEWIW.js} +4 -4
  58. package/dist/{chunk-JCIQIR5V.js.map → chunk-IGUDEWIW.js.map} +1 -1
  59. package/dist/{chunk-DIIXY6EB.js → chunk-IYXZ25E6.js} +27 -9
  60. package/dist/chunk-IYXZ25E6.js.map +1 -0
  61. package/dist/{chunk-YVKBXNPK.js → chunk-JBNQ2L3K.js} +10 -6
  62. package/dist/chunk-JBNQ2L3K.js.map +1 -0
  63. package/dist/{chunk-GU6TPVXF.cjs → chunk-JK2IWOI7.cjs} +6 -6
  64. package/dist/{chunk-GU6TPVXF.cjs.map → chunk-JK2IWOI7.cjs.map} +1 -1
  65. package/dist/{chunk-TZKBW4GA.cjs → chunk-K76UNS22.cjs} +6 -6
  66. package/dist/{chunk-TZKBW4GA.cjs.map → chunk-K76UNS22.cjs.map} +1 -1
  67. package/dist/{chunk-DAAJ3B2T.js → chunk-KP72MDFB.js} +4 -4
  68. package/dist/{chunk-DAAJ3B2T.js.map → chunk-KP72MDFB.js.map} +1 -1
  69. package/dist/{chunk-MLCIINXT.js → chunk-LBUXS6FJ.js} +4 -4
  70. package/dist/{chunk-MLCIINXT.js.map → chunk-LBUXS6FJ.js.map} +1 -1
  71. package/dist/{chunk-MD55WRGN.cjs → chunk-LE3HZ7MM.cjs} +37 -37
  72. package/dist/{chunk-MD55WRGN.cjs.map → chunk-LE3HZ7MM.cjs.map} +1 -1
  73. package/dist/{chunk-GG3IK5TL.cjs → chunk-MQK2D6I6.cjs} +9 -9
  74. package/dist/{chunk-GG3IK5TL.cjs.map → chunk-MQK2D6I6.cjs.map} +1 -1
  75. package/dist/{chunk-3A4N5E6P.js → chunk-N6STVVB6.js} +3 -3
  76. package/dist/{chunk-3A4N5E6P.js.map → chunk-N6STVVB6.js.map} +1 -1
  77. package/dist/{chunk-5WA6IYZD.js → chunk-NB2C6FSI.js} +16 -2
  78. package/dist/chunk-NB2C6FSI.js.map +1 -0
  79. package/dist/{chunk-2GBVJHWN.cjs → chunk-NH5JOZLG.cjs} +13 -13
  80. package/dist/{chunk-2GBVJHWN.cjs.map → chunk-NH5JOZLG.cjs.map} +1 -1
  81. package/dist/{chunk-NWU634SO.cjs → chunk-O2EAHOXM.cjs} +4 -4
  82. package/dist/{chunk-NWU634SO.cjs.map → chunk-O2EAHOXM.cjs.map} +1 -1
  83. package/dist/{chunk-JUYBJLPI.cjs → chunk-O7Y56J4R.cjs} +4 -4
  84. package/dist/{chunk-JUYBJLPI.cjs.map → chunk-O7Y56J4R.cjs.map} +1 -1
  85. package/dist/{chunk-GLRKXJCR.js → chunk-OX32ITWC.js} +3 -3
  86. package/dist/{chunk-GLRKXJCR.js.map → chunk-OX32ITWC.js.map} +1 -1
  87. package/dist/{chunk-L4APW65W.cjs → chunk-PJ4XEBMU.cjs} +4 -4
  88. package/dist/{chunk-L4APW65W.cjs.map → chunk-PJ4XEBMU.cjs.map} +1 -1
  89. package/dist/{chunk-OZKJYLN6.js → chunk-PSCSU63K.js} +3 -3
  90. package/dist/{chunk-OZKJYLN6.js.map → chunk-PSCSU63K.js.map} +1 -1
  91. package/dist/{chunk-ZULFKL3C.js → chunk-QJ75ZMCG.js} +7 -7
  92. package/dist/{chunk-ZULFKL3C.js.map → chunk-QJ75ZMCG.js.map} +1 -1
  93. package/dist/{chunk-EI4JU5JF.js → chunk-RKM4VGAN.js} +3 -3
  94. package/dist/{chunk-EI4JU5JF.js.map → chunk-RKM4VGAN.js.map} +1 -1
  95. package/dist/{chunk-ME7EVT6F.js → chunk-RYGVILUR.js} +3 -3
  96. package/dist/{chunk-ME7EVT6F.js.map → chunk-RYGVILUR.js.map} +1 -1
  97. package/dist/{chunk-EGPDT7SM.js → chunk-S7NJV335.js} +3 -3
  98. package/dist/{chunk-EGPDT7SM.js.map → chunk-S7NJV335.js.map} +1 -1
  99. package/dist/{chunk-TERHGQ73.cjs → chunk-U7XWWU5H.cjs} +5 -5
  100. package/dist/{chunk-TERHGQ73.cjs.map → chunk-U7XWWU5H.cjs.map} +1 -1
  101. package/dist/{chunk-G35LXI2A.js → chunk-UIFN2LYT.js} +3 -3
  102. package/dist/{chunk-G35LXI2A.js.map → chunk-UIFN2LYT.js.map} +1 -1
  103. package/dist/{chunk-NIE3WBJH.js → chunk-ULKDK6W6.js} +83 -9
  104. package/dist/chunk-ULKDK6W6.js.map +1 -0
  105. package/dist/{chunk-KB2PLV5Q.js → chunk-VQGRMCVT.js} +4 -4
  106. package/dist/{chunk-KB2PLV5Q.js.map → chunk-VQGRMCVT.js.map} +1 -1
  107. package/dist/{chunk-IPHJQ6CF.js → chunk-WI35L5TR.js} +10 -6
  108. package/dist/chunk-WI35L5TR.js.map +1 -0
  109. package/dist/{chunk-Q6QLGCL7.cjs → chunk-XCCH5KHW.cjs} +9 -9
  110. package/dist/{chunk-Q6QLGCL7.cjs.map → chunk-XCCH5KHW.cjs.map} +1 -1
  111. package/dist/{chunk-KQXD6BFO.cjs → chunk-XM3D4KAF.cjs} +9 -9
  112. package/dist/{chunk-KQXD6BFO.cjs.map → chunk-XM3D4KAF.cjs.map} +1 -1
  113. package/dist/{chunk-PINIBEIU.cjs → chunk-XRXOGMMG.cjs} +39 -11
  114. package/dist/chunk-XRXOGMMG.cjs.map +1 -0
  115. package/dist/{chunk-XPWFIDZM.cjs → chunk-XU3X2AUL.cjs} +4 -4
  116. package/dist/{chunk-XPWFIDZM.cjs.map → chunk-XU3X2AUL.cjs.map} +1 -1
  117. package/dist/{chunk-CRR7AE5D.js → chunk-Z6I4XFPC.js} +3 -3
  118. package/dist/{chunk-CRR7AE5D.js.map → chunk-Z6I4XFPC.js.map} +1 -1
  119. package/dist/{chunk-LTCHD3K5.cjs → chunk-Z7ZOSENN.cjs} +5 -5
  120. package/dist/{chunk-LTCHD3K5.cjs.map → chunk-Z7ZOSENN.cjs.map} +1 -1
  121. package/dist/{chunk-NZUQL42A.cjs → chunk-ZDA6FEKA.cjs} +5 -5
  122. package/dist/{chunk-NZUQL42A.cjs.map → chunk-ZDA6FEKA.cjs.map} +1 -1
  123. package/dist/{chunk-UY2EZYIC.js → chunk-ZSBG6C3P.js} +3 -3
  124. package/dist/{chunk-UY2EZYIC.js.map → chunk-ZSBG6C3P.js.map} +1 -1
  125. package/dist/{chunk-KAQNYX7B.js → chunk-ZVRJVUFX.js} +3 -3
  126. package/dist/{chunk-KAQNYX7B.js.map → chunk-ZVRJVUFX.js.map} +1 -1
  127. package/dist/components/AudioPlayer/index.cjs +7 -7
  128. package/dist/components/AudioPlayer/index.js +2 -2
  129. package/dist/components/BoardView/index.cjs +5 -5
  130. package/dist/components/BoardView/index.js +2 -2
  131. package/dist/components/CollabStatus/index.cjs +5 -5
  132. package/dist/components/CollabStatus/index.js +2 -2
  133. package/dist/components/Dropdown/index.cjs +9 -9
  134. package/dist/components/Dropdown/index.d.cts +6 -1
  135. package/dist/components/Dropdown/index.d.ts +6 -1
  136. package/dist/components/Dropdown/index.js +2 -2
  137. package/dist/components/EmailEditor/index.cjs +17 -17
  138. package/dist/components/EmailEditor/index.js +8 -8
  139. package/dist/components/MediaEditor/index.cjs +10 -10
  140. package/dist/components/MediaEditor/index.js +5 -5
  141. package/dist/components/MediaFeed/index.cjs +6 -6
  142. package/dist/components/MediaFeed/index.js +5 -5
  143. package/dist/components/MediaPlayer/index.cjs +8 -8
  144. package/dist/components/MediaPlayer/index.js +4 -4
  145. package/dist/components/MegaMenu/index.cjs +5 -5
  146. package/dist/components/MegaMenu/index.js +2 -2
  147. package/dist/components/RecordHeader/index.cjs +5 -5
  148. package/dist/components/RecordHeader/index.js +3 -3
  149. package/dist/components/RecordLayout/index.cjs +5 -5
  150. package/dist/components/RecordLayout/index.js +3 -3
  151. package/dist/components/RichTextEditor/index.cjs +6 -6
  152. package/dist/components/RichTextEditor/index.js +3 -3
  153. package/dist/components/Slider/index.cjs +6 -6
  154. package/dist/components/Slider/index.js +2 -2
  155. package/dist/components/SliderCalculator/index.cjs +5 -5
  156. package/dist/components/SliderCalculator/index.js +3 -3
  157. package/dist/components/SuperChat/index.cjs +23 -23
  158. package/dist/components/SuperChat/index.js +8 -8
  159. package/dist/components/SuperChat/plugins/index.cjs +5 -5
  160. package/dist/components/SuperChat/plugins/index.js +4 -4
  161. package/dist/components/Tabs/index.cjs +8 -8
  162. package/dist/components/Tabs/index.js +2 -2
  163. package/dist/components/Textarea/index.cjs +9 -9
  164. package/dist/components/Textarea/index.js +6 -6
  165. package/dist/components/ThemeProvider/index.cjs +9 -9
  166. package/dist/components/ThemeProvider/index.js +3 -3
  167. package/dist/components/Tooltip/index.cjs +3 -3
  168. package/dist/components/Tooltip/index.js +2 -2
  169. package/dist/components/ViewSet/index.cjs +5 -5
  170. package/dist/components/ViewSet/index.js +4 -4
  171. package/dist/components/ViewSwitcher/index.cjs +4 -4
  172. package/dist/components/ViewSwitcher/index.js +2 -2
  173. package/dist/deck.cjs +3 -3
  174. package/dist/deck.js +1 -1
  175. package/dist/esheet.cjs +109 -109
  176. package/dist/esheet.js +12 -12
  177. package/dist/hooks/index.cjs +5 -5
  178. package/dist/hooks/index.js +1 -1
  179. package/dist/index.cjs +288 -288
  180. package/dist/index.d.cts +6 -1
  181. package/dist/index.d.ts +6 -1
  182. package/dist/index.js +42 -42
  183. package/dist/kerebron.cjs +8 -8
  184. package/dist/kerebron.d.cts +27 -2
  185. package/dist/kerebron.d.ts +27 -2
  186. package/dist/kerebron.js +5 -5
  187. package/dist/{model-5PB6KNYH.cjs → model-2TISYEYF.cjs} +20 -20
  188. package/dist/{model-5PB6KNYH.cjs.map → model-2TISYEYF.cjs.map} +1 -1
  189. package/dist/{model-OGWTZEXR.js → model-BCS5BUK3.js} +6 -6
  190. package/dist/{model-OGWTZEXR.js.map → model-BCS5BUK3.js.map} +1 -1
  191. package/dist/org-chart.cjs +2 -2
  192. package/dist/org-chart.js +1 -1
  193. package/dist/styles.css +1 -1
  194. package/dist/tailwind-preset.cjs +4 -4
  195. package/dist/tailwind-preset.js +1 -1
  196. package/package.json +1 -1
  197. package/dist/chunk-5WA6IYZD.js.map +0 -1
  198. package/dist/chunk-DIIXY6EB.js.map +0 -1
  199. package/dist/chunk-EAAVFTKI.cjs.map +0 -1
  200. package/dist/chunk-HH7PWD5I.cjs.map +0 -1
  201. package/dist/chunk-IPHJQ6CF.js.map +0 -1
  202. package/dist/chunk-NCG7NJAW.cjs.map +0 -1
  203. package/dist/chunk-NIE3WBJH.js.map +0 -1
  204. package/dist/chunk-OYUIEJPN.js.map +0 -1
  205. package/dist/chunk-PINIBEIU.cjs.map +0 -1
  206. package/dist/chunk-XX6PNPF2.cjs.map +0 -1
  207. package/dist/chunk-YVKBXNPK.js.map +0 -1
  208. package/dist/chunk-Z3WMDVMR.cjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/RichEditor/mdyTransaction.ts","../src/components/RichEditor/editorKits.ts","../src/components/RichEditor/RichEditor.tsx"],"names":["AdvancedEditorKit","ExtensionCustomMenu","ExtensionMediaUpload","forwardRef","RichEditor","useIsDarkMode","useRef","useState","useReducer","useCallback","useEffect","editor","doc","CoreEditor","createAssetLoad","useImperativeHandle","jsx","jsxs"],"mappings":"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","file":"chunk-NCG7NJAW.cjs","sourcesContent":["/** Shared metadata for host-created MDY projection updates. */\nexport const MDY_PROJECTION_META = 'mdyProjectionRefresh';\n","/**\n * Editor kit assembly for {@link RichEditor}, for both plain and collaborative\n * (Yjs) mode.\n *\n * Both modes start from {@link AdvancedEditorKit} and drop the extensions that\n * are unsafe for our usage — see {@link unsafeExtensions} — then collaborative\n * mode adds the Yjs pieces on top.\n *\n * The Yjs pieces live in `collabKit.ts` behind a dynamic `import()`, so\n * `@kerebron/extension-yjs`, `yjs` and `y-protocols` remain truly optional\n * peers — plain-mode consumers never load them.\n */\nimport type { EditorKit } from '@kerebron/editor';\nimport { AdvancedEditorKit } from '@kerebron/editor-kits/AdvancedEditorKit';\nimport {\n ExtensionMediaUpload,\n type MediaUploadOptions,\n} from '@kerebron/extension-basic-editor/ExtensionMediaUpload';\nimport {\n ExtensionCustomMenu,\n type MenuElement,\n} from '@kerebron/extension-menu';\n\nexport type { MediaUploadOptions };\nexport type { MenuElement };\n\n/**\n * Reshape the toolbar menu before it renders: receives the stock menu's\n * item groups and returns the groups to render. Append custom\n * {@link MenuElement}s (e.g. a Macros toggle) or drop stock groups.\n */\nexport type ModifyMenu = (menus: MenuElement[][]) => MenuElement[][];\n\nexport interface CollabConfig {\n /** Room id — one shared document per room (e.g. a post id). */\n room: string;\n /**\n * WebSocket base URL for the Yjs relay. Defaults to\n * `<ws|wss>://<location.host>/yjs`. The room id is appended by the provider.\n */\n wsUrl?: string;\n /** Extra query params for the socket (e.g. `{ token }` for auth). */\n params?: Record<string, string>;\n /**\n * Who this editor is, published on awareness (`kerebron:user`) so peers see\n * a named, coloured cursor. Without it remote cursors do not render — the\n * position plugin skips awareness states that carry no user — and the\n * `id` is what the cursor colour is derived from (kerebron's `User` shape).\n */\n user?: { id: string; name: string; color?: string };\n /**\n * Custom WebSocket implementation handed to the Yjs provider — e.g. a\n * loopback socket for demos/tests, or a polyfill outside the browser.\n * Defaults to `globalThis.WebSocket`.\n */\n WebSocketPolyfill?: typeof globalThis.WebSocket;\n /**\n * Called when collaborative editing could not be started at all — the Yjs\n * kit failed to load (see {@link createEditorKits}). The editor mounts\n * anyway, as a local one; this is how the host finds out that edits are no\n * longer shared, so it can say so, or tear its own editor down if unshared\n * editing would be unsafe.\n *\n * Not for connection trouble: a room that is reachable but currently\n * disconnected still has the Yjs kit loaded, and the provider retries on its\n * own. This fires once, before the editor is created.\n */\n onUnavailable?: (error: unknown) => void;\n}\n\n/** What {@link createEditorKits} resolves to. */\nexport interface EditorKits {\n kits: EditorKit[];\n /**\n * Whether the returned kits can actually collaborate. False when `config`\n * asked for a room but the Yjs kit could not be loaded, so callers know not\n * to join one.\n */\n collaborative: boolean;\n}\n\n/**\n * Extensions dropped from {@link AdvancedEditorKit}, and why.\n *\n * `autocomplete` and `hover` debounce their DOM handlers (200ms) and then call\n * `dispatchMeta`, which reads `this.editor.state` with no guard that the editor\n * is still alive. Any teardown or document swap inside that debounce window\n * lands the deferred call on a dead view and throws\n * `null.matchesNode()` inside ProseMirror's `EditorView.updateStateInner`,\n * leaving the view permanently broken. Two ways to hit it:\n * - remount (e.g. a `key` change) while the pointer is over the editor, which\n * fires the debounced `onMouseLeave` after the view is destroyed;\n * - a Yjs remote update replacing the document tree under a pending callback.\n * The first applies to *every* editor, so both extensions come out in both\n * modes. No functional cost — autocomplete popups and node-hover tooltips are\n * compositor conveniences, not required for editing.\n *\n * `history` is collab-only: ExtensionYjs supplies its own CRDT-aware undo/redo\n * and the editor throws `Extension conflict: yjs vs history` if both are\n * present. Plain mode keeps it, so undo/redo still works there.\n */\nconst unsafeExtensions = ['autocomplete', 'hover'] as const;\n\n/**\n * {@link AdvancedEditorKit} minus {@link unsafeExtensions} (and, for collab\n * mode, minus `history`), with `mediaUpload` reconfigured when the host asks.\n *\n * `AdvancedEditorKit` constructs `ExtensionMediaUpload` with no options, and an\n * extension's options are fixed at construction — so the only way to configure\n * it is to drop that instance and append one of our own. `modifyMenu` works\n * the same way: the stock `ExtensionCustomMenu` is constructed with no config,\n * so customizing the toolbar means replacing it with a configured instance.\n */\nclass SafeAdvancedEditorKit implements EditorKit {\n name = 'advanced-editor';\n constructor(\n private readonly forCollab: boolean,\n private readonly mediaUpload?: MediaUploadOptions,\n private readonly modifyMenu?: ModifyMenu\n ) {}\n\n getExtensions() {\n const dropped: string[] = [...unsafeExtensions];\n if (this.forCollab) dropped.push('history');\n if (this.mediaUpload) dropped.push('mediaUpload');\n if (this.modifyMenu) dropped.push('customMenu');\n\n const extensions = new AdvancedEditorKit()\n .getExtensions()\n .filter(\n (extension) =>\n !('name' in extension && dropped.includes(extension.name))\n );\n\n if (this.modifyMenu) {\n extensions.push(new ExtensionCustomMenu({ modifyMenu: this.modifyMenu }));\n }\n if (this.mediaUpload) {\n extensions.push(new ExtensionMediaUpload(this.mediaUpload));\n }\n return extensions;\n }\n}\n\n/** MarkYChange + ExtensionYjs live in `collabKit.ts` (lazy-loaded). */\n\n/**\n * Build the editor kits for a session. Pass `config` to join a collaborative\n * room; omit it for a plain local editor. Pass `mediaUpload` to configure how\n * pasted/dropped files are handled — most importantly `uploadHandler`, without\n * which every image is embedded in the document as a base64 `data:` URL.\n *\n * Async because collaborative mode lazy-loads the Yjs kit (and its optional\n * peer deps) on first use; plain mode resolves immediately.\n *\n * That lazy load is allowed to fail. `@kerebron/extension-yjs`, `yjs` and\n * `y-protocols` are optional peers, so the chunk can be absent (peers never\n * installed), stale (a dev server's dependency hash moved under a running\n * page) or simply unreachable (a partial deploy, an offline client). None of\n * that is a reason to leave the caller without an editor: collaboration is an\n * enhancement, editing is the feature. So a failed load degrades to the local\n * kit and reports itself through {@link CollabConfig.onUnavailable} rather\n * than rejecting.\n */\nexport async function createEditorKits(\n config?: CollabConfig,\n mediaUpload?: MediaUploadOptions,\n modifyMenu?: ModifyMenu\n): Promise<EditorKits> {\n if (!config) {\n return {\n kits: [new SafeAdvancedEditorKit(false, mediaUpload, modifyMenu)],\n collaborative: false,\n };\n }\n\n try {\n const { HuddleYjsKit, defaultWsUrl } = await import('./collabKit');\n const url = config.wsUrl ?? defaultWsUrl();\n return {\n kits: [\n new SafeAdvancedEditorKit(true, mediaUpload, modifyMenu),\n new HuddleYjsKit(\n url,\n config.params ?? {},\n config.WebSocketPolyfill,\n config.user\n ),\n ],\n collaborative: true,\n };\n } catch (error) {\n console.warn(\n '[RichEditor] Collaborative editing unavailable — the Yjs kit failed to load. Continuing as a local editor.',\n error\n );\n config.onUnavailable?.(error);\n // Degrading to a local editor must not also drop `mediaUpload`: without it\n // the stock extension comes back and pasted files are embedded as base64.\n return {\n kits: [new SafeAdvancedEditorKit(false, mediaUpload, modifyMenu)],\n collaborative: false,\n };\n }\n}\n","'use client';\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useReducer,\n useRef,\n useState,\n} from 'react';\n\nimport { CoreEditor, type AssetLoad, type EditorKit } from '@kerebron/editor';\nimport { createAssetLoad } from '@kerebron/wasm/web';\n\nimport { useIsDarkMode } from '../../hooks/useIsDarkMode';\nimport { MDY_PROJECTION_META } from './mdyTransaction';\nimport {\n createEditorKits,\n type CollabConfig,\n type MediaUploadOptions,\n type ModifyMenu,\n} from './editorKits';\n\nexport type {\n CollabConfig,\n MediaUploadOptions,\n MenuElement,\n ModifyMenu,\n} from './editorKits';\n\nconst MARKDOWN_TYPE = 'text/x-markdown';\n\n/**\n * The markdown converter's tree-sitter WASM init is not concurrency-safe, so\n * every editor's *first* load queues behind the previous one. Later loads (a\n * `value` change) are free — by then the grammars are warm.\n */\nlet initialLoadQueue: Promise<unknown> = Promise.resolve();\n\nfunction queueInitialLoad(load: () => Promise<void>): Promise<void> {\n const queued = initialLoadQueue.catch(() => undefined).then(load);\n initialLoadQueue = queued.catch(() => undefined);\n return queued;\n}\n\nexport interface RichEditorProps {\n /** Markdown to load. Changing it reloads the editor unless `collab` is set. */\n value?: string;\n /** Called with the editor's markdown content whenever it changes. */\n onChange?: (value: string) => void;\n /** Called when editor setup or a Markdown load fails. getContent also rejects. */\n onError?: (error: unknown) => void;\n /** Called after the initial Markdown load completes. */\n onReady?: (editor: CoreEditor) => void;\n /** Whether to render the live markdown output preview. Defaults to `false`. */\n showPreview?: boolean;\n /**\n * Enable live collaborative editing (Yjs) for the given room. When set, the\n * editor connects to the `/yjs` websocket relay and every peer in the same\n * `room` co-edits one shared document. Uncontrolled like `value` — remount via\n * `key` to switch rooms.\n *\n * Best-effort: if the Yjs kit cannot be loaded the editor still mounts, as a\n * local one, and `collab.onUnavailable` is called. Pass that callback if\n * unshared editing is something your users need to be told about.\n */\n collab?: CollabConfig;\n /** Read-only surface: no typing, and the content dims. */\n disabled?: boolean;\n /**\n * Lock edits while keeping the surface focusable and selectable, without\n * the dimmed `disabled` styling. Applied from creation, so the document\n * cannot be edited even while the initial load is still in flight.\n */\n readOnly?: boolean;\n /**\n * Id for the editor host element — an `aria-labelledby`/`aria-describedby`\n * anchor. The host is a `div`, not a labelable control, so a\n * `<label htmlFor>` will not associate; name the editor with `aria-label`\n * or `aria-labelledby` instead.\n */\n id?: string;\n /** Extra classes on the editor surface, beside `kb-component`. */\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n /**\n * Where the tree-sitter WASM grammars load from. Defaults to\n * `createAssetLoad('/kerebron-wasm')`; supply your own when the host serves\n * `@kerebron/wasm`'s `assets/` somewhere else.\n */\n assetLoad?: AssetLoad;\n /**\n * How files pasted or dropped into the editor are handled.\n *\n * **Set `uploadHandler` if your documents are persisted anywhere.** Without\n * it, a pasted image is embedded in the document as a base64 `data:` URL and\n * a video as a blob object URL: a 4 MB screenshot becomes ~5.8 MB of\n * markdown, which most APIs will refuse, and an object URL is dead as soon as\n * the page reloads. `uploadHandler` receives the file and returns the URL to\n * reference it by, so the document carries a link instead of the bytes.\n *\n * ```tsx\n * <RichEditor\n * mediaUpload={{ uploadHandler: (file) => uploadToMyMediaStore(file) }}\n * />\n * ```\n *\n * Read once, when the editor mounts — like {@link collab}, remount via `key`\n * to change it.\n */\n mediaUpload?: MediaUploadOptions;\n /** Additional editor kits, installed once when the editor mounts. */\n editorKits?: EditorKit[];\n /**\n * Reshape the stock toolbar before it renders: receives the menu's item\n * groups and returns the groups to render — append custom controls (a\n * macros toggle, dictation) or drop stock ones. Read once, when the editor\n * mounts — like {@link collab}, remount via `key` to change it.\n */\n modifyMenu?: ModifyMenu;\n /**\n * MIME type of the `value`/`onChange` contract (`'text/x-markdown'` by\n * default; pass `'text/html'` for an HTML-valued surface). Governs both\n * how `value` is parsed and what `onChange`/`getContent()` emit.\n */\n valueType?: string;\n /**\n * Converge the document to `value` on every render, not only when the\n * prop changes — native controlled-input semantics: when a host's\n * `onChange` does not echo an edit back into `value`, the edit reverts.\n * A rejected edit leaves the prop identity unchanged while the document\n * moved on, which a change-gated reload can never see. Off by default,\n * which tolerates read-once hosts that call `getContent()` on submit.\n */\n strictValue?: boolean;\n}\n\nexport interface RichEditorHandle {\n /**\n * The editor's markdown, awaiting the initial load. `onChange` can lag the\n * last keystroke, so read this on submit rather than trusting mirrored state.\n */\n getContent: () => Promise<string>;\n /** Focus the editor, restoring the caret where the writer left it. */\n focus: () => void;\n}\n\n/**\n * Markdown editor over Kerebron's `CoreEditor`.\n *\n * The editor mounts into a **disposable child div**: `CoreEditor.destroy()`\n * replaces its host element with a clone, which would strand React's ref (and,\n * under StrictMode's double-mount, leave the live editor detached behind a\n * dead clone).\n */\nconst RichEditor = forwardRef<RichEditorHandle, RichEditorProps>(\n function RichEditor(\n {\n value = '',\n onChange,\n onError,\n onReady,\n showPreview = false,\n collab,\n disabled = false,\n readOnly = false,\n id,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n assetLoad,\n mediaUpload,\n editorKits: additionalEditorKits,\n modifyMenu,\n valueType = MARKDOWN_TYPE,\n strictValue = false,\n },\n ref\n ) {\n const isDark = useIsDarkMode();\n const hostRef = useRef<HTMLDivElement>(null);\n const editorInstance = useRef<CoreEditor | null>(null);\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n // Mirrors what the editor last held, so an echo of our own `onChange`\n // doesn't reload the document out from under the caret.\n const valueRef = useRef(value);\n const readyRef = useRef<Promise<void> | null>(null);\n const loadingRef = useRef(false);\n const loadVersionRef = useRef(0);\n // Return the exact source until a writer changes the loaded document.\n // Running the Markdown converter alone can normalize whitespace or links.\n const loadedDocRef = useRef<unknown>(null);\n const disabledRef = useRef(disabled);\n const readOnlyRef = useRef(readOnly);\n\n const [md, setMd] = useState<string>('');\n // A strict surface reconciles in an after-render effect, but publishing\n // an edit only mutates refs — a host whose `onChange` ignores the edit\n // (rejection) triggers no render, so the stale document would stay\n // visible. Each publication schedules one render; an accepted update\n // from the host batches into the same pass, so the effect compares the\n // freshest prop either way.\n const [, scheduleStrictReconcile] = useReducer(\n (tick: number) => tick + 1,\n 0\n );\n const strictValueRef = useRef(strictValue);\n strictValueRef.current = strictValue;\n // Serializing the document is the expensive part of a transaction, so the\n // last doc that was serialized is kept to recognise the transactions that\n // did not change it. ProseMirror documents are immutable, so identity is an\n // exact test.\n const lastSerializedDoc = useRef<unknown>(null);\n // Read inside effects created once on mount.\n const showPreviewRef = useRef(showPreview);\n showPreviewRef.current = showPreview;\n const valueTypeRef = useRef(valueType);\n valueTypeRef.current = valueType;\n\n // The contenteditable surface has no implicit ARIA role, so labeling\n // attributes are only permitted alongside an explicit textbox role — and\n // `aria-readonly` is only valid on such a role, not on the host div.\n const surfaceAttributes = useCallback(\n () =>\n ariaLabel || ariaLabelledBy\n ? {\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(ariaLabel ? { 'aria-label': ariaLabel } : {}),\n ...(ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),\n ...(readOnlyRef.current ? { 'aria-readonly': 'true' } : {}),\n }\n : null,\n [ariaLabel, ariaLabelledBy]\n );\n\n // Applies the read state everywhere it matters: the view's `editable`\n // prop, the surface's ARIA attributes, and the stock toolbar — whose\n // buttons dispatch commands regardless of `editable`, so disabled and\n // readOnly must neutralize it with `inert` (blocks pointer and keyboard\n // access while the document's text stays selectable).\n // ProseMirror drops natural tabbability once `editable` is false, so a\n // read-only (not disabled) surface restores it with a direct tabindex —\n // tracked by ownership so a host-supplied tabindex (the TextAreaRich\n // adapter sets its own through `setProps`) is never touched.\n const ownsTabindexRef = useRef(false);\n const syncReadState = useCallback(() => {\n const editor = editorInstance.current;\n if (editor) {\n const attributes = surfaceAttributes();\n editor.view.setProps({\n editable: () => !disabledRef.current && !readOnlyRef.current,\n ...(attributes ? { attributes } : {}),\n });\n const dom = editor.view.dom as HTMLElement;\n if (readOnlyRef.current && !disabledRef.current) {\n if (!dom.hasAttribute('tabindex')) {\n dom.setAttribute('tabindex', '0');\n ownsTabindexRef.current = true;\n }\n } else if (ownsTabindexRef.current) {\n if (dom.getAttribute('tabindex') === '0')\n dom.removeAttribute('tabindex');\n ownsTabindexRef.current = false;\n }\n }\n const inert = disabledRef.current || readOnlyRef.current;\n for (const toolbar of hostRef.current?.querySelectorAll<HTMLElement>(\n '.kb-custom-menu, .kb-custom-menu__overflow-menu'\n ) ?? []) {\n toolbar.inert = inert;\n }\n }, [surfaceAttributes]);\n\n useEffect(() => {\n disabledRef.current = disabled;\n readOnlyRef.current = readOnly;\n syncReadState();\n }, [disabled, readOnly, syncReadState]);\n\n // Runs after every render (no dependency array): a `strictValue` surface\n // must converge even when the prop identity never changed — a rejected\n // edit keeps `value` as-is while the document moved on. The\n // `value === valueRef` guard keeps the common case free; non-strict\n // hosts additionally require the prop itself to have changed (tracked\n // manually below), preserving tolerance for read-once hosts.\n const lastValuePropRef = useRef(value);\n useEffect(() => {\n const propChanged = lastValuePropRef.current !== value;\n lastValuePropRef.current = value;\n // In collab mode the CRDT owns the content; reloading would fight it.\n if (collab || value === valueRef.current) return;\n if (!strictValue && !propChanged) return;\n valueRef.current = value;\n const editor = editorInstance.current;\n if (!editor) return;\n\n loadingRef.current = true;\n const loadVersion = ++loadVersionRef.current;\n const previousReady = readyRef.current;\n // Serialize reloads behind setup and one another. Saving while a reload\n // is pending awaits that same promise rather than reading stale prose.\n const pending = (previousReady ?? Promise.resolve())\n .catch(() => undefined)\n .then(async () => {\n if (editorInstance.current !== editor) return;\n // Reloading the document must not cost the writer their caret: a\n // host-composed update (macro pick, finding) lands mid-flow and\n // the next keystroke should keep going into the editable.\n const hadFocus = editor.view.hasFocus();\n await editor.loadDocumentText(valueTypeRef.current, value);\n if (editorInstance.current !== editor) return;\n loadedDocRef.current = editor.view.state.doc;\n lastSerializedDoc.current = editor.view.state.doc;\n if (hadFocus) {\n // The load can take long enough for the writer to move on —\n // only reclaim the caret when no other control has taken it.\n const active = document.activeElement;\n if (\n !active ||\n active === document.body ||\n (editor.view.dom as HTMLElement).contains(active)\n ) {\n editor.view.focus();\n }\n }\n if (showPreviewRef.current) setMd(value);\n })\n .finally(() => {\n if (\n editorInstance.current === editor &&\n loadVersion === loadVersionRef.current\n ) {\n loadingRef.current = false;\n }\n });\n readyRef.current = pending;\n void pending.catch((error) => {\n if (editorInstance.current !== editor) return;\n console.error('Failed to load markdown:', error);\n onErrorRef.current?.(error);\n });\n });\n\n useEffect(() => {\n if (!hostRef.current) return;\n const host = hostRef.current;\n\n // Set on cleanup so async continuations (kit loading and the\n // `loadDocumentText` chain) don't touch the editor after `destroy()`.\n let disposed = false;\n let editor: CoreEditor | null = null;\n\n const mount = document.createElement('div');\n host.appendChild(mount);\n\n // Listen to transactions and update markdown preview\n const onTransaction = async (event?: Event) => {\n const transaction = (\n event as\n | globalThis.CustomEvent<{\n transaction?: {\n getMeta: (key: string) => unknown;\n before: unknown;\n };\n }>\n | undefined\n )?.detail?.transaction;\n if (transaction?.getMeta(MDY_PROJECTION_META) === true) {\n const doc = editorInstance.current?.view.state.doc;\n if (transaction.before === loadedDocRef.current) {\n loadedDocRef.current = doc;\n lastSerializedDoc.current = doc;\n } else {\n lastSerializedDoc.current = null;\n // A host projection can overtake a pending user-edit save. That\n // older result is discarded below, so publish the newest composed\n // document even if the writer does not make another transaction.\n // A microtask coalesces a burst of clinical updates into one save.\n void Promise.resolve().then(() => {\n if (!disposed) return onTransaction();\n });\n }\n return;\n }\n // Programmatic loads are not edits — reporting them would echo the\n // caller's own `value` back through `onChange`.\n if (loadingRef.current || !editorInstance.current) return;\n\n // ProseMirror fires a transaction for every selection change too —\n // arrow keys, clicks, a blur. Serializing the whole document to\n // markdown for those costs a full tree-sitter pass and two React\n // renders for a caret move, so only a changed document is re-read.\n const { doc } = editorInstance.current.view.state;\n if (doc === lastSerializedDoc.current) return;\n lastSerializedDoc.current = doc;\n const loadVersion = loadVersionRef.current;\n\n try {\n const buffer = await editorInstance.current.saveDocument(\n valueTypeRef.current\n );\n const markdown = new globalThis.TextDecoder().decode(buffer);\n if (\n disposed ||\n loadingRef.current ||\n loadVersion !== loadVersionRef.current ||\n doc !== editorInstance.current?.view.state.doc\n ) {\n return;\n }\n valueRef.current = markdown;\n // `md` only feeds the preview pane; setting it with the preview off\n // re-renders the editor on every keystroke for nothing.\n if (showPreviewRef.current) setMd(markdown);\n onChangeRef.current?.(markdown);\n if (strictValueRef.current) scheduleStrictReconcile();\n // This source is now published. Future clinical-only projections\n // preserve it without starting another authored-prose write.\n loadedDocRef.current = doc;\n } catch (err) {\n // The document was marked as serialized before the attempt, to keep\n // selection-only transactions arriving mid-save from re-entering.\n // A failure has to undo that, or this document is never retried.\n lastSerializedDoc.current = null;\n console.error('Failed to save markdown:', err);\n }\n };\n\n // Initialize the editor. Both modes drop the teardown-unsafe extensions;\n // collaborative mode additionally swaps `history` for the Yjs CRDT sync\n // and lazy-loads the Yjs kit (see `editorKits.ts` for why).\n const setup = async () => {\n loadingRef.current = true;\n const loadVersion = ++loadVersionRef.current;\n // `collaborative` is false when a room was asked for but the Yjs kit\n // could not be loaded — the editor is still created, just a local one,\n // so there is no room to join below.\n const { kits: editorKits, collaborative } = await createEditorKits(\n collab,\n mediaUpload,\n modifyMenu\n );\n if (disposed) return;\n\n editor = CoreEditor.create({\n element: mount,\n uri: 'file:///untitled.md',\n assetLoad: assetLoad ?? createAssetLoad('/kerebron-wasm'),\n editorKits: [...editorKits, ...(additionalEditorKits ?? [])],\n readOnly: disabledRef.current || readOnlyRef.current,\n });\n\n editorInstance.current = editor;\n syncReadState();\n editor.addEventListener('transaction', onTransaction);\n\n // Seed initial content, then populate the preview once on mount.\n //\n // In collaborative mode we still load the local markdown first, then\n // join the room: the Yjs binding seeds an *empty* shared document from\n // this content on the first join, and overwrites the editor with the\n // shared content when the room already has edits — so the stored\n // markdown is the starting point without ever double-inserting.\n const joinRoom = () => {\n if (collaborative && collab && editor && !disposed) {\n (\n editor.run as Record<string, (...args: unknown[]) => boolean>\n ).changeRoom?.(collab.room);\n reseedWhenRoomStaysEmpty();\n }\n };\n\n // The Yjs binding is supposed to seed an empty room from the local\n // content, but the sync import can land as an overwrite that blanks\n // the just-loaded seed (observed with extension-yjs 0.8.x). Heal it:\n // once the join settles, an empty document with a non-empty seed\n // means nobody's content won — reload the seed, which the binding\n // then pushes into the room. Joiners pass no value, so exactly one\n // participant ever does this.\n const seed = valueRef.current;\n const reseedWhenRoomStaysEmpty = () => {\n if (!seed) return;\n const check = async (attempt: number) => {\n if (disposed || !editorInstance.current) return;\n try {\n const buffer =\n await editorInstance.current.saveDocument(MARKDOWN_TYPE);\n const current = new globalThis.TextDecoder()\n .decode(buffer)\n .trim();\n if (disposed || !editorInstance.current) return;\n if (current) return; // somebody's content arrived — done\n if (attempt >= 2) {\n await editorInstance.current.loadDocumentText(\n valueTypeRef.current,\n seed\n );\n return;\n }\n setTimeout(() => void check(attempt + 1), 300);\n } catch {\n // A failed probe must not break the editor; the room stays as-is.\n }\n };\n setTimeout(() => void check(0), 300);\n };\n\n if (valueRef.current) {\n await queueInitialLoad(() =>\n editor!.loadDocumentText(valueTypeRef.current, valueRef.current)\n );\n }\n if (disposed) return;\n loadedDocRef.current = editor.view.state.doc;\n lastSerializedDoc.current = editor.view.state.doc;\n if (showPreviewRef.current) setMd(valueRef.current);\n if (loadVersion === loadVersionRef.current) loadingRef.current = false;\n onReadyRef.current?.(editor);\n joinRoom();\n };\n\n const pending = setup();\n readyRef.current = pending;\n // Observe the rejection without replacing the readiness promise: callers\n // must be able to detect a failed load instead of saving stale content.\n void pending.catch((error) => {\n if (disposed) return;\n loadingRef.current = false;\n console.error('Failed to set up editor:', error);\n onErrorRef.current?.(error);\n });\n\n // Cleanup on unmount\n return () => {\n disposed = true;\n editorInstance.current = null; // makes onTransaction's guard effective\n editor?.removeEventListener('transaction', onTransaction);\n editor?.destroy();\n readyRef.current = null;\n host.replaceChildren();\n };\n // Initial `value`/`collab` are intentionally only applied on mount\n // (uncontrolled). Remount via `key` to switch rooms.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n getContent: async (): Promise<string> => {\n while (true) {\n await readyRef.current;\n const editor = editorInstance.current;\n if (!editor) return valueRef.current;\n const doc = editor.view.state.doc;\n const loadVersion = loadVersionRef.current;\n if (doc === loadedDocRef.current) return valueRef.current;\n const buffer = await editor.saveDocument(valueTypeRef.current);\n if (\n editorInstance.current !== editor ||\n loadVersion !== loadVersionRef.current ||\n doc !== editor.view.state.doc\n )\n continue;\n const markdown = new globalThis.TextDecoder().decode(buffer);\n valueRef.current = markdown;\n loadedDocRef.current = doc;\n lastSerializedDoc.current = doc;\n return markdown;\n }\n },\n focus: (): void => {\n const apply = (): void => {\n const view = editorInstance.current?.view as\n | { focus?: () => void }\n | undefined;\n if (view?.focus) {\n view.focus();\n return;\n }\n hostRef.current\n ?.querySelector<HTMLElement>('[contenteditable=\"true\"], textarea')\n ?.focus();\n };\n // Callers focus on mount; the editor may still be loading its kits.\n if (editorInstance.current) apply();\n else void readyRef.current?.then(apply, () => undefined);\n },\n }),\n []\n );\n\n return (\n <div>\n <div>\n <div\n ref={hostRef}\n id={id}\n className={[\n 'kb-component',\n isDark ? 'kb-component--dark' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-disabled={disabled || undefined}\n style={{\n isolation: 'isolate',\n opacity: disabled ? 0.65 : undefined,\n pointerEvents: disabled ? 'none' : undefined,\n }}\n />\n </div>\n\n {showPreview && (\n <div>\n <div>\n <h5>Markdown Output</h5>\n <pre>{md}</pre>\n </div>\n </div>\n )}\n </div>\n );\n }\n);\n\nRichEditor.displayName = 'RichEditor';\n\nexport { RichEditor };\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/RichEditor/mdyTransaction.ts","../src/components/RichEditor/editorKits.ts","../src/components/RichEditor/RichEditor.tsx"],"names":["RichEditor","doc"],"mappings":"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","file":"chunk-NIE3WBJH.js","sourcesContent":["/** Shared metadata for host-created MDY projection updates. */\nexport const MDY_PROJECTION_META = 'mdyProjectionRefresh';\n","/**\n * Editor kit assembly for {@link RichEditor}, for both plain and collaborative\n * (Yjs) mode.\n *\n * Both modes start from {@link AdvancedEditorKit} and drop the extensions that\n * are unsafe for our usage — see {@link unsafeExtensions} — then collaborative\n * mode adds the Yjs pieces on top.\n *\n * The Yjs pieces live in `collabKit.ts` behind a dynamic `import()`, so\n * `@kerebron/extension-yjs`, `yjs` and `y-protocols` remain truly optional\n * peers — plain-mode consumers never load them.\n */\nimport type { EditorKit } from '@kerebron/editor';\nimport { AdvancedEditorKit } from '@kerebron/editor-kits/AdvancedEditorKit';\nimport {\n ExtensionMediaUpload,\n type MediaUploadOptions,\n} from '@kerebron/extension-basic-editor/ExtensionMediaUpload';\nimport {\n ExtensionCustomMenu,\n type MenuElement,\n} from '@kerebron/extension-menu';\n\nexport type { MediaUploadOptions };\nexport type { MenuElement };\n\n/**\n * Reshape the toolbar menu before it renders: receives the stock menu's\n * item groups and returns the groups to render. Append custom\n * {@link MenuElement}s (e.g. a Macros toggle) or drop stock groups.\n */\nexport type ModifyMenu = (menus: MenuElement[][]) => MenuElement[][];\n\nexport interface CollabConfig {\n /** Room id — one shared document per room (e.g. a post id). */\n room: string;\n /**\n * WebSocket base URL for the Yjs relay. Defaults to\n * `<ws|wss>://<location.host>/yjs`. The room id is appended by the provider.\n */\n wsUrl?: string;\n /** Extra query params for the socket (e.g. `{ token }` for auth). */\n params?: Record<string, string>;\n /**\n * Who this editor is, published on awareness (`kerebron:user`) so peers see\n * a named, coloured cursor. Without it remote cursors do not render — the\n * position plugin skips awareness states that carry no user — and the\n * `id` is what the cursor colour is derived from (kerebron's `User` shape).\n */\n user?: { id: string; name: string; color?: string };\n /**\n * Custom WebSocket implementation handed to the Yjs provider — e.g. a\n * loopback socket for demos/tests, or a polyfill outside the browser.\n * Defaults to `globalThis.WebSocket`.\n */\n WebSocketPolyfill?: typeof globalThis.WebSocket;\n /**\n * Called when collaborative editing could not be started at all — the Yjs\n * kit failed to load (see {@link createEditorKits}). The editor mounts\n * anyway, as a local one; this is how the host finds out that edits are no\n * longer shared, so it can say so, or tear its own editor down if unshared\n * editing would be unsafe.\n *\n * Not for connection trouble: a room that is reachable but currently\n * disconnected still has the Yjs kit loaded, and the provider retries on its\n * own. This fires once, before the editor is created.\n */\n onUnavailable?: (error: unknown) => void;\n}\n\n/** What {@link createEditorKits} resolves to. */\nexport interface EditorKits {\n kits: EditorKit[];\n /**\n * Whether the returned kits can actually collaborate. False when `config`\n * asked for a room but the Yjs kit could not be loaded, so callers know not\n * to join one.\n */\n collaborative: boolean;\n}\n\n/**\n * Extensions dropped from {@link AdvancedEditorKit}, and why.\n *\n * `autocomplete` and `hover` debounce their DOM handlers (200ms) and then call\n * `dispatchMeta`, which reads `this.editor.state` with no guard that the editor\n * is still alive. Any teardown or document swap inside that debounce window\n * lands the deferred call on a dead view and throws\n * `null.matchesNode()` inside ProseMirror's `EditorView.updateStateInner`,\n * leaving the view permanently broken. Two ways to hit it:\n * - remount (e.g. a `key` change) while the pointer is over the editor, which\n * fires the debounced `onMouseLeave` after the view is destroyed;\n * - a Yjs remote update replacing the document tree under a pending callback.\n * The first applies to *every* editor, so both extensions come out in both\n * modes. No functional cost — autocomplete popups and node-hover tooltips are\n * compositor conveniences, not required for editing.\n *\n * `history` is collab-only: ExtensionYjs supplies its own CRDT-aware undo/redo\n * and the editor throws `Extension conflict: yjs vs history` if both are\n * present. Plain mode keeps it, so undo/redo still works there.\n */\nconst unsafeExtensions = ['autocomplete', 'hover'] as const;\n\n/**\n * {@link AdvancedEditorKit} minus {@link unsafeExtensions} (and, for collab\n * mode, minus `history`), with `mediaUpload` reconfigured when the host asks.\n *\n * `AdvancedEditorKit` constructs `ExtensionMediaUpload` with no options, and an\n * extension's options are fixed at construction — so the only way to configure\n * it is to drop that instance and append one of our own. `modifyMenu` works\n * the same way: the stock `ExtensionCustomMenu` is constructed with no config,\n * so customizing the toolbar means replacing it with a configured instance.\n */\nclass SafeAdvancedEditorKit implements EditorKit {\n name = 'advanced-editor';\n constructor(\n private readonly forCollab: boolean,\n private readonly mediaUpload?: MediaUploadOptions,\n private readonly modifyMenu?: ModifyMenu\n ) {}\n\n getExtensions() {\n const dropped: string[] = [...unsafeExtensions];\n if (this.forCollab) dropped.push('history');\n if (this.mediaUpload) dropped.push('mediaUpload');\n if (this.modifyMenu) dropped.push('customMenu');\n\n const extensions = new AdvancedEditorKit()\n .getExtensions()\n .filter(\n (extension) =>\n !('name' in extension && dropped.includes(extension.name))\n );\n\n if (this.modifyMenu) {\n extensions.push(new ExtensionCustomMenu({ modifyMenu: this.modifyMenu }));\n }\n if (this.mediaUpload) {\n extensions.push(new ExtensionMediaUpload(this.mediaUpload));\n }\n return extensions;\n }\n}\n\n/** MarkYChange + ExtensionYjs live in `collabKit.ts` (lazy-loaded). */\n\n/**\n * Build the editor kits for a session. Pass `config` to join a collaborative\n * room; omit it for a plain local editor. Pass `mediaUpload` to configure how\n * pasted/dropped files are handled — most importantly `uploadHandler`, without\n * which every image is embedded in the document as a base64 `data:` URL.\n *\n * Async because collaborative mode lazy-loads the Yjs kit (and its optional\n * peer deps) on first use; plain mode resolves immediately.\n *\n * That lazy load is allowed to fail. `@kerebron/extension-yjs`, `yjs` and\n * `y-protocols` are optional peers, so the chunk can be absent (peers never\n * installed), stale (a dev server's dependency hash moved under a running\n * page) or simply unreachable (a partial deploy, an offline client). None of\n * that is a reason to leave the caller without an editor: collaboration is an\n * enhancement, editing is the feature. So a failed load degrades to the local\n * kit and reports itself through {@link CollabConfig.onUnavailable} rather\n * than rejecting.\n */\nexport async function createEditorKits(\n config?: CollabConfig,\n mediaUpload?: MediaUploadOptions,\n modifyMenu?: ModifyMenu\n): Promise<EditorKits> {\n if (!config) {\n return {\n kits: [new SafeAdvancedEditorKit(false, mediaUpload, modifyMenu)],\n collaborative: false,\n };\n }\n\n try {\n const { HuddleYjsKit, defaultWsUrl } = await import('./collabKit');\n const url = config.wsUrl ?? defaultWsUrl();\n return {\n kits: [\n new SafeAdvancedEditorKit(true, mediaUpload, modifyMenu),\n new HuddleYjsKit(\n url,\n config.params ?? {},\n config.WebSocketPolyfill,\n config.user\n ),\n ],\n collaborative: true,\n };\n } catch (error) {\n console.warn(\n '[RichEditor] Collaborative editing unavailable — the Yjs kit failed to load. Continuing as a local editor.',\n error\n );\n config.onUnavailable?.(error);\n // Degrading to a local editor must not also drop `mediaUpload`: without it\n // the stock extension comes back and pasted files are embedded as base64.\n return {\n kits: [new SafeAdvancedEditorKit(false, mediaUpload, modifyMenu)],\n collaborative: false,\n };\n }\n}\n","'use client';\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useReducer,\n useRef,\n useState,\n} from 'react';\n\nimport { CoreEditor, type AssetLoad, type EditorKit } from '@kerebron/editor';\nimport { createAssetLoad } from '@kerebron/wasm/web';\n\nimport { useIsDarkMode } from '../../hooks/useIsDarkMode';\nimport { MDY_PROJECTION_META } from './mdyTransaction';\nimport {\n createEditorKits,\n type CollabConfig,\n type MediaUploadOptions,\n type ModifyMenu,\n} from './editorKits';\n\nexport type {\n CollabConfig,\n MediaUploadOptions,\n MenuElement,\n ModifyMenu,\n} from './editorKits';\n\nconst MARKDOWN_TYPE = 'text/x-markdown';\n\n/**\n * The markdown converter's tree-sitter WASM init is not concurrency-safe, so\n * every editor's *first* load queues behind the previous one. Later loads (a\n * `value` change) are free — by then the grammars are warm.\n */\nlet initialLoadQueue: Promise<unknown> = Promise.resolve();\n\nfunction queueInitialLoad(load: () => Promise<void>): Promise<void> {\n const queued = initialLoadQueue.catch(() => undefined).then(load);\n initialLoadQueue = queued.catch(() => undefined);\n return queued;\n}\n\nexport interface RichEditorProps {\n /** Markdown to load. Changing it reloads the editor unless `collab` is set. */\n value?: string;\n /** Called with the editor's markdown content whenever it changes. */\n onChange?: (value: string) => void;\n /** Called when editor setup or a Markdown load fails. getContent also rejects. */\n onError?: (error: unknown) => void;\n /** Called after the initial Markdown load completes. */\n onReady?: (editor: CoreEditor) => void;\n /** Whether to render the live markdown output preview. Defaults to `false`. */\n showPreview?: boolean;\n /**\n * Enable live collaborative editing (Yjs) for the given room. When set, the\n * editor connects to the `/yjs` websocket relay and every peer in the same\n * `room` co-edits one shared document. Uncontrolled like `value` — remount via\n * `key` to switch rooms.\n *\n * Best-effort: if the Yjs kit cannot be loaded the editor still mounts, as a\n * local one, and `collab.onUnavailable` is called. Pass that callback if\n * unshared editing is something your users need to be told about.\n */\n collab?: CollabConfig;\n /** Read-only surface: no typing, and the content dims. */\n disabled?: boolean;\n /**\n * Lock edits while keeping the surface focusable and selectable, without\n * the dimmed `disabled` styling. Applied from creation, so the document\n * cannot be edited even while the initial load is still in flight.\n */\n readOnly?: boolean;\n /**\n * Id for the editor host element — an `aria-labelledby`/`aria-describedby`\n * anchor. The host is a `div`, not a labelable control, so a\n * `<label htmlFor>` will not associate; name the editor with `aria-label`\n * or `aria-labelledby` instead.\n */\n id?: string;\n /** Extra classes on the editor surface, beside `kb-component`. */\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n /**\n * Where the tree-sitter WASM grammars load from. Defaults to\n * `createAssetLoad('/kerebron-wasm')`; supply your own when the host serves\n * `@kerebron/wasm`'s `assets/` somewhere else.\n */\n assetLoad?: AssetLoad;\n /**\n * How files pasted or dropped into the editor are handled.\n *\n * **Set `uploadHandler` if your documents are persisted anywhere.** Without\n * it, a pasted image is embedded in the document as a base64 `data:` URL and\n * a video as a blob object URL: a 4 MB screenshot becomes ~5.8 MB of\n * markdown, which most APIs will refuse, and an object URL is dead as soon as\n * the page reloads. `uploadHandler` receives the file and returns the URL to\n * reference it by, so the document carries a link instead of the bytes.\n *\n * ```tsx\n * <RichEditor\n * mediaUpload={{ uploadHandler: (file) => uploadToMyMediaStore(file) }}\n * />\n * ```\n *\n * Read once, when the editor mounts — like {@link collab}, remount via `key`\n * to change it.\n */\n mediaUpload?: MediaUploadOptions;\n /** Additional editor kits, installed once when the editor mounts. */\n editorKits?: EditorKit[];\n /**\n * Reshape the stock toolbar before it renders: receives the menu's item\n * groups and returns the groups to render — append custom controls (a\n * macros toggle, dictation) or drop stock ones. Read once, when the editor\n * mounts — like {@link collab}, remount via `key` to change it.\n */\n modifyMenu?: ModifyMenu;\n /**\n * MIME type of the `value`/`onChange` contract (`'text/x-markdown'` by\n * default; pass `'text/html'` for an HTML-valued surface). Governs both\n * how `value` is parsed and what `onChange`/`getContent()` emit.\n */\n valueType?: string;\n /**\n * Converge the document to `value` on every render, not only when the\n * prop changes — native controlled-input semantics: when a host's\n * `onChange` does not echo an edit back into `value`, the edit reverts.\n * A rejected edit leaves the prop identity unchanged while the document\n * moved on, which a change-gated reload can never see. Off by default,\n * which tolerates read-once hosts that call `getContent()` on submit.\n */\n strictValue?: boolean;\n}\n\nexport interface RichEditorHandle {\n /**\n * The editor's markdown, awaiting the initial load. `onChange` can lag the\n * last keystroke, so read this on submit rather than trusting mirrored state.\n */\n getContent: () => Promise<string>;\n /** Focus the editor, restoring the caret where the writer left it. */\n focus: () => void;\n}\n\n/**\n * Markdown editor over Kerebron's `CoreEditor`.\n *\n * The editor mounts into a **disposable child div**: `CoreEditor.destroy()`\n * replaces its host element with a clone, which would strand React's ref (and,\n * under StrictMode's double-mount, leave the live editor detached behind a\n * dead clone).\n */\nconst RichEditor = forwardRef<RichEditorHandle, RichEditorProps>(\n function RichEditor(\n {\n value = '',\n onChange,\n onError,\n onReady,\n showPreview = false,\n collab,\n disabled = false,\n readOnly = false,\n id,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n assetLoad,\n mediaUpload,\n editorKits: additionalEditorKits,\n modifyMenu,\n valueType = MARKDOWN_TYPE,\n strictValue = false,\n },\n ref\n ) {\n const isDark = useIsDarkMode();\n const hostRef = useRef<HTMLDivElement>(null);\n const editorInstance = useRef<CoreEditor | null>(null);\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n // Mirrors what the editor last held, so an echo of our own `onChange`\n // doesn't reload the document out from under the caret.\n const valueRef = useRef(value);\n const readyRef = useRef<Promise<void> | null>(null);\n const loadingRef = useRef(false);\n const loadVersionRef = useRef(0);\n // Return the exact source until a writer changes the loaded document.\n // Running the Markdown converter alone can normalize whitespace or links.\n const loadedDocRef = useRef<unknown>(null);\n const disabledRef = useRef(disabled);\n const readOnlyRef = useRef(readOnly);\n\n const [md, setMd] = useState<string>('');\n // A strict surface reconciles in an after-render effect, but publishing\n // an edit only mutates refs — a host whose `onChange` ignores the edit\n // (rejection) triggers no render, so the stale document would stay\n // visible. Each publication schedules one render; an accepted update\n // from the host batches into the same pass, so the effect compares the\n // freshest prop either way.\n const [, scheduleStrictReconcile] = useReducer(\n (tick: number) => tick + 1,\n 0\n );\n const strictValueRef = useRef(strictValue);\n strictValueRef.current = strictValue;\n // Serializing the document is the expensive part of a transaction, so the\n // last doc that was serialized is kept to recognise the transactions that\n // did not change it. ProseMirror documents are immutable, so identity is an\n // exact test.\n const lastSerializedDoc = useRef<unknown>(null);\n // Read inside effects created once on mount.\n const showPreviewRef = useRef(showPreview);\n showPreviewRef.current = showPreview;\n const valueTypeRef = useRef(valueType);\n valueTypeRef.current = valueType;\n\n // The contenteditable surface has no implicit ARIA role, so labeling\n // attributes are only permitted alongside an explicit textbox role — and\n // `aria-readonly` is only valid on such a role, not on the host div.\n const surfaceAttributes = useCallback(\n () =>\n ariaLabel || ariaLabelledBy\n ? {\n role: 'textbox',\n 'aria-multiline': 'true',\n ...(ariaLabel ? { 'aria-label': ariaLabel } : {}),\n ...(ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {}),\n ...(readOnlyRef.current ? { 'aria-readonly': 'true' } : {}),\n }\n : null,\n [ariaLabel, ariaLabelledBy]\n );\n\n // Applies the read state everywhere it matters: the view's `editable`\n // prop, the surface's ARIA attributes, and the stock toolbar — whose\n // buttons dispatch commands regardless of `editable`, so disabled and\n // readOnly must neutralize it with `inert` (blocks pointer and keyboard\n // access while the document's text stays selectable).\n // ProseMirror drops natural tabbability once `editable` is false, so a\n // read-only (not disabled) surface restores it with a direct tabindex —\n // tracked by ownership so a host-supplied tabindex (the TextAreaRich\n // adapter sets its own through `setProps`) is never touched.\n const ownsTabindexRef = useRef(false);\n const syncReadState = useCallback(() => {\n const editor = editorInstance.current;\n if (editor) {\n const attributes = surfaceAttributes();\n editor.view.setProps({\n editable: () => !disabledRef.current && !readOnlyRef.current,\n ...(attributes ? { attributes } : {}),\n });\n const dom = editor.view.dom as HTMLElement;\n if (readOnlyRef.current && !disabledRef.current) {\n if (!dom.hasAttribute('tabindex')) {\n dom.setAttribute('tabindex', '0');\n ownsTabindexRef.current = true;\n }\n } else if (ownsTabindexRef.current) {\n if (dom.getAttribute('tabindex') === '0')\n dom.removeAttribute('tabindex');\n ownsTabindexRef.current = false;\n }\n }\n const inert = disabledRef.current || readOnlyRef.current;\n for (const toolbar of hostRef.current?.querySelectorAll<HTMLElement>(\n '.kb-custom-menu, .kb-custom-menu__overflow-menu'\n ) ?? []) {\n toolbar.inert = inert;\n }\n }, [surfaceAttributes]);\n\n useEffect(() => {\n disabledRef.current = disabled;\n readOnlyRef.current = readOnly;\n syncReadState();\n }, [disabled, readOnly, syncReadState]);\n\n // Runs after every render (no dependency array): a `strictValue` surface\n // must converge even when the prop identity never changed — a rejected\n // edit keeps `value` as-is while the document moved on. The\n // `value === valueRef` guard keeps the common case free; non-strict\n // hosts additionally require the prop itself to have changed (tracked\n // manually below), preserving tolerance for read-once hosts.\n const lastValuePropRef = useRef(value);\n useEffect(() => {\n const propChanged = lastValuePropRef.current !== value;\n lastValuePropRef.current = value;\n // In collab mode the CRDT owns the content; reloading would fight it.\n if (collab || value === valueRef.current) return;\n if (!strictValue && !propChanged) return;\n valueRef.current = value;\n const editor = editorInstance.current;\n if (!editor) return;\n\n loadingRef.current = true;\n const loadVersion = ++loadVersionRef.current;\n const previousReady = readyRef.current;\n // Serialize reloads behind setup and one another. Saving while a reload\n // is pending awaits that same promise rather than reading stale prose.\n const pending = (previousReady ?? Promise.resolve())\n .catch(() => undefined)\n .then(async () => {\n if (editorInstance.current !== editor) return;\n // Reloading the document must not cost the writer their caret: a\n // host-composed update (macro pick, finding) lands mid-flow and\n // the next keystroke should keep going into the editable.\n const hadFocus = editor.view.hasFocus();\n await editor.loadDocumentText(valueTypeRef.current, value);\n if (editorInstance.current !== editor) return;\n loadedDocRef.current = editor.view.state.doc;\n lastSerializedDoc.current = editor.view.state.doc;\n if (hadFocus) {\n // The load can take long enough for the writer to move on —\n // only reclaim the caret when no other control has taken it.\n const active = document.activeElement;\n if (\n !active ||\n active === document.body ||\n (editor.view.dom as HTMLElement).contains(active)\n ) {\n editor.view.focus();\n }\n }\n if (showPreviewRef.current) setMd(value);\n })\n .finally(() => {\n if (\n editorInstance.current === editor &&\n loadVersion === loadVersionRef.current\n ) {\n loadingRef.current = false;\n }\n });\n readyRef.current = pending;\n void pending.catch((error) => {\n if (editorInstance.current !== editor) return;\n console.error('Failed to load markdown:', error);\n onErrorRef.current?.(error);\n });\n });\n\n useEffect(() => {\n if (!hostRef.current) return;\n const host = hostRef.current;\n\n // Set on cleanup so async continuations (kit loading and the\n // `loadDocumentText` chain) don't touch the editor after `destroy()`.\n let disposed = false;\n let editor: CoreEditor | null = null;\n\n const mount = document.createElement('div');\n host.appendChild(mount);\n\n // Listen to transactions and update markdown preview\n const onTransaction = async (event?: Event) => {\n const transaction = (\n event as\n | globalThis.CustomEvent<{\n transaction?: {\n getMeta: (key: string) => unknown;\n before: unknown;\n };\n }>\n | undefined\n )?.detail?.transaction;\n if (transaction?.getMeta(MDY_PROJECTION_META) === true) {\n const doc = editorInstance.current?.view.state.doc;\n if (transaction.before === loadedDocRef.current) {\n loadedDocRef.current = doc;\n lastSerializedDoc.current = doc;\n } else {\n lastSerializedDoc.current = null;\n // A host projection can overtake a pending user-edit save. That\n // older result is discarded below, so publish the newest composed\n // document even if the writer does not make another transaction.\n // A microtask coalesces a burst of clinical updates into one save.\n void Promise.resolve().then(() => {\n if (!disposed) return onTransaction();\n });\n }\n return;\n }\n // Programmatic loads are not edits — reporting them would echo the\n // caller's own `value` back through `onChange`.\n if (loadingRef.current || !editorInstance.current) return;\n\n // ProseMirror fires a transaction for every selection change too —\n // arrow keys, clicks, a blur. Serializing the whole document to\n // markdown for those costs a full tree-sitter pass and two React\n // renders for a caret move, so only a changed document is re-read.\n const { doc } = editorInstance.current.view.state;\n if (doc === lastSerializedDoc.current) return;\n lastSerializedDoc.current = doc;\n const loadVersion = loadVersionRef.current;\n\n try {\n const buffer = await editorInstance.current.saveDocument(\n valueTypeRef.current\n );\n const markdown = new globalThis.TextDecoder().decode(buffer);\n if (\n disposed ||\n loadingRef.current ||\n loadVersion !== loadVersionRef.current ||\n doc !== editorInstance.current?.view.state.doc\n ) {\n return;\n }\n valueRef.current = markdown;\n // `md` only feeds the preview pane; setting it with the preview off\n // re-renders the editor on every keystroke for nothing.\n if (showPreviewRef.current) setMd(markdown);\n onChangeRef.current?.(markdown);\n if (strictValueRef.current) scheduleStrictReconcile();\n // This source is now published. Future clinical-only projections\n // preserve it without starting another authored-prose write.\n loadedDocRef.current = doc;\n } catch (err) {\n // The document was marked as serialized before the attempt, to keep\n // selection-only transactions arriving mid-save from re-entering.\n // A failure has to undo that, or this document is never retried.\n lastSerializedDoc.current = null;\n console.error('Failed to save markdown:', err);\n }\n };\n\n // Initialize the editor. Both modes drop the teardown-unsafe extensions;\n // collaborative mode additionally swaps `history` for the Yjs CRDT sync\n // and lazy-loads the Yjs kit (see `editorKits.ts` for why).\n const setup = async () => {\n loadingRef.current = true;\n const loadVersion = ++loadVersionRef.current;\n // `collaborative` is false when a room was asked for but the Yjs kit\n // could not be loaded — the editor is still created, just a local one,\n // so there is no room to join below.\n const { kits: editorKits, collaborative } = await createEditorKits(\n collab,\n mediaUpload,\n modifyMenu\n );\n if (disposed) return;\n\n editor = CoreEditor.create({\n element: mount,\n uri: 'file:///untitled.md',\n assetLoad: assetLoad ?? createAssetLoad('/kerebron-wasm'),\n editorKits: [...editorKits, ...(additionalEditorKits ?? [])],\n readOnly: disabledRef.current || readOnlyRef.current,\n });\n\n editorInstance.current = editor;\n syncReadState();\n editor.addEventListener('transaction', onTransaction);\n\n // Seed initial content, then populate the preview once on mount.\n //\n // In collaborative mode we still load the local markdown first, then\n // join the room: the Yjs binding seeds an *empty* shared document from\n // this content on the first join, and overwrites the editor with the\n // shared content when the room already has edits — so the stored\n // markdown is the starting point without ever double-inserting.\n const joinRoom = () => {\n if (collaborative && collab && editor && !disposed) {\n (\n editor.run as Record<string, (...args: unknown[]) => boolean>\n ).changeRoom?.(collab.room);\n reseedWhenRoomStaysEmpty();\n }\n };\n\n // The Yjs binding is supposed to seed an empty room from the local\n // content, but the sync import can land as an overwrite that blanks\n // the just-loaded seed (observed with extension-yjs 0.8.x). Heal it:\n // once the join settles, an empty document with a non-empty seed\n // means nobody's content won — reload the seed, which the binding\n // then pushes into the room. Joiners pass no value, so exactly one\n // participant ever does this.\n const seed = valueRef.current;\n const reseedWhenRoomStaysEmpty = () => {\n if (!seed) return;\n const check = async (attempt: number) => {\n if (disposed || !editorInstance.current) return;\n try {\n const buffer =\n await editorInstance.current.saveDocument(MARKDOWN_TYPE);\n const current = new globalThis.TextDecoder()\n .decode(buffer)\n .trim();\n if (disposed || !editorInstance.current) return;\n if (current) return; // somebody's content arrived — done\n if (attempt >= 2) {\n await editorInstance.current.loadDocumentText(\n valueTypeRef.current,\n seed\n );\n return;\n }\n setTimeout(() => void check(attempt + 1), 300);\n } catch {\n // A failed probe must not break the editor; the room stays as-is.\n }\n };\n setTimeout(() => void check(0), 300);\n };\n\n if (valueRef.current) {\n await queueInitialLoad(() =>\n editor!.loadDocumentText(valueTypeRef.current, valueRef.current)\n );\n }\n if (disposed) return;\n loadedDocRef.current = editor.view.state.doc;\n lastSerializedDoc.current = editor.view.state.doc;\n if (showPreviewRef.current) setMd(valueRef.current);\n if (loadVersion === loadVersionRef.current) loadingRef.current = false;\n onReadyRef.current?.(editor);\n joinRoom();\n };\n\n const pending = setup();\n readyRef.current = pending;\n // Observe the rejection without replacing the readiness promise: callers\n // must be able to detect a failed load instead of saving stale content.\n void pending.catch((error) => {\n if (disposed) return;\n loadingRef.current = false;\n console.error('Failed to set up editor:', error);\n onErrorRef.current?.(error);\n });\n\n // Cleanup on unmount\n return () => {\n disposed = true;\n editorInstance.current = null; // makes onTransaction's guard effective\n editor?.removeEventListener('transaction', onTransaction);\n editor?.destroy();\n readyRef.current = null;\n host.replaceChildren();\n };\n // Initial `value`/`collab` are intentionally only applied on mount\n // (uncontrolled). Remount via `key` to switch rooms.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useImperativeHandle(\n ref,\n () => ({\n getContent: async (): Promise<string> => {\n while (true) {\n await readyRef.current;\n const editor = editorInstance.current;\n if (!editor) return valueRef.current;\n const doc = editor.view.state.doc;\n const loadVersion = loadVersionRef.current;\n if (doc === loadedDocRef.current) return valueRef.current;\n const buffer = await editor.saveDocument(valueTypeRef.current);\n if (\n editorInstance.current !== editor ||\n loadVersion !== loadVersionRef.current ||\n doc !== editor.view.state.doc\n )\n continue;\n const markdown = new globalThis.TextDecoder().decode(buffer);\n valueRef.current = markdown;\n loadedDocRef.current = doc;\n lastSerializedDoc.current = doc;\n return markdown;\n }\n },\n focus: (): void => {\n const apply = (): void => {\n const view = editorInstance.current?.view as\n | { focus?: () => void }\n | undefined;\n if (view?.focus) {\n view.focus();\n return;\n }\n hostRef.current\n ?.querySelector<HTMLElement>('[contenteditable=\"true\"], textarea')\n ?.focus();\n };\n // Callers focus on mount; the editor may still be loading its kits.\n if (editorInstance.current) apply();\n else void readyRef.current?.then(apply, () => undefined);\n },\n }),\n []\n );\n\n return (\n <div>\n <div>\n <div\n ref={hostRef}\n id={id}\n className={[\n 'kb-component',\n isDark ? 'kb-component--dark' : '',\n className ?? '',\n ]\n .filter(Boolean)\n .join(' ')}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-disabled={disabled || undefined}\n style={{\n isolation: 'isolate',\n opacity: disabled ? 0.65 : undefined,\n pointerEvents: disabled ? 'none' : undefined,\n }}\n />\n </div>\n\n {showPreview && (\n <div>\n <div>\n <h5>Markdown Output</h5>\n <pre>{md}</pre>\n </div>\n </div>\n )}\n </div>\n );\n }\n);\n\nRichEditor.displayName = 'RichEditor';\n\nexport { RichEditor };\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Dropdown/Dropdown.tsx"],"names":["Fragment","rtl","ChevronRightIcon"],"mappings":"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","file":"chunk-OYUIEJPN.js","sourcesContent":["import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { ChevronRight as ChevronRightIcon } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { useClickOutside } from '../../hooks/useClickOutside';\nimport { isRtl } from '../../hooks/useDirection';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\nimport {\n useAnchoredPosition,\n type AnchoredPlacement,\n type AnchoredSide,\n} from '../../hooks/useAnchoredPosition';\nimport { Animated, AnimatedPresence } from '../../motion';\nimport { inputVariants } from '../Input';\n\nexport type DropdownPlacement = AnchoredPlacement;\n\nexport interface DropdownProps {\n /** The trigger element (usually a button) */\n trigger: React.ReactElement<{\n onClick?: () => void;\n disabled?: boolean;\n 'aria-haspopup'?: string;\n 'aria-expanded'?: boolean;\n 'aria-controls'?: string;\n }>;\n /** Dropdown content */\n children: React.ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Placement of the dropdown */\n placement?: DropdownPlacement;\n /** Additional class name for the dropdown menu */\n className?: string;\n /** Width of the dropdown menu */\n width?: 'auto' | 'trigger' | number;\n /** Whether the dropdown is disabled */\n disabled?: boolean;\n /** Whether to render a search field at the top of the dropdown */\n searchable?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Accessible label for the search input */\n searchAriaLabel?: string;\n /** Content to render when no items match the search query */\n searchEmptyState?: React.ReactNode;\n /** Whether dropdown items support multi-select checkboxes */\n multiSelect?: boolean;\n /** Selected item values for controlled multi-select dropdowns */\n selectedValues?: string[];\n /** Initial selected item values for uncontrolled multi-select dropdowns */\n defaultSelectedValues?: string[];\n /** Callback fired when selected values change in multi-select mode */\n onSelectedValuesChange?: (values: string[]) => void;\n /** Whether to render a select-all control for multi-select dropdowns */\n showSelectAll?: boolean;\n /** Label for the select-all control */\n selectAllLabel?: React.ReactNode;\n}\n\nconst placementOffset = 8; // matches the previous mt-2/mb-2 gap\n\n/**\n * Scale origin per resolved side, so the menu grows out of its trigger rather\n * than out of its own middle. Written as whole literal class names because\n * Tailwind's scanner only matches complete strings.\n */\nconst menuTransformOrigin: Record<AnchoredSide, string> = {\n bottom: 'origin-top',\n top: 'origin-bottom',\n right: 'origin-left',\n left: 'origin-right',\n};\n\n/**\n * CSS stand-in used when no motion runtime is active.\n *\n * Note this replaces `animate-in fade-in zoom-in-95 duration-100`, which was\n * dead markup: those are `tailwindcss-animate` utilities and that plugin is not\n * installed, so none of them were ever emitted into the stylesheet. `animate-fade-in`\n * is a real utility from this package's own Tailwind preset.\n */\nconst DROPDOWN_FALLBACK_ANIMATION = 'animate-fade-in';\n\ninterface DropdownContextValue {\n multiSelect: boolean;\n selectedValues: string[];\n toggleSelectedValue: (value: string) => void;\n /**\n * Registers a portaled descendant (submenu panel) with the root dropdown's\n * click-outside detection so clicks inside it don't close the menu.\n * Returns an unregister function.\n */\n registerOutsideRef: (ref: React.RefObject<HTMLElement | null>) => () => void;\n}\n\nconst DropdownContext = React.createContext<DropdownContextValue | null>(null);\n\nfunction getNodeText(node: React.ReactNode): string {\n if (typeof node === 'string' || typeof node === 'number') {\n return String(node);\n }\n\n if (Array.isArray(node)) {\n return node.map(getNodeText).join(' ');\n }\n\n if (React.isValidElement<{ children?: React.ReactNode }>(node)) {\n return getNodeText(node.props.children);\n }\n\n return '';\n}\n\nfunction isDropdownElement<P>(\n node: React.ReactNode,\n component: React.JSXElementConstructor<P>\n): node is React.ReactElement<P> {\n return React.isValidElement(node) && node.type === component;\n}\n\nfunction hasVisibleDropdownContent(node: React.ReactNode): boolean {\n if (node == null || typeof node === 'boolean') {\n return false;\n }\n\n if (Array.isArray(node)) {\n return node.some(hasVisibleDropdownContent);\n }\n\n if (!React.isValidElement<{ children?: React.ReactNode }>(node)) {\n if (typeof node === 'string') {\n return node.trim().length > 0;\n }\n\n return true;\n }\n\n if (node.type === React.Fragment) {\n return React.Children.toArray(node.props.children).some(\n hasVisibleDropdownContent\n );\n }\n\n if (\n node.type === DropdownSeparator ||\n node.type === DropdownLabel ||\n node.type === DropdownHeader\n ) {\n return false;\n }\n\n if (node.type === DropdownContent) {\n return React.Children.toArray(node.props.children).some(\n hasVisibleDropdownContent\n );\n }\n\n return true;\n}\n\nfunction normalizeDropdownSiblings(\n children: React.ReactNode[]\n): React.ReactNode[] {\n const hasContentBefore = (index: number) => {\n for (let current = index - 1; current >= 0; current -= 1) {\n const child = children[current];\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return false;\n }\n\n if (hasVisibleDropdownContent(child)) {\n return true;\n }\n }\n\n return false;\n };\n\n const hasContentAfter = (index: number) => {\n for (let current = index + 1; current < children.length; current += 1) {\n const child = children[current];\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return false;\n }\n\n if (hasVisibleDropdownContent(child)) {\n return true;\n }\n }\n\n return false;\n };\n\n return children.filter((child, index) => {\n if (isDropdownElement(child, DropdownSeparator)) {\n return hasContentBefore(index) && hasContentAfter(index);\n }\n\n if (isDropdownElement(child, DropdownLabel)) {\n return hasContentAfter(index);\n }\n\n return true;\n });\n}\n\nfunction filterDropdownChildren(\n children: React.ReactNode,\n query: string\n): React.ReactNode[] {\n const normalizedQuery = query.trim().toLowerCase();\n\n if (!normalizedQuery) {\n return React.Children.toArray(children);\n }\n\n const filteredChildren = React.Children.toArray(children)\n .map((child) => {\n if (!React.isValidElement<{ children?: React.ReactNode }>(child)) {\n if (typeof child === 'string' || typeof child === 'number') {\n return String(child).toLowerCase().includes(normalizedQuery)\n ? child\n : null;\n }\n\n return null;\n }\n\n if (child.type === React.Fragment) {\n const fragmentChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return fragmentChildren.length > 0\n ? React.cloneElement(child, undefined, fragmentChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownHeader)) {\n return child;\n }\n\n if (isDropdownElement(child, DropdownItem)) {\n const searchText = [\n getNodeText(child.props.children),\n child.props.searchText,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n return searchText.includes(normalizedQuery) ? child : null;\n }\n\n if (isDropdownElement(child, DropdownSubmenu)) {\n const searchText = [\n getNodeText(child.props.label),\n child.props.searchText,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n // Keep the whole submenu when its label matches; otherwise filter its\n // items and keep it only when something inside still matches.\n if (searchText.includes(normalizedQuery)) {\n return child;\n }\n\n const submenuChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return hasVisibleDropdownContent(submenuChildren)\n ? React.cloneElement(child, undefined, submenuChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownContent)) {\n const contentChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return hasVisibleDropdownContent(contentChildren)\n ? React.cloneElement(child, undefined, contentChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return child;\n }\n\n if (isDropdownElement(child, DropdownLabel)) {\n return child;\n }\n\n const nestedChildren = child.props.children;\n\n if (nestedChildren === undefined) {\n return child;\n }\n\n const filteredNestedChildren = filterDropdownChildren(\n nestedChildren,\n normalizedQuery\n );\n\n return filteredNestedChildren.length > 0\n ? React.cloneElement(child, undefined, filteredNestedChildren)\n : null;\n })\n .filter((child) => child !== null);\n\n return normalizeDropdownSiblings(filteredChildren);\n}\n\nfunction getSelectableValues(children: React.ReactNode): string[] {\n return React.Children.toArray(children).flatMap((child) => {\n if (\n !React.isValidElement<{ children?: React.ReactNode; value?: unknown }>(\n child\n )\n ) {\n return [];\n }\n\n if (child.type === React.Fragment || child.type === DropdownContent) {\n return getSelectableValues(child.props.children);\n }\n\n if (isDropdownElement(child, DropdownItem)) {\n return typeof child.props.value === 'string' ? [child.props.value] : [];\n }\n\n return child.props.children !== undefined\n ? getSelectableValues(child.props.children)\n : [];\n });\n}\n\n/**\n * An accessible dropdown menu component.\n *\n * @example\n * ```tsx\n * <Dropdown\n * trigger={<Button>Options</Button>}\n * >\n * <DropdownItem onClick={() => console.log('Edit')}>Edit</DropdownItem>\n * <DropdownItem onClick={() => console.log('Delete')} variant=\"danger\">Delete</DropdownItem>\n * </Dropdown>\n * ```\n */\nfunction Dropdown({\n trigger,\n children,\n open: controlledOpen,\n onOpenChange,\n placement = 'bottom-start',\n className,\n width = 'auto',\n disabled = false,\n searchable = false,\n searchPlaceholder = 'Search...',\n searchAriaLabel = 'Search dropdown items',\n searchEmptyState = 'No results found',\n multiSelect = false,\n selectedValues: controlledSelectedValues,\n defaultSelectedValues = [],\n onSelectedValuesChange,\n showSelectAll = false,\n selectAllLabel = 'Select all',\n}: DropdownProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const [uncontrolledSelectedValues, setUncontrolledSelectedValues] =\n React.useState(defaultSelectedValues);\n const [searchQuery, setSearchQuery] = React.useState('');\n const [extraOutsideRefs, setExtraOutsideRefs] = React.useState<\n ReadonlyArray<React.RefObject<HTMLElement | null>>\n >([]);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n const menuId = React.useId();\n\n const isControlled = controlledOpen !== undefined;\n const isSelectedValuesControlled = controlledSelectedValues !== undefined;\n const isOpen = isControlled ? controlledOpen : uncontrolledOpen;\n const selectedValues = isSelectedValuesControlled\n ? controlledSelectedValues\n : uncontrolledSelectedValues;\n\n const setOpen = React.useCallback(\n (value: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(value);\n }\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange]\n );\n\n const handleToggle = React.useCallback(() => {\n if (!disabled) {\n setOpen(!isOpen);\n }\n }, [disabled, isOpen, setOpen]);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const setSelectedValues = React.useCallback(\n (values: string[]) => {\n if (!isSelectedValuesControlled) {\n setUncontrolledSelectedValues(values);\n }\n onSelectedValuesChange?.(values);\n },\n [isSelectedValuesControlled, onSelectedValuesChange]\n );\n\n const toggleSelectedValue = React.useCallback(\n (value: string) => {\n if (!multiSelect) {\n return;\n }\n\n setSelectedValues(\n selectedValues.includes(value)\n ? selectedValues.filter((selectedValue) => selectedValue !== value)\n : [...selectedValues, value]\n );\n },\n [multiSelect, selectedValues, setSelectedValues]\n );\n\n const registerOutsideRef = React.useCallback(\n (ref: React.RefObject<HTMLElement | null>) => {\n setExtraOutsideRefs((prev) => [...prev, ref]);\n return () => setExtraOutsideRefs((prev) => prev.filter((r) => r !== ref));\n },\n []\n );\n\n const dropdownContext = React.useMemo<DropdownContextValue>(\n () => ({\n multiSelect,\n selectedValues,\n toggleSelectedValue,\n registerOutsideRef,\n }),\n [multiSelect, selectedValues, toggleSelectedValue, registerOutsideRef]\n );\n\n useEscapeKey(handleClose, isOpen);\n\n // Portal + fixed positioning so the menu escapes overflow-hidden ancestors.\n const { anchorRef, floatingRef, style, actualSide } = useAnchoredPosition<\n HTMLDivElement,\n HTMLDivElement\n >({\n open: isOpen,\n placement,\n offset: placementOffset,\n matchMinWidth: width === 'trigger',\n });\n\n const outsideRefs = React.useMemo(\n () => [containerRef, floatingRef, ...extraOutsideRefs],\n [floatingRef, extraOutsideRefs]\n );\n useClickOutside(outsideRefs, handleClose, isOpen);\n\n React.useEffect(() => {\n if (!isOpen) {\n setSearchQuery('');\n return;\n }\n\n if (searchable) {\n requestAnimationFrame(() => searchInputRef.current?.focus());\n }\n }, [isOpen, searchable]);\n\n // Clone trigger to add event handlers\n const triggerElement = React.cloneElement(trigger, {\n onClick: handleToggle,\n 'aria-haspopup': 'menu',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? menuId : undefined,\n disabled: disabled || trigger.props.disabled,\n });\n\n const widthStyle = typeof width === 'number' ? { width: `${width}px` } : {};\n\n const filteredChildren = React.useMemo(\n () => filterDropdownChildren(children, searchQuery),\n [children, searchQuery]\n );\n const visibleSelectableValues = React.useMemo(\n () => getSelectableValues(searchable ? filteredChildren : children),\n [children, filteredChildren, searchable]\n );\n const hasSearchResults = React.useMemo(\n () => hasVisibleDropdownContent(filteredChildren),\n [filteredChildren]\n );\n const allVisibleSelected =\n visibleSelectableValues.length > 0 &&\n visibleSelectableValues.every((value) => selectedValues.includes(value));\n const someVisibleSelected = visibleSelectableValues.some((value) =>\n selectedValues.includes(value)\n );\n\n const handleSelectAll = React.useCallback(() => {\n if (!multiSelect || visibleSelectableValues.length === 0) {\n return;\n }\n\n const visibleValueSet = new Set(visibleSelectableValues);\n\n setSelectedValues(\n allVisibleSelected\n ? selectedValues.filter((value) => !visibleValueSet.has(value))\n : Array.from(new Set([...selectedValues, ...visibleSelectableValues]))\n );\n }, [\n allVisibleSelected,\n multiSelect,\n selectedValues,\n setSelectedValues,\n visibleSelectableValues,\n ]);\n\n return (\n <DropdownContext.Provider value={dropdownContext}>\n <div\n ref={(node) => {\n containerRef.current = node;\n anchorRef.current = node;\n }}\n className=\"relative inline-flex\"\n >\n {triggerElement}\n {typeof document !== 'undefined' &&\n createPortal(\n <AnimatedPresence>\n {isOpen && (\n <Animated\n key=\"dropdown-menu\"\n ref={floatingRef as React.Ref<HTMLElement>}\n preset=\"menu\"\n mode=\"presence\"\n // Post-flip side, not the requested `placement`: a menu that\n // flipped for want of room has to animate from where it\n // actually landed.\n custom={actualSide}\n style={{ ...style, ...widthStyle }}\n data-slot=\"dropdown-menu\"\n className={cn(\n 'flex min-w-[12rem] flex-col overflow-hidden',\n 'rounded-xl border border-neutral-200 bg-white shadow-lg',\n 'dark:border-neutral-700 dark:bg-neutral-800',\n // Anchors the scale to the trigger. Static per side and never\n // animated, so CSS owns it rather than the preset.\n menuTransformOrigin[actualSide],\n className\n )}\n fallbackClassName={DROPDOWN_FALLBACK_ANIMATION}\n >\n {searchable && (\n <div\n className=\"shrink-0 border-b border-neutral-200 p-2 dark:border-neutral-700\"\n data-slot=\"dropdown-search\"\n >\n <input\n ref={searchInputRef}\n type=\"search\"\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.target.value)}\n placeholder={searchPlaceholder}\n aria-label={searchAriaLabel}\n aria-controls={menuId}\n aria-autocomplete=\"list\"\n data-slot=\"dropdown-search-input\"\n className={cn(\n inputVariants({ size: 'sm' }),\n 'text-sm',\n 'dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-100'\n )}\n />\n </div>\n )}\n <div\n id={menuId}\n role=\"menu\"\n className=\"min-h-0 overflow-y-auto\"\n >\n {multiSelect &&\n showSelectAll &&\n visibleSelectableValues.length > 0 && (\n <>\n <div className=\"p-2\" data-slot=\"dropdown-select-all\">\n <DropdownItem\n checked={allVisibleSelected}\n indeterminate={\n !allVisibleSelected && someVisibleSelected\n }\n onClick={handleSelectAll}\n >\n {selectAllLabel}\n </DropdownItem>\n </div>\n <DropdownSeparator />\n </>\n )}\n {searchable ? (\n hasSearchResults ? (\n filteredChildren\n ) : (\n <div\n className=\"text-muted-foreground px-3 py-4 text-center text-sm\"\n data-slot=\"dropdown-empty\"\n >\n {searchEmptyState}\n </div>\n )\n ) : (\n children\n )}\n </div>\n </Animated>\n )}\n </AnimatedPresence>,\n document.body\n )}\n </div>\n </DropdownContext.Provider>\n );\n}\n\nDropdown.displayName = 'Dropdown';\n\n// ============================================================================\n// Dropdown Header Component\n// ============================================================================\n\nexport interface DropdownHeaderProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /** Avatar element or image */\n avatar?: React.ReactNode;\n /** Primary text (e.g., user name) */\n title: React.ReactNode;\n /** Secondary text (e.g., email) */\n subtitle?: React.ReactNode;\n}\n\n/**\n * A header section for dropdown menus, typically used for user info.\n *\n * @example\n * ```tsx\n * <DropdownHeader\n * avatar={<Avatar name=\"John Doe\" />}\n * title=\"John Doe\"\n * subtitle=\"john@example.com\"\n * />\n * ```\n */\nconst DropdownHeader = React.forwardRef<HTMLDivElement, DropdownHeaderProps>(\n ({ className, avatar, title, subtitle, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"dropdown-header\"\n className={cn(\n 'border-b border-neutral-200 p-4 dark:border-neutral-700',\n className\n )}\n {...props}\n >\n <div\n className=\"flex items-center gap-3\"\n data-slot=\"dropdown-header-row\"\n >\n {avatar}\n <div className=\"min-w-0 flex-1\">\n <p\n className=\"truncate text-sm font-semibold text-neutral-900 dark:text-white\"\n data-slot=\"dropdown-header-title\"\n >\n {title}\n </p>\n {subtitle && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n data-slot=\"dropdown-header-subtitle\"\n >\n {subtitle}\n </p>\n )}\n </div>\n </div>\n {children}\n </div>\n );\n }\n);\n\nDropdownHeader.displayName = 'DropdownHeader';\n\n// ============================================================================\n// Dropdown Content Component\n// ============================================================================\n\nexport type DropdownContentProps = React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * A container for dropdown menu items with proper padding.\n */\nconst DropdownContent = React.forwardRef<HTMLDivElement, DropdownContentProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"dropdown-content\"\n className={cn('p-2', className)}\n {...props}\n />\n );\n }\n);\n\nDropdownContent.displayName = 'DropdownContent';\n\n// ============================================================================\n// Dropdown Item Component\n// ============================================================================\n\nexport interface DropdownItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Icon to display before the label */\n icon?: React.ReactNode;\n /** Danger variant for destructive actions */\n variant?: 'default' | 'danger';\n /** Optional text used when filtering searchable dropdown items */\n searchText?: string;\n /** Checked state for multi-select items */\n checked?: boolean;\n /** Indeterminate state for multi-select items */\n indeterminate?: boolean;\n /** Callback fired when a multi-select item changes */\n onCheckedChange?: (checked: boolean) => void;\n}\n\nfunction DropdownItemCheckbox({\n checked,\n indeterminate = false,\n}: {\n checked: boolean;\n indeterminate?: boolean;\n}) {\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"dropdown-checkbox\"\n className={cn(\n 'flex h-4 w-4 shrink-0 items-center justify-center rounded border-2 transition-colors duration-150',\n checked || indeterminate\n ? 'border-primary-500 bg-primary-800 text-white'\n : 'border-input bg-background text-transparent'\n )}\n >\n {indeterminate ? (\n <svg\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M4 8h8\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n ) : (\n <svg\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </span>\n );\n}\n\n/**\n * An item within a Dropdown menu.\n */\nconst DropdownItem = React.forwardRef<HTMLButtonElement, DropdownItemProps>(\n (\n {\n className,\n icon,\n variant = 'default',\n children,\n searchText,\n checked,\n indeterminate = false,\n onCheckedChange,\n onClick,\n value,\n disabled,\n ...props\n },\n ref\n ) => {\n const dropdownContext = React.useContext(DropdownContext);\n const itemValue = typeof value === 'string' ? value : undefined;\n const contextSelectedValues = dropdownContext?.selectedValues ?? [];\n const isMultiSelectItem =\n (dropdownContext?.multiSelect === true && itemValue !== undefined) ||\n checked !== undefined ||\n indeterminate;\n const isChecked =\n checked ??\n (isMultiSelectItem\n ? itemValue !== undefined && contextSelectedValues.includes(itemValue)\n : false);\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n if (\n dropdownContext &&\n isMultiSelectItem &&\n itemValue !== undefined &&\n !disabled\n ) {\n dropdownContext.toggleSelectedValue(itemValue);\n onCheckedChange?.(!isChecked);\n }\n\n onClick?.(event);\n },\n [\n disabled,\n dropdownContext,\n isChecked,\n isMultiSelectItem,\n itemValue,\n onCheckedChange,\n onClick,\n ]\n );\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role={isMultiSelectItem ? 'menuitemcheckbox' : 'menuitem'}\n aria-checked={\n isMultiSelectItem ? (indeterminate ? 'mixed' : isChecked) : undefined\n }\n disabled={disabled}\n data-slot=\"dropdown-item\"\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm',\n 'transition-colors duration-150',\n 'focus:outline-none',\n variant === 'default' && [\n 'text-neutral-700 dark:text-neutral-300',\n 'hover:bg-neutral-100 dark:hover:bg-neutral-700',\n 'focus:bg-neutral-100 dark:focus:bg-neutral-700',\n ],\n variant === 'danger' && [\n 'text-red-600 dark:text-red-400',\n 'hover:bg-red-50 dark:hover:bg-red-900/20',\n 'focus:bg-red-50 dark:focus:bg-red-900/20',\n ],\n className\n )}\n data-search-text={searchText}\n onClick={handleClick}\n value={value}\n {...props}\n >\n {isMultiSelectItem && (\n <DropdownItemCheckbox\n checked={isChecked}\n indeterminate={indeterminate}\n />\n )}\n {icon && (\n <span className=\"h-4 w-4 shrink-0\" data-slot=\"dropdown-item-icon\">\n {icon}\n </span>\n )}\n <span className=\"font-medium\" data-slot=\"dropdown-item-label\">\n {children}\n </span>\n </button>\n );\n }\n);\n\nDropdownItem.displayName = 'DropdownItem';\n\n// ============================================================================\n// Dropdown Submenu Component\n// ============================================================================\n\nexport interface DropdownSubmenuProps {\n /** The parent item's label */\n label: React.ReactNode;\n /** Icon to display before the label */\n icon?: React.ReactNode;\n /** Whether the submenu trigger is disabled */\n disabled?: boolean;\n /** Optional text used when filtering searchable dropdown items */\n searchText?: string;\n /** Additional class name for the submenu trigger item */\n className?: string;\n /** Submenu items */\n children: React.ReactNode;\n}\n\n/** Delay before a hover-opened submenu closes, allowing diagonal travel. */\nconst submenuCloseDelay = 150;\n\n/**\n * A dropdown item that opens a nested flyout menu.\n *\n * Opens on hover or click, and from the keyboard via Enter/Space or the\n * arrow toward the inline-end (ArrowRight in LTR, ArrowLeft in RTL); the\n * opposite arrow or Escape closes just the submenu (Escape is stopped so the\n * root menu stays open) and returns focus to the trigger.\n *\n * @example\n * ```tsx\n * <Dropdown trigger={<Button>Options</Button>}>\n * <DropdownItem onClick={copy}>Copy</DropdownItem>\n * <DropdownSubmenu label=\"Copy as\">\n * <DropdownItem onClick={copyMarkdown}>Markdown</DropdownItem>\n * <DropdownItem onClick={copyPlain}>Plain text</DropdownItem>\n * </DropdownSubmenu>\n * </Dropdown>\n * ```\n */\nfunction DropdownSubmenu({\n label,\n icon,\n disabled = false,\n className,\n children,\n}: DropdownSubmenuProps) {\n const [open, setOpen] = React.useState(false);\n // The flyout opens toward the inline-end — physical left under RTL — so\n // the panel side matches the open key and the flipped chevron.\n const [rtl, setRtl] = React.useState(false);\n const menuId = React.useId();\n const dropdownContext = React.useContext(DropdownContext);\n const closeTimer = React.useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n\n const { anchorRef, floatingRef, style, actualSide } = useAnchoredPosition<\n HTMLButtonElement,\n HTMLDivElement\n >({ open, placement: rtl ? 'left-start' : 'right-start', offset: 4 });\n\n // Sample direction when opening; layout effect so the reposition with the\n // corrected placement happens before paint (no wrong-side flash).\n React.useLayoutEffect(() => {\n if (open) setRtl(isRtl(anchorRef.current));\n }, [open, anchorRef]);\n\n // Let the root dropdown treat clicks inside the portaled flyout as \"inside\"\n // so they don't dismiss the whole menu. Layout effect so the registration\n // flushes before the browser can deliver the next mousedown/touchstart —\n // a passive effect could lose a fast open-then-click race.\n const registerOutsideRef = dropdownContext?.registerOutsideRef;\n React.useLayoutEffect(() => {\n if (!open || !registerOutsideRef) return;\n return registerOutsideRef(floatingRef);\n }, [open, registerOutsideRef, floatingRef]);\n\n React.useEffect(() => () => clearTimeout(closeTimer.current), []);\n\n const cancelClose = () => clearTimeout(closeTimer.current);\n const openNow = () => {\n if (disabled) return;\n cancelClose();\n setOpen(true);\n };\n const scheduleClose = () => {\n cancelClose();\n closeTimer.current = setTimeout(() => setOpen(false), submenuCloseDelay);\n };\n const closeAndRefocus = () => {\n cancelClose();\n setOpen(false);\n anchorRef.current?.focus();\n };\n\n const focusFirstItem = () => {\n // The flyout positions in a layout effect; wait a frame so it's measurable\n // and visible before moving focus.\n requestAnimationFrame(() => {\n floatingRef.current\n ?.querySelector<HTMLElement>('[data-slot=\"dropdown-item\"]')\n ?.focus();\n });\n };\n\n return (\n <>\n <button\n ref={anchorRef}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n data-slot=\"dropdown-submenu-trigger\"\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm',\n 'transition-colors duration-150',\n 'focus:outline-none',\n 'text-neutral-700 dark:text-neutral-300',\n 'hover:bg-neutral-100 dark:hover:bg-neutral-700',\n 'focus:bg-neutral-100 dark:focus:bg-neutral-700',\n open && 'bg-neutral-100 dark:bg-neutral-700',\n className\n )}\n onPointerEnter={(event) => {\n // Hover-open is a mouse affordance; touch taps go through onClick so\n // the flyout doesn't open-then-toggle on the same tap.\n if (event.pointerType === 'mouse') openNow();\n }}\n onPointerLeave={(event) => {\n if (event.pointerType === 'mouse') scheduleClose();\n }}\n onClick={(event) => {\n openNow();\n // Keyboard activation (Enter/Space fire click with detail 0) moves\n // focus into the flyout; pointer clicks leave focus on the trigger.\n if (event.detail === 0) focusFirstItem();\n }}\n onKeyDown={(event) => {\n // The submenu opens toward the inline-end and its chevron flips\n // under RTL, so the open/close arrows are visual and invert too.\n const rtl = isRtl(event.currentTarget);\n const openKey = rtl ? 'ArrowLeft' : 'ArrowRight';\n const closeKey = rtl ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === openKey) {\n event.preventDefault();\n openNow();\n focusFirstItem();\n } else if (\n open &&\n (event.key === closeKey || event.key === 'Escape')\n ) {\n event.preventDefault();\n // Keep the root menu open: stop Escape before it reaches the\n // document-level listener that closes the whole dropdown.\n event.stopPropagation();\n closeAndRefocus();\n }\n }}\n >\n {icon && (\n <span className=\"h-4 w-4 shrink-0\" data-slot=\"dropdown-item-icon\">\n {icon}\n </span>\n )}\n <span className=\"flex-1 font-medium\" data-slot=\"dropdown-item-label\">\n {label}\n </span>\n <ChevronRightIcon\n size={16}\n aria-hidden=\"true\"\n className=\"shrink-0 text-neutral-400 rtl:-scale-x-100\"\n />\n </button>\n {typeof document !== 'undefined' &&\n createPortal(\n <AnimatedPresence>\n {open && (\n <Animated\n key=\"dropdown-submenu\"\n ref={floatingRef}\n style={style}\n preset=\"menu\"\n mode=\"presence\"\n // A submenu opens to the side and flips when it runs out of\n // room, so it has to animate from the side it actually landed\n // on — same contract as the root menu.\n custom={actualSide}\n id={menuId}\n role=\"menu\"\n // Programmatically focusable (a11y: interactive role); focus\n // lands on the menu items themselves.\n tabIndex={-1}\n data-slot=\"dropdown-submenu\"\n className={cn(\n // min() keeps the preferred width from beating the hook's\n // maxWidth viewport clamp on very narrow screens.\n 'flex min-w-[min(10rem,calc(100vw-1rem))] flex-col overflow-hidden',\n 'rounded-xl border border-neutral-200 bg-white shadow-lg',\n 'dark:border-neutral-700 dark:bg-neutral-800',\n // Anchors the scale to the trigger, as on the root menu.\n menuTransformOrigin[actualSide]\n )}\n fallbackClassName={DROPDOWN_FALLBACK_ANIMATION}\n onPointerEnter={cancelClose}\n onPointerLeave={(event) => {\n if (event.pointerType === 'mouse') scheduleClose();\n }}\n onKeyDown={(event) => {\n // The panel is portaled to document.body, so computing the\n // direction from event.currentTarget would miss a local dir\n // override around the dropdown — reuse the direction sampled\n // from the in-place trigger when the flyout opened.\n const closeKey = rtl ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === closeKey || event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n closeAndRefocus();\n }\n }}\n >\n <div className=\"min-h-0 overflow-y-auto\">{children}</div>\n </Animated>\n )}\n </AnimatedPresence>,\n document.body\n )}\n </>\n );\n}\n\nDropdownSubmenu.displayName = 'DropdownSubmenu';\n\n// ============================================================================\n// Dropdown Separator Component\n// ============================================================================\n\n/**\n * A separator between dropdown items.\n */\nfunction DropdownSeparator({ className }: { className?: string }) {\n return (\n <hr\n data-slot=\"dropdown-separator\"\n className={cn(\n 'border-t border-neutral-200 dark:border-neutral-700',\n className\n )}\n />\n );\n}\n\nDropdownSeparator.displayName = 'DropdownSeparator';\n\n// ============================================================================\n// Dropdown Label Component\n// ============================================================================\n\n/**\n * A label/header for a group of dropdown items.\n */\nfunction DropdownLabel({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <div\n data-slot=\"dropdown-label\"\n className={cn(\n 'px-3 py-1.5 text-xs font-semibold tracking-wider uppercase',\n 'text-muted-foreground',\n className\n )}\n >\n {children}\n </div>\n );\n}\n\nDropdownLabel.displayName = 'DropdownLabel';\n\nexport {\n Dropdown,\n DropdownHeader,\n DropdownContent,\n DropdownItem,\n DropdownSubmenu,\n DropdownSeparator,\n DropdownLabel,\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Dropdown/Dropdown.tsx"],"names":["React","useEscapeKey","useAnchoredPosition","useClickOutside","jsx","jsxs","createPortal","AnimatedPresence","Animated","cn","inputVariants","Fragment","isRtl","rtl","ChevronRightIcon"],"mappings":"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","file":"chunk-PINIBEIU.cjs","sourcesContent":["import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { ChevronRight as ChevronRightIcon } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { useClickOutside } from '../../hooks/useClickOutside';\nimport { isRtl } from '../../hooks/useDirection';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\nimport {\n useAnchoredPosition,\n type AnchoredPlacement,\n type AnchoredSide,\n} from '../../hooks/useAnchoredPosition';\nimport { Animated, AnimatedPresence } from '../../motion';\nimport { inputVariants } from '../Input';\n\nexport type DropdownPlacement = AnchoredPlacement;\n\nexport interface DropdownProps {\n /** The trigger element (usually a button) */\n trigger: React.ReactElement<{\n onClick?: () => void;\n disabled?: boolean;\n 'aria-haspopup'?: string;\n 'aria-expanded'?: boolean;\n 'aria-controls'?: string;\n }>;\n /** Dropdown content */\n children: React.ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Placement of the dropdown */\n placement?: DropdownPlacement;\n /** Additional class name for the dropdown menu */\n className?: string;\n /** Width of the dropdown menu */\n width?: 'auto' | 'trigger' | number;\n /** Whether the dropdown is disabled */\n disabled?: boolean;\n /** Whether to render a search field at the top of the dropdown */\n searchable?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Accessible label for the search input */\n searchAriaLabel?: string;\n /** Content to render when no items match the search query */\n searchEmptyState?: React.ReactNode;\n /** Whether dropdown items support multi-select checkboxes */\n multiSelect?: boolean;\n /** Selected item values for controlled multi-select dropdowns */\n selectedValues?: string[];\n /** Initial selected item values for uncontrolled multi-select dropdowns */\n defaultSelectedValues?: string[];\n /** Callback fired when selected values change in multi-select mode */\n onSelectedValuesChange?: (values: string[]) => void;\n /** Whether to render a select-all control for multi-select dropdowns */\n showSelectAll?: boolean;\n /** Label for the select-all control */\n selectAllLabel?: React.ReactNode;\n}\n\nconst placementOffset = 8; // matches the previous mt-2/mb-2 gap\n\n/**\n * Scale origin per resolved side, so the menu grows out of its trigger rather\n * than out of its own middle. Written as whole literal class names because\n * Tailwind's scanner only matches complete strings.\n */\nconst menuTransformOrigin: Record<AnchoredSide, string> = {\n bottom: 'origin-top',\n top: 'origin-bottom',\n right: 'origin-left',\n left: 'origin-right',\n};\n\n/**\n * CSS stand-in used when no motion runtime is active.\n *\n * Note this replaces `animate-in fade-in zoom-in-95 duration-100`, which was\n * dead markup: those are `tailwindcss-animate` utilities and that plugin is not\n * installed, so none of them were ever emitted into the stylesheet. `animate-fade-in`\n * is a real utility from this package's own Tailwind preset.\n */\nconst DROPDOWN_FALLBACK_ANIMATION = 'animate-fade-in';\n\ninterface DropdownContextValue {\n multiSelect: boolean;\n selectedValues: string[];\n toggleSelectedValue: (value: string) => void;\n /**\n * Registers a portaled descendant (submenu panel) with the root dropdown's\n * click-outside detection so clicks inside it don't close the menu.\n * Returns an unregister function.\n */\n registerOutsideRef: (ref: React.RefObject<HTMLElement | null>) => () => void;\n}\n\nconst DropdownContext = React.createContext<DropdownContextValue | null>(null);\n\nfunction getNodeText(node: React.ReactNode): string {\n if (typeof node === 'string' || typeof node === 'number') {\n return String(node);\n }\n\n if (Array.isArray(node)) {\n return node.map(getNodeText).join(' ');\n }\n\n if (React.isValidElement<{ children?: React.ReactNode }>(node)) {\n return getNodeText(node.props.children);\n }\n\n return '';\n}\n\nfunction isDropdownElement<P>(\n node: React.ReactNode,\n component: React.JSXElementConstructor<P>\n): node is React.ReactElement<P> {\n return React.isValidElement(node) && node.type === component;\n}\n\nfunction hasVisibleDropdownContent(node: React.ReactNode): boolean {\n if (node == null || typeof node === 'boolean') {\n return false;\n }\n\n if (Array.isArray(node)) {\n return node.some(hasVisibleDropdownContent);\n }\n\n if (!React.isValidElement<{ children?: React.ReactNode }>(node)) {\n if (typeof node === 'string') {\n return node.trim().length > 0;\n }\n\n return true;\n }\n\n if (node.type === React.Fragment) {\n return React.Children.toArray(node.props.children).some(\n hasVisibleDropdownContent\n );\n }\n\n if (\n node.type === DropdownSeparator ||\n node.type === DropdownLabel ||\n node.type === DropdownHeader\n ) {\n return false;\n }\n\n if (node.type === DropdownContent) {\n return React.Children.toArray(node.props.children).some(\n hasVisibleDropdownContent\n );\n }\n\n return true;\n}\n\nfunction normalizeDropdownSiblings(\n children: React.ReactNode[]\n): React.ReactNode[] {\n const hasContentBefore = (index: number) => {\n for (let current = index - 1; current >= 0; current -= 1) {\n const child = children[current];\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return false;\n }\n\n if (hasVisibleDropdownContent(child)) {\n return true;\n }\n }\n\n return false;\n };\n\n const hasContentAfter = (index: number) => {\n for (let current = index + 1; current < children.length; current += 1) {\n const child = children[current];\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return false;\n }\n\n if (hasVisibleDropdownContent(child)) {\n return true;\n }\n }\n\n return false;\n };\n\n return children.filter((child, index) => {\n if (isDropdownElement(child, DropdownSeparator)) {\n return hasContentBefore(index) && hasContentAfter(index);\n }\n\n if (isDropdownElement(child, DropdownLabel)) {\n return hasContentAfter(index);\n }\n\n return true;\n });\n}\n\nfunction filterDropdownChildren(\n children: React.ReactNode,\n query: string\n): React.ReactNode[] {\n const normalizedQuery = query.trim().toLowerCase();\n\n if (!normalizedQuery) {\n return React.Children.toArray(children);\n }\n\n const filteredChildren = React.Children.toArray(children)\n .map((child) => {\n if (!React.isValidElement<{ children?: React.ReactNode }>(child)) {\n if (typeof child === 'string' || typeof child === 'number') {\n return String(child).toLowerCase().includes(normalizedQuery)\n ? child\n : null;\n }\n\n return null;\n }\n\n if (child.type === React.Fragment) {\n const fragmentChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return fragmentChildren.length > 0\n ? React.cloneElement(child, undefined, fragmentChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownHeader)) {\n return child;\n }\n\n if (isDropdownElement(child, DropdownItem)) {\n const searchText = [\n getNodeText(child.props.children),\n child.props.searchText,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n return searchText.includes(normalizedQuery) ? child : null;\n }\n\n if (isDropdownElement(child, DropdownSubmenu)) {\n const searchText = [\n getNodeText(child.props.label),\n child.props.searchText,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n // Keep the whole submenu when its label matches; otherwise filter its\n // items and keep it only when something inside still matches.\n if (searchText.includes(normalizedQuery)) {\n return child;\n }\n\n const submenuChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return hasVisibleDropdownContent(submenuChildren)\n ? React.cloneElement(child, undefined, submenuChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownContent)) {\n const contentChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return hasVisibleDropdownContent(contentChildren)\n ? React.cloneElement(child, undefined, contentChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return child;\n }\n\n if (isDropdownElement(child, DropdownLabel)) {\n return child;\n }\n\n const nestedChildren = child.props.children;\n\n if (nestedChildren === undefined) {\n return child;\n }\n\n const filteredNestedChildren = filterDropdownChildren(\n nestedChildren,\n normalizedQuery\n );\n\n return filteredNestedChildren.length > 0\n ? React.cloneElement(child, undefined, filteredNestedChildren)\n : null;\n })\n .filter((child) => child !== null);\n\n return normalizeDropdownSiblings(filteredChildren);\n}\n\nfunction getSelectableValues(children: React.ReactNode): string[] {\n return React.Children.toArray(children).flatMap((child) => {\n if (\n !React.isValidElement<{ children?: React.ReactNode; value?: unknown }>(\n child\n )\n ) {\n return [];\n }\n\n if (child.type === React.Fragment || child.type === DropdownContent) {\n return getSelectableValues(child.props.children);\n }\n\n if (isDropdownElement(child, DropdownItem)) {\n return typeof child.props.value === 'string' ? [child.props.value] : [];\n }\n\n return child.props.children !== undefined\n ? getSelectableValues(child.props.children)\n : [];\n });\n}\n\n/**\n * An accessible dropdown menu component.\n *\n * @example\n * ```tsx\n * <Dropdown\n * trigger={<Button>Options</Button>}\n * >\n * <DropdownItem onClick={() => console.log('Edit')}>Edit</DropdownItem>\n * <DropdownItem onClick={() => console.log('Delete')} variant=\"danger\">Delete</DropdownItem>\n * </Dropdown>\n * ```\n */\nfunction Dropdown({\n trigger,\n children,\n open: controlledOpen,\n onOpenChange,\n placement = 'bottom-start',\n className,\n width = 'auto',\n disabled = false,\n searchable = false,\n searchPlaceholder = 'Search...',\n searchAriaLabel = 'Search dropdown items',\n searchEmptyState = 'No results found',\n multiSelect = false,\n selectedValues: controlledSelectedValues,\n defaultSelectedValues = [],\n onSelectedValuesChange,\n showSelectAll = false,\n selectAllLabel = 'Select all',\n}: DropdownProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const [uncontrolledSelectedValues, setUncontrolledSelectedValues] =\n React.useState(defaultSelectedValues);\n const [searchQuery, setSearchQuery] = React.useState('');\n const [extraOutsideRefs, setExtraOutsideRefs] = React.useState<\n ReadonlyArray<React.RefObject<HTMLElement | null>>\n >([]);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n const menuId = React.useId();\n\n const isControlled = controlledOpen !== undefined;\n const isSelectedValuesControlled = controlledSelectedValues !== undefined;\n const isOpen = isControlled ? controlledOpen : uncontrolledOpen;\n const selectedValues = isSelectedValuesControlled\n ? controlledSelectedValues\n : uncontrolledSelectedValues;\n\n const setOpen = React.useCallback(\n (value: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(value);\n }\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange]\n );\n\n const handleToggle = React.useCallback(() => {\n if (!disabled) {\n setOpen(!isOpen);\n }\n }, [disabled, isOpen, setOpen]);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const setSelectedValues = React.useCallback(\n (values: string[]) => {\n if (!isSelectedValuesControlled) {\n setUncontrolledSelectedValues(values);\n }\n onSelectedValuesChange?.(values);\n },\n [isSelectedValuesControlled, onSelectedValuesChange]\n );\n\n const toggleSelectedValue = React.useCallback(\n (value: string) => {\n if (!multiSelect) {\n return;\n }\n\n setSelectedValues(\n selectedValues.includes(value)\n ? selectedValues.filter((selectedValue) => selectedValue !== value)\n : [...selectedValues, value]\n );\n },\n [multiSelect, selectedValues, setSelectedValues]\n );\n\n const registerOutsideRef = React.useCallback(\n (ref: React.RefObject<HTMLElement | null>) => {\n setExtraOutsideRefs((prev) => [...prev, ref]);\n return () => setExtraOutsideRefs((prev) => prev.filter((r) => r !== ref));\n },\n []\n );\n\n const dropdownContext = React.useMemo<DropdownContextValue>(\n () => ({\n multiSelect,\n selectedValues,\n toggleSelectedValue,\n registerOutsideRef,\n }),\n [multiSelect, selectedValues, toggleSelectedValue, registerOutsideRef]\n );\n\n useEscapeKey(handleClose, isOpen);\n\n // Portal + fixed positioning so the menu escapes overflow-hidden ancestors.\n const { anchorRef, floatingRef, style, actualSide } = useAnchoredPosition<\n HTMLDivElement,\n HTMLDivElement\n >({\n open: isOpen,\n placement,\n offset: placementOffset,\n matchMinWidth: width === 'trigger',\n });\n\n const outsideRefs = React.useMemo(\n () => [containerRef, floatingRef, ...extraOutsideRefs],\n [floatingRef, extraOutsideRefs]\n );\n useClickOutside(outsideRefs, handleClose, isOpen);\n\n React.useEffect(() => {\n if (!isOpen) {\n setSearchQuery('');\n return;\n }\n\n if (searchable) {\n requestAnimationFrame(() => searchInputRef.current?.focus());\n }\n }, [isOpen, searchable]);\n\n // Clone trigger to add event handlers\n const triggerElement = React.cloneElement(trigger, {\n onClick: handleToggle,\n 'aria-haspopup': 'menu',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? menuId : undefined,\n disabled: disabled || trigger.props.disabled,\n });\n\n const widthStyle = typeof width === 'number' ? { width: `${width}px` } : {};\n\n const filteredChildren = React.useMemo(\n () => filterDropdownChildren(children, searchQuery),\n [children, searchQuery]\n );\n const visibleSelectableValues = React.useMemo(\n () => getSelectableValues(searchable ? filteredChildren : children),\n [children, filteredChildren, searchable]\n );\n const hasSearchResults = React.useMemo(\n () => hasVisibleDropdownContent(filteredChildren),\n [filteredChildren]\n );\n const allVisibleSelected =\n visibleSelectableValues.length > 0 &&\n visibleSelectableValues.every((value) => selectedValues.includes(value));\n const someVisibleSelected = visibleSelectableValues.some((value) =>\n selectedValues.includes(value)\n );\n\n const handleSelectAll = React.useCallback(() => {\n if (!multiSelect || visibleSelectableValues.length === 0) {\n return;\n }\n\n const visibleValueSet = new Set(visibleSelectableValues);\n\n setSelectedValues(\n allVisibleSelected\n ? selectedValues.filter((value) => !visibleValueSet.has(value))\n : Array.from(new Set([...selectedValues, ...visibleSelectableValues]))\n );\n }, [\n allVisibleSelected,\n multiSelect,\n selectedValues,\n setSelectedValues,\n visibleSelectableValues,\n ]);\n\n return (\n <DropdownContext.Provider value={dropdownContext}>\n <div\n ref={(node) => {\n containerRef.current = node;\n anchorRef.current = node;\n }}\n className=\"relative inline-flex\"\n >\n {triggerElement}\n {typeof document !== 'undefined' &&\n createPortal(\n <AnimatedPresence>\n {isOpen && (\n <Animated\n key=\"dropdown-menu\"\n ref={floatingRef as React.Ref<HTMLElement>}\n preset=\"menu\"\n mode=\"presence\"\n // Post-flip side, not the requested `placement`: a menu that\n // flipped for want of room has to animate from where it\n // actually landed.\n custom={actualSide}\n style={{ ...style, ...widthStyle }}\n data-slot=\"dropdown-menu\"\n className={cn(\n 'flex min-w-[12rem] flex-col overflow-hidden',\n 'rounded-xl border border-neutral-200 bg-white shadow-lg',\n 'dark:border-neutral-700 dark:bg-neutral-800',\n // Anchors the scale to the trigger. Static per side and never\n // animated, so CSS owns it rather than the preset.\n menuTransformOrigin[actualSide],\n className\n )}\n fallbackClassName={DROPDOWN_FALLBACK_ANIMATION}\n >\n {searchable && (\n <div\n className=\"shrink-0 border-b border-neutral-200 p-2 dark:border-neutral-700\"\n data-slot=\"dropdown-search\"\n >\n <input\n ref={searchInputRef}\n type=\"search\"\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.target.value)}\n placeholder={searchPlaceholder}\n aria-label={searchAriaLabel}\n aria-controls={menuId}\n aria-autocomplete=\"list\"\n data-slot=\"dropdown-search-input\"\n className={cn(\n inputVariants({ size: 'sm' }),\n 'text-sm',\n 'dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-100'\n )}\n />\n </div>\n )}\n <div\n id={menuId}\n role=\"menu\"\n className=\"min-h-0 overflow-y-auto\"\n >\n {multiSelect &&\n showSelectAll &&\n visibleSelectableValues.length > 0 && (\n <>\n <div className=\"p-2\" data-slot=\"dropdown-select-all\">\n <DropdownItem\n checked={allVisibleSelected}\n indeterminate={\n !allVisibleSelected && someVisibleSelected\n }\n onClick={handleSelectAll}\n >\n {selectAllLabel}\n </DropdownItem>\n </div>\n <DropdownSeparator />\n </>\n )}\n {searchable ? (\n hasSearchResults ? (\n filteredChildren\n ) : (\n <div\n className=\"text-muted-foreground px-3 py-4 text-center text-sm\"\n data-slot=\"dropdown-empty\"\n >\n {searchEmptyState}\n </div>\n )\n ) : (\n children\n )}\n </div>\n </Animated>\n )}\n </AnimatedPresence>,\n document.body\n )}\n </div>\n </DropdownContext.Provider>\n );\n}\n\nDropdown.displayName = 'Dropdown';\n\n// ============================================================================\n// Dropdown Header Component\n// ============================================================================\n\nexport interface DropdownHeaderProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /** Avatar element or image */\n avatar?: React.ReactNode;\n /** Primary text (e.g., user name) */\n title: React.ReactNode;\n /** Secondary text (e.g., email) */\n subtitle?: React.ReactNode;\n}\n\n/**\n * A header section for dropdown menus, typically used for user info.\n *\n * @example\n * ```tsx\n * <DropdownHeader\n * avatar={<Avatar name=\"John Doe\" />}\n * title=\"John Doe\"\n * subtitle=\"john@example.com\"\n * />\n * ```\n */\nconst DropdownHeader = React.forwardRef<HTMLDivElement, DropdownHeaderProps>(\n ({ className, avatar, title, subtitle, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"dropdown-header\"\n className={cn(\n 'border-b border-neutral-200 p-4 dark:border-neutral-700',\n className\n )}\n {...props}\n >\n <div\n className=\"flex items-center gap-3\"\n data-slot=\"dropdown-header-row\"\n >\n {avatar}\n <div className=\"min-w-0 flex-1\">\n <p\n className=\"truncate text-sm font-semibold text-neutral-900 dark:text-white\"\n data-slot=\"dropdown-header-title\"\n >\n {title}\n </p>\n {subtitle && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n data-slot=\"dropdown-header-subtitle\"\n >\n {subtitle}\n </p>\n )}\n </div>\n </div>\n {children}\n </div>\n );\n }\n);\n\nDropdownHeader.displayName = 'DropdownHeader';\n\n// ============================================================================\n// Dropdown Content Component\n// ============================================================================\n\nexport type DropdownContentProps = React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * A container for dropdown menu items with proper padding.\n */\nconst DropdownContent = React.forwardRef<HTMLDivElement, DropdownContentProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"dropdown-content\"\n className={cn('p-2', className)}\n {...props}\n />\n );\n }\n);\n\nDropdownContent.displayName = 'DropdownContent';\n\n// ============================================================================\n// Dropdown Item Component\n// ============================================================================\n\nexport interface DropdownItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Icon to display before the label */\n icon?: React.ReactNode;\n /** Danger variant for destructive actions */\n variant?: 'default' | 'danger';\n /** Optional text used when filtering searchable dropdown items */\n searchText?: string;\n /** Checked state for multi-select items */\n checked?: boolean;\n /** Indeterminate state for multi-select items */\n indeterminate?: boolean;\n /** Callback fired when a multi-select item changes */\n onCheckedChange?: (checked: boolean) => void;\n}\n\nfunction DropdownItemCheckbox({\n checked,\n indeterminate = false,\n}: {\n checked: boolean;\n indeterminate?: boolean;\n}) {\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"dropdown-checkbox\"\n className={cn(\n 'flex h-4 w-4 shrink-0 items-center justify-center rounded border-2 transition-colors duration-150',\n checked || indeterminate\n ? 'border-primary-500 bg-primary-800 text-white'\n : 'border-input bg-background text-transparent'\n )}\n >\n {indeterminate ? (\n <svg\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M4 8h8\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n ) : (\n <svg\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </span>\n );\n}\n\n/**\n * An item within a Dropdown menu.\n */\nconst DropdownItem = React.forwardRef<HTMLButtonElement, DropdownItemProps>(\n (\n {\n className,\n icon,\n variant = 'default',\n children,\n searchText,\n checked,\n indeterminate = false,\n onCheckedChange,\n onClick,\n value,\n disabled,\n ...props\n },\n ref\n ) => {\n const dropdownContext = React.useContext(DropdownContext);\n const itemValue = typeof value === 'string' ? value : undefined;\n const contextSelectedValues = dropdownContext?.selectedValues ?? [];\n const isMultiSelectItem =\n (dropdownContext?.multiSelect === true && itemValue !== undefined) ||\n checked !== undefined ||\n indeterminate;\n const isChecked =\n checked ??\n (isMultiSelectItem\n ? itemValue !== undefined && contextSelectedValues.includes(itemValue)\n : false);\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n if (\n dropdownContext &&\n isMultiSelectItem &&\n itemValue !== undefined &&\n !disabled\n ) {\n dropdownContext.toggleSelectedValue(itemValue);\n onCheckedChange?.(!isChecked);\n }\n\n onClick?.(event);\n },\n [\n disabled,\n dropdownContext,\n isChecked,\n isMultiSelectItem,\n itemValue,\n onCheckedChange,\n onClick,\n ]\n );\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role={isMultiSelectItem ? 'menuitemcheckbox' : 'menuitem'}\n aria-checked={\n isMultiSelectItem ? (indeterminate ? 'mixed' : isChecked) : undefined\n }\n disabled={disabled}\n data-slot=\"dropdown-item\"\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm',\n 'transition-colors duration-150',\n 'focus:outline-none',\n variant === 'default' && [\n 'text-neutral-700 dark:text-neutral-300',\n 'hover:bg-neutral-100 dark:hover:bg-neutral-700',\n 'focus:bg-neutral-100 dark:focus:bg-neutral-700',\n ],\n variant === 'danger' && [\n 'text-red-600 dark:text-red-400',\n 'hover:bg-red-50 dark:hover:bg-red-900/20',\n 'focus:bg-red-50 dark:focus:bg-red-900/20',\n ],\n className\n )}\n data-search-text={searchText}\n onClick={handleClick}\n value={value}\n {...props}\n >\n {isMultiSelectItem && (\n <DropdownItemCheckbox\n checked={isChecked}\n indeterminate={indeterminate}\n />\n )}\n {icon && (\n <span className=\"h-4 w-4 shrink-0\" data-slot=\"dropdown-item-icon\">\n {icon}\n </span>\n )}\n <span className=\"font-medium\" data-slot=\"dropdown-item-label\">\n {children}\n </span>\n </button>\n );\n }\n);\n\nDropdownItem.displayName = 'DropdownItem';\n\n// ============================================================================\n// Dropdown Submenu Component\n// ============================================================================\n\nexport interface DropdownSubmenuProps {\n /** The parent item's label */\n label: React.ReactNode;\n /** Icon to display before the label */\n icon?: React.ReactNode;\n /** Whether the submenu trigger is disabled */\n disabled?: boolean;\n /** Optional text used when filtering searchable dropdown items */\n searchText?: string;\n /** Additional class name for the submenu trigger item */\n className?: string;\n /** Submenu items */\n children: React.ReactNode;\n}\n\n/** Delay before a hover-opened submenu closes, allowing diagonal travel. */\nconst submenuCloseDelay = 150;\n\n/**\n * A dropdown item that opens a nested flyout menu.\n *\n * Opens on hover or click, and from the keyboard via Enter/Space or the\n * arrow toward the inline-end (ArrowRight in LTR, ArrowLeft in RTL); the\n * opposite arrow or Escape closes just the submenu (Escape is stopped so the\n * root menu stays open) and returns focus to the trigger.\n *\n * @example\n * ```tsx\n * <Dropdown trigger={<Button>Options</Button>}>\n * <DropdownItem onClick={copy}>Copy</DropdownItem>\n * <DropdownSubmenu label=\"Copy as\">\n * <DropdownItem onClick={copyMarkdown}>Markdown</DropdownItem>\n * <DropdownItem onClick={copyPlain}>Plain text</DropdownItem>\n * </DropdownSubmenu>\n * </Dropdown>\n * ```\n */\nfunction DropdownSubmenu({\n label,\n icon,\n disabled = false,\n className,\n children,\n}: DropdownSubmenuProps) {\n const [open, setOpen] = React.useState(false);\n // The flyout opens toward the inline-end — physical left under RTL — so\n // the panel side matches the open key and the flipped chevron.\n const [rtl, setRtl] = React.useState(false);\n const menuId = React.useId();\n const dropdownContext = React.useContext(DropdownContext);\n const closeTimer = React.useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n\n const { anchorRef, floatingRef, style, actualSide } = useAnchoredPosition<\n HTMLButtonElement,\n HTMLDivElement\n >({ open, placement: rtl ? 'left-start' : 'right-start', offset: 4 });\n\n // Sample direction when opening; layout effect so the reposition with the\n // corrected placement happens before paint (no wrong-side flash).\n React.useLayoutEffect(() => {\n if (open) setRtl(isRtl(anchorRef.current));\n }, [open, anchorRef]);\n\n // Let the root dropdown treat clicks inside the portaled flyout as \"inside\"\n // so they don't dismiss the whole menu. Layout effect so the registration\n // flushes before the browser can deliver the next mousedown/touchstart —\n // a passive effect could lose a fast open-then-click race.\n const registerOutsideRef = dropdownContext?.registerOutsideRef;\n React.useLayoutEffect(() => {\n if (!open || !registerOutsideRef) return;\n return registerOutsideRef(floatingRef);\n }, [open, registerOutsideRef, floatingRef]);\n\n React.useEffect(() => () => clearTimeout(closeTimer.current), []);\n\n const cancelClose = () => clearTimeout(closeTimer.current);\n const openNow = () => {\n if (disabled) return;\n cancelClose();\n setOpen(true);\n };\n const scheduleClose = () => {\n cancelClose();\n closeTimer.current = setTimeout(() => setOpen(false), submenuCloseDelay);\n };\n const closeAndRefocus = () => {\n cancelClose();\n setOpen(false);\n anchorRef.current?.focus();\n };\n\n const focusFirstItem = () => {\n // The flyout positions in a layout effect; wait a frame so it's measurable\n // and visible before moving focus.\n requestAnimationFrame(() => {\n floatingRef.current\n ?.querySelector<HTMLElement>('[data-slot=\"dropdown-item\"]')\n ?.focus();\n });\n };\n\n return (\n <>\n <button\n ref={anchorRef}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n data-slot=\"dropdown-submenu-trigger\"\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm',\n 'transition-colors duration-150',\n 'focus:outline-none',\n 'text-neutral-700 dark:text-neutral-300',\n 'hover:bg-neutral-100 dark:hover:bg-neutral-700',\n 'focus:bg-neutral-100 dark:focus:bg-neutral-700',\n open && 'bg-neutral-100 dark:bg-neutral-700',\n className\n )}\n onPointerEnter={(event) => {\n // Hover-open is a mouse affordance; touch taps go through onClick so\n // the flyout doesn't open-then-toggle on the same tap.\n if (event.pointerType === 'mouse') openNow();\n }}\n onPointerLeave={(event) => {\n if (event.pointerType === 'mouse') scheduleClose();\n }}\n onClick={(event) => {\n openNow();\n // Keyboard activation (Enter/Space fire click with detail 0) moves\n // focus into the flyout; pointer clicks leave focus on the trigger.\n if (event.detail === 0) focusFirstItem();\n }}\n onKeyDown={(event) => {\n // The submenu opens toward the inline-end and its chevron flips\n // under RTL, so the open/close arrows are visual and invert too.\n const rtl = isRtl(event.currentTarget);\n const openKey = rtl ? 'ArrowLeft' : 'ArrowRight';\n const closeKey = rtl ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === openKey) {\n event.preventDefault();\n openNow();\n focusFirstItem();\n } else if (\n open &&\n (event.key === closeKey || event.key === 'Escape')\n ) {\n event.preventDefault();\n // Keep the root menu open: stop Escape before it reaches the\n // document-level listener that closes the whole dropdown.\n event.stopPropagation();\n closeAndRefocus();\n }\n }}\n >\n {icon && (\n <span className=\"h-4 w-4 shrink-0\" data-slot=\"dropdown-item-icon\">\n {icon}\n </span>\n )}\n <span className=\"flex-1 font-medium\" data-slot=\"dropdown-item-label\">\n {label}\n </span>\n <ChevronRightIcon\n size={16}\n aria-hidden=\"true\"\n className=\"shrink-0 text-neutral-400 rtl:-scale-x-100\"\n />\n </button>\n {typeof document !== 'undefined' &&\n createPortal(\n <AnimatedPresence>\n {open && (\n <Animated\n key=\"dropdown-submenu\"\n ref={floatingRef}\n style={style}\n preset=\"menu\"\n mode=\"presence\"\n // A submenu opens to the side and flips when it runs out of\n // room, so it has to animate from the side it actually landed\n // on — same contract as the root menu.\n custom={actualSide}\n id={menuId}\n role=\"menu\"\n // Programmatically focusable (a11y: interactive role); focus\n // lands on the menu items themselves.\n tabIndex={-1}\n data-slot=\"dropdown-submenu\"\n className={cn(\n // min() keeps the preferred width from beating the hook's\n // maxWidth viewport clamp on very narrow screens.\n 'flex min-w-[min(10rem,calc(100vw-1rem))] flex-col overflow-hidden',\n 'rounded-xl border border-neutral-200 bg-white shadow-lg',\n 'dark:border-neutral-700 dark:bg-neutral-800',\n // Anchors the scale to the trigger, as on the root menu.\n menuTransformOrigin[actualSide]\n )}\n fallbackClassName={DROPDOWN_FALLBACK_ANIMATION}\n onPointerEnter={cancelClose}\n onPointerLeave={(event) => {\n if (event.pointerType === 'mouse') scheduleClose();\n }}\n onKeyDown={(event) => {\n // The panel is portaled to document.body, so computing the\n // direction from event.currentTarget would miss a local dir\n // override around the dropdown — reuse the direction sampled\n // from the in-place trigger when the flyout opened.\n const closeKey = rtl ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === closeKey || event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n closeAndRefocus();\n }\n }}\n >\n <div className=\"min-h-0 overflow-y-auto\">{children}</div>\n </Animated>\n )}\n </AnimatedPresence>,\n document.body\n )}\n </>\n );\n}\n\nDropdownSubmenu.displayName = 'DropdownSubmenu';\n\n// ============================================================================\n// Dropdown Separator Component\n// ============================================================================\n\n/**\n * A separator between dropdown items.\n */\nfunction DropdownSeparator({ className }: { className?: string }) {\n return (\n <hr\n data-slot=\"dropdown-separator\"\n className={cn(\n 'border-t border-neutral-200 dark:border-neutral-700',\n className\n )}\n />\n );\n}\n\nDropdownSeparator.displayName = 'DropdownSeparator';\n\n// ============================================================================\n// Dropdown Label Component\n// ============================================================================\n\n/**\n * A label/header for a group of dropdown items.\n */\nfunction DropdownLabel({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <div\n data-slot=\"dropdown-label\"\n className={cn(\n 'px-3 py-1.5 text-xs font-semibold tracking-wider uppercase',\n 'text-muted-foreground',\n className\n )}\n >\n {children}\n </div>\n );\n}\n\nDropdownLabel.displayName = 'DropdownLabel';\n\nexport {\n Dropdown,\n DropdownHeader,\n DropdownContent,\n DropdownItem,\n DropdownSubmenu,\n DropdownSeparator,\n DropdownLabel,\n};\n"]}