@dxos/react-ui-editor 0.8.4-main.3f58842 → 0.8.4-main.406dc2a

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 (310) hide show
  1. package/dist/lib/browser/{chunk-22UMM3QJ.mjs → chunk-HL3YF6WC.mjs} +2 -2
  2. package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +4239 -3098
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +71 -1
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/browser/types/index.mjs +1 -1
  9. package/dist/lib/node-esm/{chunk-YXYQPV6R.mjs → chunk-YJZGD3LY.mjs} +2 -2
  10. package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +7 -0
  11. package/dist/lib/node-esm/index.mjs +4239 -3098
  12. package/dist/lib/node-esm/index.mjs.map +4 -4
  13. package/dist/lib/node-esm/meta.json +1 -1
  14. package/dist/lib/node-esm/testing/index.mjs +71 -1
  15. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  16. package/dist/lib/node-esm/types/index.mjs +1 -1
  17. package/dist/types/src/components/Editor/Editor.d.ts +24 -9
  18. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  19. package/dist/types/src/components/Editor/Editor.stories.d.ts +30 -0
  20. package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -0
  21. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  23. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  24. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  25. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  26. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  27. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/util.d.ts +3 -3
  29. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +1 -1
  31. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  32. package/dist/types/src/components/index.d.ts +0 -1
  33. package/dist/types/src/components/index.d.ts.map +1 -1
  34. package/dist/types/src/defaults.d.ts.map +1 -1
  35. package/dist/types/src/extensions/autocomplete/autocomplete.d.ts +26 -0
  36. package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
  37. package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
  38. package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
  39. package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
  40. package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
  41. package/dist/types/src/extensions/autocomplete/placeholder.d.ts +20 -0
  42. package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
  43. package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
  44. package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
  45. package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
  46. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  47. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +10 -19
  48. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  49. package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
  50. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  51. package/dist/types/src/extensions/automerge/sync.d.ts +2 -2
  52. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  53. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  54. package/dist/types/src/extensions/autoscroll.d.ts +10 -0
  55. package/dist/types/src/extensions/autoscroll.d.ts.map +1 -0
  56. package/dist/types/src/extensions/comments.d.ts +1 -1
  57. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  58. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  59. package/dist/types/src/extensions/factories.d.ts +8 -8
  60. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  61. package/dist/types/src/extensions/focus.d.ts.map +1 -1
  62. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  63. package/dist/types/src/extensions/index.d.ts +4 -1
  64. package/dist/types/src/extensions/index.d.ts.map +1 -1
  65. package/dist/types/src/extensions/json.d.ts +1 -1
  66. package/dist/types/src/extensions/json.d.ts.map +1 -1
  67. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
  68. package/dist/types/src/extensions/markdown/bundle.d.ts +8 -2
  69. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  70. package/dist/types/src/extensions/markdown/changes.d.ts +1 -1
  71. package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
  72. package/dist/types/src/extensions/markdown/decorate.d.ts +9 -1
  73. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  74. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  75. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  76. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
  77. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  78. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  79. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  80. package/dist/types/src/extensions/modes.d.ts +1 -1
  81. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  82. package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
  83. package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
  84. package/dist/types/src/extensions/outliner/outliner.d.ts +1 -1
  85. package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
  86. package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
  87. package/dist/types/src/extensions/outliner/tree.d.ts +2 -2
  88. package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
  89. package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts +36 -0
  90. package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts.map +1 -0
  91. package/dist/types/src/extensions/popover/index.d.ts +8 -0
  92. package/dist/types/src/extensions/popover/index.d.ts.map +1 -0
  93. package/dist/types/src/extensions/popover/menu-presets.d.ts +4 -0
  94. package/dist/types/src/extensions/popover/menu-presets.d.ts.map +1 -0
  95. package/dist/types/src/extensions/popover/menu.d.ts +24 -0
  96. package/dist/types/src/extensions/popover/menu.d.ts.map +1 -0
  97. package/dist/types/src/extensions/popover/modal.d.ts +7 -0
  98. package/dist/types/src/extensions/popover/modal.d.ts.map +1 -0
  99. package/dist/types/src/extensions/popover/popover.d.ts +47 -0
  100. package/dist/types/src/extensions/popover/popover.d.ts.map +1 -0
  101. package/dist/types/src/extensions/popover/usePopoverMenu.d.ts +34 -0
  102. package/dist/types/src/extensions/popover/usePopoverMenu.d.ts.map +1 -0
  103. package/dist/types/src/extensions/popover/util.d.ts +8 -0
  104. package/dist/types/src/extensions/popover/util.d.ts.map +1 -0
  105. package/dist/types/src/extensions/preview/preview.d.ts +2 -6
  106. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  107. package/dist/types/src/extensions/state.d.ts +2 -0
  108. package/dist/types/src/extensions/state.d.ts.map +1 -0
  109. package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
  110. package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
  111. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
  112. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
  113. package/dist/types/src/extensions/tags/index.d.ts +4 -0
  114. package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
  115. package/dist/types/src/extensions/tags/streamer.d.ts +12 -0
  116. package/dist/types/src/extensions/tags/streamer.d.ts.map +1 -0
  117. package/dist/types/src/extensions/tags/xml-tags.d.ts +72 -0
  118. package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
  119. package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
  120. package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
  121. package/dist/types/src/hooks/useTextEditor.d.ts +4 -8
  122. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  123. package/dist/types/src/stories/CommandDialog.stories.d.ts +14 -0
  124. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +1 -0
  125. package/dist/types/src/stories/Comments.stories.d.ts +21 -10
  126. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  127. package/dist/types/src/stories/EditorToolbar.stories.d.ts +39 -3
  128. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  129. package/dist/types/src/stories/Experimental.stories.d.ts +22 -13
  130. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  131. package/dist/types/src/stories/Markdown.stories.d.ts +32 -43
  132. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  133. package/dist/types/src/stories/Outliner.stories.d.ts +15 -21
  134. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  135. package/dist/types/src/stories/Popover.stories.d.ts +20 -0
  136. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -0
  137. package/dist/types/src/stories/Preview.stories.d.ts +21 -7
  138. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  139. package/dist/types/src/stories/Tags.stories.d.ts +16 -0
  140. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -0
  141. package/dist/types/src/stories/TextEditor.stories.d.ts +37 -52
  142. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  143. package/dist/types/src/stories/components/EditorStory.d.ts +6 -9
  144. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  145. package/dist/types/src/styles/theme.d.ts.map +1 -1
  146. package/dist/types/src/testing/PreviewPopover.d.ts +20 -0
  147. package/dist/types/src/testing/PreviewPopover.d.ts.map +1 -0
  148. package/dist/types/src/testing/index.d.ts +1 -0
  149. package/dist/types/src/testing/index.d.ts.map +1 -1
  150. package/dist/types/src/testing/util.d.ts +1 -0
  151. package/dist/types/src/testing/util.d.ts.map +1 -1
  152. package/dist/types/src/translations.d.ts +1 -1
  153. package/dist/types/src/types/types.d.ts +2 -2
  154. package/dist/types/src/types/types.d.ts.map +1 -1
  155. package/dist/types/src/util/cursor.d.ts.map +1 -1
  156. package/dist/types/src/util/debug.d.ts +1 -1
  157. package/dist/types/src/util/debug.d.ts.map +1 -1
  158. package/dist/types/src/util/decorations.d.ts +4 -0
  159. package/dist/types/src/util/decorations.d.ts.map +1 -0
  160. package/dist/types/src/util/dom.d.ts +2 -12
  161. package/dist/types/src/util/dom.d.ts.map +1 -1
  162. package/dist/types/src/util/index.d.ts +1 -0
  163. package/dist/types/src/util/index.d.ts.map +1 -1
  164. package/dist/types/src/util/react.d.ts +1 -1
  165. package/dist/types/src/util/react.d.ts.map +1 -1
  166. package/dist/types/tsconfig.tsbuildinfo +1 -1
  167. package/package.json +69 -61
  168. package/src/components/Editor/Editor.stories.tsx +72 -0
  169. package/src/components/Editor/Editor.tsx +58 -15
  170. package/src/components/EditorToolbar/EditorToolbar.tsx +41 -30
  171. package/src/components/EditorToolbar/blocks.ts +21 -24
  172. package/src/components/EditorToolbar/formatting.ts +22 -25
  173. package/src/components/EditorToolbar/headings.ts +10 -5
  174. package/src/components/EditorToolbar/image.ts +8 -4
  175. package/src/components/EditorToolbar/lists.ts +16 -19
  176. package/src/components/EditorToolbar/search.ts +8 -4
  177. package/src/components/EditorToolbar/util.ts +16 -5
  178. package/src/components/EditorToolbar/view-mode.ts +11 -6
  179. package/src/components/index.ts +0 -1
  180. package/src/defaults.ts +5 -2
  181. package/src/extensions/autocomplete/autocomplete.ts +220 -0
  182. package/src/extensions/autocomplete/index.ts +8 -0
  183. package/src/extensions/autocomplete/match.ts +46 -0
  184. package/src/extensions/{command → autocomplete}/placeholder.ts +22 -18
  185. package/src/extensions/{command → autocomplete}/typeahead.ts +8 -50
  186. package/src/extensions/automerge/automerge.stories.tsx +31 -24
  187. package/src/extensions/automerge/automerge.ts +31 -11
  188. package/src/extensions/automerge/defs.ts +1 -1
  189. package/src/extensions/automerge/sync.ts +8 -4
  190. package/src/extensions/automerge/update-automerge.ts +1 -1
  191. package/src/extensions/autoscroll.ts +157 -0
  192. package/src/extensions/awareness/awareness.ts +2 -2
  193. package/src/extensions/comments.ts +18 -13
  194. package/src/extensions/dnd.ts +1 -1
  195. package/src/extensions/factories.ts +48 -31
  196. package/src/extensions/focus.ts +5 -4
  197. package/src/extensions/folding.tsx +4 -6
  198. package/src/extensions/hashtag.tsx +2 -2
  199. package/src/extensions/index.ts +4 -1
  200. package/src/extensions/json.ts +1 -1
  201. package/src/extensions/markdown/action.ts +2 -1
  202. package/src/extensions/markdown/bundle.ts +29 -5
  203. package/src/extensions/markdown/changes.ts +1 -1
  204. package/src/extensions/markdown/decorate.ts +24 -14
  205. package/src/extensions/markdown/formatting.test.ts +6 -6
  206. package/src/extensions/markdown/formatting.ts +3 -3
  207. package/src/extensions/markdown/highlight.ts +1 -1
  208. package/src/extensions/markdown/image.ts +3 -4
  209. package/src/extensions/markdown/link.ts +3 -0
  210. package/src/extensions/markdown/table.ts +7 -1
  211. package/src/extensions/mention.ts +1 -1
  212. package/src/extensions/modes.ts +2 -2
  213. package/src/extensions/{command/floating-menu.ts → outliner/menu.ts} +16 -21
  214. package/src/extensions/outliner/outliner.test.ts +3 -2
  215. package/src/extensions/outliner/outliner.ts +7 -6
  216. package/src/extensions/outliner/selection.ts +1 -1
  217. package/src/extensions/outliner/tree.test.ts +2 -1
  218. package/src/extensions/outliner/tree.ts +2 -2
  219. package/src/extensions/popover/PopoverMenuProvider.tsx +221 -0
  220. package/src/extensions/popover/index.ts +12 -0
  221. package/src/extensions/popover/menu-presets.ts +124 -0
  222. package/src/extensions/popover/menu.ts +67 -0
  223. package/src/extensions/popover/modal.ts +24 -0
  224. package/src/extensions/popover/popover.ts +293 -0
  225. package/src/extensions/popover/usePopoverMenu.ts +173 -0
  226. package/src/extensions/popover/util.ts +29 -0
  227. package/src/extensions/preview/index.ts +1 -1
  228. package/src/extensions/preview/preview.ts +57 -62
  229. package/src/extensions/selection.ts +2 -2
  230. package/src/extensions/state.ts +7 -0
  231. package/src/extensions/tags/extended-markdown.test.ts +261 -0
  232. package/src/extensions/tags/extended-markdown.ts +78 -0
  233. package/src/extensions/tags/index.ts +7 -0
  234. package/src/extensions/tags/streamer.ts +243 -0
  235. package/src/extensions/tags/xml-tags.ts +393 -0
  236. package/src/extensions/tags/xml-util.ts +94 -0
  237. package/src/hooks/useTextEditor.ts +27 -39
  238. package/src/stories/CommandDialog.stories.tsx +78 -0
  239. package/src/stories/Comments.stories.tsx +14 -10
  240. package/src/stories/EditorToolbar.stories.tsx +13 -12
  241. package/src/stories/Experimental.stories.tsx +17 -13
  242. package/src/stories/Markdown.stories.tsx +25 -21
  243. package/src/stories/Outliner.stories.tsx +54 -35
  244. package/src/stories/Popover.stories.tsx +163 -0
  245. package/src/stories/Preview.stories.tsx +34 -33
  246. package/src/stories/Tags.stories.tsx +81 -0
  247. package/src/stories/TextEditor.stories.tsx +39 -58
  248. package/src/stories/components/EditorStory.tsx +16 -15
  249. package/src/styles/theme.ts +16 -12
  250. package/src/testing/PreviewPopover.tsx +80 -0
  251. package/src/testing/index.ts +1 -0
  252. package/src/testing/util.ts +2 -0
  253. package/src/translations.ts +1 -1
  254. package/src/types/types.ts +1 -1
  255. package/src/util/cursor.ts +2 -1
  256. package/src/util/debug.ts +2 -2
  257. package/src/util/decorations.ts +21 -0
  258. package/src/util/dom.ts +5 -27
  259. package/src/util/index.ts +1 -0
  260. package/src/util/react.tsx +1 -1
  261. package/dist/lib/browser/chunk-22UMM3QJ.mjs.map +0 -7
  262. package/dist/lib/node-esm/chunk-YXYQPV6R.mjs.map +0 -7
  263. package/dist/types/src/components/Popover/CommandMenu.d.ts +0 -34
  264. package/dist/types/src/components/Popover/CommandMenu.d.ts.map +0 -1
  265. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +0 -21
  266. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +0 -1
  267. package/dist/types/src/components/Popover/RefPopover.d.ts +0 -34
  268. package/dist/types/src/components/Popover/RefPopover.d.ts.map +0 -1
  269. package/dist/types/src/components/Popover/index.d.ts +0 -4
  270. package/dist/types/src/components/Popover/index.d.ts.map +0 -1
  271. package/dist/types/src/extensions/autocomplete.d.ts +0 -13
  272. package/dist/types/src/extensions/autocomplete.d.ts.map +0 -1
  273. package/dist/types/src/extensions/command/action.d.ts +0 -17
  274. package/dist/types/src/extensions/command/action.d.ts.map +0 -1
  275. package/dist/types/src/extensions/command/command-menu.d.ts +0 -20
  276. package/dist/types/src/extensions/command/command-menu.d.ts.map +0 -1
  277. package/dist/types/src/extensions/command/command.d.ts +0 -6
  278. package/dist/types/src/extensions/command/command.d.ts.map +0 -1
  279. package/dist/types/src/extensions/command/floating-menu.d.ts +0 -7
  280. package/dist/types/src/extensions/command/floating-menu.d.ts.map +0 -1
  281. package/dist/types/src/extensions/command/hint.d.ts +0 -24
  282. package/dist/types/src/extensions/command/hint.d.ts.map +0 -1
  283. package/dist/types/src/extensions/command/index.d.ts +0 -7
  284. package/dist/types/src/extensions/command/index.d.ts.map +0 -1
  285. package/dist/types/src/extensions/command/placeholder.d.ts +0 -10
  286. package/dist/types/src/extensions/command/placeholder.d.ts.map +0 -1
  287. package/dist/types/src/extensions/command/state.d.ts +0 -16
  288. package/dist/types/src/extensions/command/state.d.ts.map +0 -1
  289. package/dist/types/src/extensions/command/typeahead.d.ts +0 -22
  290. package/dist/types/src/extensions/command/typeahead.d.ts.map +0 -1
  291. package/dist/types/src/extensions/command/useCommandMenu.d.ts +0 -26
  292. package/dist/types/src/extensions/command/useCommandMenu.d.ts.map +0 -1
  293. package/dist/types/src/stories/Command.stories.d.ts +0 -7
  294. package/dist/types/src/stories/Command.stories.d.ts.map +0 -1
  295. package/dist/types/src/stories/CommandMenu.stories.d.ts +0 -13
  296. package/dist/types/src/stories/CommandMenu.stories.d.ts.map +0 -1
  297. package/src/components/Popover/CommandMenu.tsx +0 -279
  298. package/src/components/Popover/RefDropdownMenu.tsx +0 -85
  299. package/src/components/Popover/RefPopover.tsx +0 -99
  300. package/src/components/Popover/index.ts +0 -7
  301. package/src/extensions/autocomplete.ts +0 -69
  302. package/src/extensions/command/action.ts +0 -56
  303. package/src/extensions/command/command-menu.ts +0 -210
  304. package/src/extensions/command/command.ts +0 -34
  305. package/src/extensions/command/hint.ts +0 -102
  306. package/src/extensions/command/index.ts +0 -10
  307. package/src/extensions/command/state.ts +0 -89
  308. package/src/extensions/command/useCommandMenu.ts +0 -118
  309. package/src/stories/Command.stories.tsx +0 -97
  310. package/src/stories/CommandMenu.stories.tsx +0 -159
@@ -2,24 +2,24 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { syntaxTree } from '@codemirror/language';
8
6
  import { type EditorView } from '@codemirror/view';
9
- import React, { useState, useEffect, useMemo, useCallback } from 'react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
10
9
  import { createPortal } from 'react-dom';
11
10
 
12
11
  import { invariant } from '@dxos/invariant';
13
12
  import { faker } from '@dxos/random';
14
13
  import { Popover } from '@dxos/react-ui';
14
+ import { withTheme } from '@dxos/react-ui/testing';
15
15
  import { Card } from '@dxos/react-ui-stack';
16
16
  import { hoverableControlItem, hoverableControlItemTransition, hoverableControls } from '@dxos/react-ui-theme';
17
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
17
+ import { trim } from '@dxos/util';
18
+
19
+ import { type PreviewLinkRef, type PreviewLinkTarget, getLinkRef, image, preview } from '../extensions';
20
+ import { PreviewPopoverProvider, usePreviewPopover } from '../testing';
18
21
 
19
22
  import { EditorStory } from './components';
20
- import { PreviewProvider, useRefPopover } from '../components';
21
- import { preview, image, type PreviewLinkRef, type PreviewLinkTarget, getLinkRef } from '../extensions';
22
- import { str } from '../testing';
23
23
 
24
24
  const handlePreviewLookup = async ({ label, ref }: PreviewLinkRef): Promise<PreviewLinkTarget> => {
25
25
  // Random text.
@@ -43,7 +43,7 @@ const useRefTarget = (link: PreviewLinkRef): PreviewLinkTarget | undefined => {
43
43
  };
44
44
 
45
45
  const PreviewCard = () => {
46
- const { target } = useRefPopover('PreviewCard');
46
+ const { target } = usePreviewPopover('PreviewCard');
47
47
  return (
48
48
  <Popover.Portal>
49
49
  <Popover.Content onOpenAutoFocus={(event) => event.preventDefault()}>
@@ -132,7 +132,7 @@ const PreviewBlock = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElemen
132
132
  <Card.Toolbar classNames='is-min p-[--dx-cardSpacingInline]'>
133
133
  {(link.suggest && (
134
134
  <>
135
- <Card.ToolbarIconButton label='Discard' icon={'ph--x--regular'} onClick={handleDelete} />
135
+ <Card.ToolbarIconButton label='Discard' icon='ph--x--regular' onClick={handleDelete} />
136
136
  {target && (
137
137
  <Card.ToolbarIconButton
138
138
  classNames='bg-successSurface text-successSurfaceText'
@@ -164,20 +164,23 @@ const PreviewBlock = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElemen
164
164
  );
165
165
  };
166
166
 
167
- const meta: Meta<typeof EditorStory> = {
167
+ const meta = {
168
168
  title: 'ui/react-ui-editor/Preview',
169
169
  component: EditorStory,
170
- decorators: [withTheme, withLayout({ fullscreen: true })],
171
- parameters: { layout: 'fullscreen' },
172
- };
170
+ decorators: [withTheme],
171
+ parameters: {
172
+ layout: 'fullscreen',
173
+ },
174
+ } satisfies Meta<typeof EditorStory>;
173
175
 
174
176
  export default meta;
175
177
 
176
- export const Default = {
178
+ type Story = StoryObj<typeof meta>;
179
+
180
+ export const Default: Story = {
177
181
  render: () => {
178
182
  const [view, setView] = useState<EditorView>();
179
183
  const [previewBlocks, setPreviewBlocks] = useState<{ link: PreviewLinkRef; el: HTMLElement }[]>([]);
180
-
181
184
  const extensions = useMemo(() => {
182
185
  return [
183
186
  image(),
@@ -197,32 +200,30 @@ export const Default = {
197
200
  }, []);
198
201
 
199
202
  return (
200
- <PreviewProvider onLookup={handlePreviewLookup}>
203
+ <PreviewPopoverProvider onLookup={handlePreviewLookup}>
201
204
  <EditorStory
202
205
  ref={handleViewRef}
203
- text={str(
204
- '# Preview',
205
- '',
206
- 'This project is part of the [DXOS][dxn:queue:data:123] SDK.',
207
- '',
208
- '![DXOS][?dxn:queue:data:123]',
209
- '',
210
- 'It consists of [ECHO][dxn:queue:data:echo], [HALO][dxn:queue:data:halo], and [MESH][dxn:queue:data:mesh].',
211
- '',
212
- '## Deep dive',
213
- '',
214
- '![ECHO][dxn:queue:data:echo]',
215
- '',
216
- '',
217
- '',
218
- )}
206
+ text={trim`
207
+ # Preview
208
+
209
+ This project is part of the [DXOS](dxn:queue:data:123) SDK.
210
+
211
+ ![DXOS](dxn:queue:data:123)
212
+
213
+ It consists of [ECHO](dxn:queue:data:echo), [HALO](dxn:queue:data:halo), and [MESH](dxn:queue:data:mesh).
214
+
215
+ ## Deep dive
216
+
217
+ ![ECHO](dxn:queue:data:echo)
218
+
219
+ `}
219
220
  extensions={extensions}
220
221
  />
221
222
  <PreviewCard />
222
223
  {previewBlocks.map(({ link, el }) => (
223
224
  <PreviewBlock key={link.ref} link={link} el={el} view={view} />
224
225
  ))}
225
- </PreviewProvider>
226
+ </PreviewPopoverProvider>
226
227
  );
227
228
  },
228
229
  };
@@ -0,0 +1,81 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useState } from 'react';
7
+ import { createPortal } from 'react-dom';
8
+
9
+ import { useThemeContext } from '@dxos/react-ui';
10
+ import { withTheme } from '@dxos/react-ui/testing';
11
+ import { trim } from '@dxos/util';
12
+
13
+ import {
14
+ type XmlWidgetRegistry,
15
+ type XmlWidgetState,
16
+ createBasicExtensions,
17
+ createThemeExtensions,
18
+ decorateMarkdown,
19
+ extendedMarkdown,
20
+ xmlTags,
21
+ } from '../extensions';
22
+ import { useTextEditor } from '../hooks';
23
+
24
+ const registry = {
25
+ // <test/>
26
+ ['test' as const]: {
27
+ block: true,
28
+ Component: () => <div className='p-2 border border-separator rounded'>Test</div>,
29
+ },
30
+ } satisfies XmlWidgetRegistry;
31
+
32
+ const DefaultStory = ({ text }: { text?: string }) => {
33
+ const { themeMode } = useThemeContext();
34
+ const [widgets, setWidgets] = useState<XmlWidgetState[]>([]);
35
+ const { parentRef } = useTextEditor({
36
+ initialValue: text,
37
+ extensions: [
38
+ createThemeExtensions({ themeMode }),
39
+ createBasicExtensions({ lineWrapping: true, readOnly: true }),
40
+ decorateMarkdown(),
41
+ extendedMarkdown({ registry }),
42
+ xmlTags({ registry, setWidgets }),
43
+ ],
44
+ });
45
+
46
+ return (
47
+ <>
48
+ <div ref={parentRef} className='is-full p-4' />
49
+ {widgets.map(({ Component, root, id, ...props }) => (
50
+ <div key={id}>{createPortal(<Component {...props} />, root)}</div>
51
+ ))}
52
+ </>
53
+ );
54
+ };
55
+
56
+ const text = trim`
57
+ # Tags
58
+
59
+ <test id="123" />
60
+
61
+ React widget above.
62
+ `;
63
+
64
+ const meta = {
65
+ title: 'ui/react-ui-editor/Tags',
66
+ render: DefaultStory,
67
+ decorators: [withTheme],
68
+ parameters: {
69
+ layout: 'fullscreen',
70
+ },
71
+ } satisfies Meta<typeof DefaultStory>;
72
+
73
+ export default meta;
74
+
75
+ type Story = StoryObj<typeof meta>;
76
+
77
+ export const Default: Story = {
78
+ args: {
79
+ text,
80
+ },
81
+ };
@@ -2,32 +2,17 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { javascript } from '@codemirror/lang-javascript';
8
6
  import { openSearchPanel } from '@codemirror/search';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
9
8
  import React from 'react';
10
9
 
11
10
  import { log } from '@dxos/log';
12
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
11
+ import { withTheme } from '@dxos/react-ui/testing';
13
12
 
14
- import {
15
- EditorStory,
16
- allExtensions,
17
- content,
18
- defaultExtensions,
19
- global,
20
- largeWithImages,
21
- links,
22
- longText,
23
- names,
24
- renderLinkButton,
25
- text,
26
- } from './components';
27
13
  import { editorMonospace } from '../defaults';
28
14
  import {
29
15
  InputModeExtensions,
30
- autocomplete,
31
16
  decorateMarkdown,
32
17
  folding,
33
18
  image,
@@ -39,12 +24,27 @@ import {
39
24
  } from '../extensions';
40
25
  import { str } from '../testing';
41
26
 
42
- const meta: Meta<typeof EditorStory> = {
27
+ import {
28
+ EditorStory,
29
+ allExtensions,
30
+ content,
31
+ defaultExtensions,
32
+ global,
33
+ largeWithImages,
34
+ longText,
35
+ names,
36
+ text,
37
+ } from './components';
38
+
39
+ const meta = {
43
40
  title: 'ui/react-ui-editor/TextEditor',
44
41
  component: EditorStory,
45
- decorators: [withTheme, withLayout({ fullscreen: true })],
46
- parameters: { layout: 'fullscreen', controls: { disable: true } },
47
- };
42
+ decorators: [withTheme],
43
+ parameters: {
44
+ layout: 'fullscreen',
45
+ controls: { disable: true },
46
+ },
47
+ } satisfies Meta<typeof EditorStory>;
48
48
 
49
49
  export default meta;
50
50
 
@@ -52,7 +52,9 @@ export default meta;
52
52
  // Default
53
53
  //
54
54
 
55
- export const Default = {
55
+ type Story = StoryObj<typeof meta>;
56
+
57
+ export const Default: Story = {
56
58
  render: () => <EditorStory text={text} extensions={defaultExtensions} />,
57
59
  };
58
60
 
@@ -60,7 +62,7 @@ export const Default = {
60
62
  // Everything
61
63
  //
62
64
 
63
- export const Everything = {
65
+ export const Everything: Story = {
64
66
  render: () => <EditorStory text={text} extensions={allExtensions} selection={{ anchor: 99, head: 110 }} />,
65
67
  };
66
68
 
@@ -68,7 +70,7 @@ export const Everything = {
68
70
  // Empty
69
71
  //
70
72
 
71
- export const Empty = {
73
+ export const Empty: Story = {
72
74
  render: () => <EditorStory extensions={defaultExtensions} />,
73
75
  };
74
76
 
@@ -76,7 +78,7 @@ export const Empty = {
76
78
  // Readonly
77
79
  //
78
80
 
79
- export const Readonly = {
81
+ export const Readonly: Story = {
80
82
  render: () => <EditorStory text={text} extensions={defaultExtensions} readOnly />,
81
83
  };
82
84
 
@@ -84,7 +86,7 @@ export const Readonly = {
84
86
  // No Extensions
85
87
  //
86
88
 
87
- export const NoExtensions = {
89
+ export const NoExtensions: Story = {
88
90
  render: () => <EditorStory text={text} />,
89
91
  };
90
92
 
@@ -92,7 +94,7 @@ export const NoExtensions = {
92
94
  // Vim
93
95
  //
94
96
 
95
- export const Vim = {
97
+ export const Vim: Story = {
96
98
  render: () => (
97
99
  <EditorStory
98
100
  text={str('# Vim Mode', '', 'The distant future. The year 2000.', '', content.paragraphs)}
@@ -105,7 +107,7 @@ export const Vim = {
105
107
  // Listener
106
108
  //
107
109
 
108
- export const Listener = {
110
+ export const Listener: Story = {
109
111
  render: () => (
110
112
  <EditorStory
111
113
  text={str('# Listener', '', content.footer)}
@@ -127,7 +129,7 @@ export const Listener = {
127
129
  // Folding
128
130
  //
129
131
 
130
- export const Folding = {
132
+ export const Folding: Story = {
131
133
  render: () => <EditorStory text={text} extensions={[folding()]} />,
132
134
  };
133
135
 
@@ -135,7 +137,7 @@ export const Folding = {
135
137
  // Scrolling
136
138
  //
137
139
 
138
- export const Scrolling = {
140
+ export const Scrolling: Story = {
139
141
  render: () => (
140
142
  <EditorStory
141
143
  text={str('# Large Document', '', longText)}
@@ -147,13 +149,13 @@ export const Scrolling = {
147
149
  ),
148
150
  };
149
151
 
150
- export const ScrollingWithImages = {
152
+ export const ScrollingWithImages: Story = {
151
153
  render: () => (
152
154
  <EditorStory text={str('# Large Document', '', largeWithImages)} extensions={[decorateMarkdown(), image()]} />
153
155
  ),
154
156
  };
155
157
 
156
- export const ScrollTo = {
158
+ export const ScrollTo: Story = {
157
159
  render: () => {
158
160
  // NOTE: Selection won't appear if text is reformatted.
159
161
  const word = 'Scroll to here...';
@@ -174,7 +176,7 @@ export const ScrollTo = {
174
176
  // Typescript
175
177
  //
176
178
 
177
- export const Typescript = {
179
+ export const Typescript: Story = {
178
180
  render: () => (
179
181
  <EditorStory
180
182
  text={content.typescript}
@@ -184,38 +186,17 @@ export const Typescript = {
184
186
  ),
185
187
  };
186
188
 
187
- //
188
- // Autocomplete
189
- //
190
-
191
- export const Autocomplete = {
192
- render: () => (
193
- <EditorStory
194
- text={str('# Autocomplete', '', 'Press Ctrl-Space...', content.footer)}
195
- extensions={[
196
- decorateMarkdown({ renderLinkButton }),
197
- autocomplete({
198
- onSearch: (text) => {
199
- return links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase()));
200
- },
201
- }),
202
- ]}
203
- />
204
- ),
205
- };
206
-
207
189
  //
208
190
  // Typeahead
209
191
  //
210
192
 
211
- const completions = ['type', 'AND', 'OR', 'NOT', 'dxos.org'];
193
+ const completions = ['hello world!', 'dxos.org'];
212
194
 
213
- export const Typeahead = {
195
+ export const Typeahead: Story = {
214
196
  render: () => (
215
197
  <EditorStory
216
198
  text={str('# Typeahead', '')}
217
199
  extensions={[
218
- decorateMarkdown({ renderLinkButton }),
219
200
  typeahead({
220
201
  onComplete: staticCompletion(completions, { minLength: 2 }),
221
202
  }),
@@ -228,7 +209,7 @@ export const Typeahead = {
228
209
  // Mention
229
210
  //
230
211
 
231
- export const Mention = {
212
+ export const Mention: Story = {
232
213
  render: () => (
233
214
  <EditorStory
234
215
  text={str('# Mention', '', 'Type @...', content.footer)}
@@ -245,7 +226,7 @@ export const Mention = {
245
226
  // Search
246
227
  //
247
228
 
248
- export const Search = {
229
+ export const Search: Story = {
249
230
  render: () => (
250
231
  <EditorStory
251
232
  text={str('# Search', text)}
@@ -3,12 +3,12 @@
3
3
  //
4
4
 
5
5
  import { type EditorView } from '@codemirror/view';
6
- import React, { type ReactNode, forwardRef, useEffect, useState, useImperativeHandle, useMemo } from 'react';
6
+ import React, { type ReactNode, forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
7
7
 
8
- import { Expando } from '@dxos/echo-schema';
8
+ import { Expando } from '@dxos/echo/internal';
9
+ import { live } from '@dxos/echo/internal';
9
10
  import { invariant } from '@dxos/invariant';
10
11
  import { PublicKey } from '@dxos/keys';
11
- import { live } from '@dxos/live-object';
12
12
  import { createDocAccessor, createObject } from '@dxos/react-client/echo';
13
13
  import { useForwardedRef, useThemeContext } from '@dxos/react-ui';
14
14
  import { useAttentionAttributes } from '@dxos/react-ui-attention';
@@ -16,26 +16,26 @@ import { JsonFilter } from '@dxos/react-ui-syntax-highlighter';
16
16
  import { mx } from '@dxos/react-ui-theme';
17
17
  import { isNonNullable } from '@dxos/util';
18
18
 
19
- import { editorSlots, editorGutter } from '../../defaults';
19
+ import { editorGutter, editorSlots } from '../../defaults';
20
20
  import {
21
21
  type DebugNode,
22
22
  type ThemeExtensionsOptions,
23
- createDataExtensions,
24
23
  createBasicExtensions,
24
+ createDataExtensions,
25
25
  createMarkdownExtensions,
26
26
  createThemeExtensions,
27
27
  debugTree,
28
+ decorateMarkdown,
28
29
  } from '../../extensions';
29
- import { useTextEditor, type UseTextEditorProps } from '../../hooks';
30
+ import { type UseTextEditorProps, useTextEditor } from '../../hooks';
30
31
 
31
32
  // Type definitions.
32
33
  export type DebugMode = 'raw' | 'tree' | 'raw+tree';
33
34
 
34
35
  const defaultId = 'editor-' + PublicKey.random().toHex().slice(0, 8);
35
36
 
36
- export type StoryProps = Pick<UseTextEditorProps, 'scrollTo' | 'selection' | 'extensions'> &
37
+ export type StoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection' | 'extensions'> &
37
38
  Pick<ThemeExtensionsOptions, 'slots'> & {
38
- id?: string;
39
39
  debug?: DebugMode;
40
40
  debugCustom?: (view: EditorView) => ReactNode;
41
41
  text?: string;
@@ -46,18 +46,18 @@ export type StoryProps = Pick<UseTextEditorProps, 'scrollTo' | 'selection' | 'ex
46
46
  onReady?: (view: EditorView) => void;
47
47
  };
48
48
 
49
- export const EditorStory = forwardRef<EditorView | undefined, StoryProps>(
49
+ export const EditorStory = forwardRef<EditorView | null, StoryProps>(
50
50
  ({ debug, debugCustom, text, extensions: _extensions, ...props }, forwardedRef) => {
51
- const attentionAttrs = useAttentionAttributes('testing');
51
+ const attentionAttrs = useAttentionAttributes('test-panel');
52
52
  const [tree, setTree] = useState<DebugNode>();
53
53
  const [object] = useState(createObject(live(Expando, { content: text ?? '' })));
54
54
  const viewRef = useForwardedRef(forwardedRef);
55
- const view = viewRef.current;
56
55
  const extensions = useMemo(
57
56
  () => (debug ? [_extensions, debugTree(setTree)].filter(isNonNullable) : _extensions),
58
57
  [debug, _extensions],
59
58
  );
60
59
 
60
+ const view = viewRef.current;
61
61
  return (
62
62
  <div className={mx('w-full h-full grid overflow-hidden', debug && 'grid-cols-2 lg:grid-cols-[1fr_600px]')}>
63
63
  <EditorComponent ref={viewRef} object={object} text={text} extensions={extensions} {...props} />
@@ -84,7 +84,7 @@ export const EditorStory = forwardRef<EditorView | undefined, StoryProps>(
84
84
  /**
85
85
  * Default story component.
86
86
  */
87
- export const EditorComponent = forwardRef<EditorView | undefined, StoryProps>(
87
+ export const EditorComponent = forwardRef<EditorView | null, StoryProps>(
88
88
  (
89
89
  {
90
90
  id = defaultId,
@@ -112,9 +112,10 @@ export const EditorComponent = forwardRef<EditorView | undefined, StoryProps>(
112
112
  initialValue: text,
113
113
  extensions: [
114
114
  createDataExtensions({ id, text: createDocAccessor(object, ['content']) }),
115
- createBasicExtensions({ readOnly, placeholder, lineNumbers, scrollPastEnd: true }),
116
- createMarkdownExtensions({ themeMode }),
115
+ createBasicExtensions({ readOnly, placeholder, lineNumbers, scrollPastEnd: true, search: true }),
116
+ createMarkdownExtensions(),
117
117
  createThemeExtensions({ themeMode, syntaxHighlighting: true, slots }),
118
+ decorateMarkdown(),
118
119
  editorGutter,
119
120
  extensions || [],
120
121
  ],
@@ -122,7 +123,7 @@ export const EditorComponent = forwardRef<EditorView | undefined, StoryProps>(
122
123
  [id, object, extensions, themeMode],
123
124
  );
124
125
 
125
- useImperativeHandle(forwardedRef, () => view, [view]);
126
+ useImperativeHandle<EditorView | null, EditorView | null>(forwardedRef, () => view, [view]);
126
127
 
127
128
  useEffect(() => {
128
129
  if (view) {
@@ -64,7 +64,7 @@ export const defaultTheme: ThemeStyles = {
64
64
  fontFamily: fontBody,
65
65
  // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
66
66
  fontSize: '16px',
67
- lineHeight: 1.5,
67
+ lineHeight: '24px',
68
68
  color: 'unset',
69
69
  },
70
70
 
@@ -74,7 +74,7 @@ export const defaultTheme: ThemeStyles = {
74
74
  */
75
75
  '.cm-gutters': {
76
76
  borderRight: 'none',
77
- background: 'transparent',
77
+ // background: 'transparent',
78
78
  },
79
79
  '.cm-gutter': {},
80
80
  '.cm-gutter.cm-lineNumbers': {
@@ -88,14 +88,15 @@ export const defaultTheme: ThemeStyles = {
88
88
  * Height is set to match the corresponding line (which may have wrapped).
89
89
  */
90
90
  '.cm-gutterElement': {
91
- fontSize: '12px',
92
91
  lineHeight: '24px',
92
+ fontSize: '12px',
93
93
  },
94
94
 
95
95
  /**
96
96
  * Line.
97
97
  */
98
98
  '.cm-line': {
99
+ lineHeight: '24px',
99
100
  paddingInline: 0,
100
101
  },
101
102
  '.cm-activeLine': {
@@ -109,6 +110,7 @@ export const defaultTheme: ThemeStyles = {
109
110
  borderLeft: '2px solid var(--dx-cmCursor)',
110
111
  },
111
112
  '.cm-placeholder': {
113
+ fontFamily: fontBody,
112
114
  color: 'var(--dx-placeholder)',
113
115
  },
114
116
 
@@ -164,10 +166,10 @@ export const defaultTheme: ThemeStyles = {
164
166
  * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
165
167
  */
166
168
  '.cm-tooltip.cm-tooltip-autocomplete': {
167
- marginTop: '4px',
168
- marginLeft: '-3px',
169
- borderColor: 'var(--dx-separator)',
170
- borderTop: 'none',
169
+ marginTop: '6px',
170
+ marginLeft: '-10px',
171
+ border: '2px solid var(--dx-separator)',
172
+ borderRadius: '4px',
171
173
  },
172
174
  '.cm-tooltip.cm-tooltip-autocomplete > ul': {
173
175
  maxHeight: '20em',
@@ -176,12 +178,12 @@ export const defaultTheme: ThemeStyles = {
176
178
  padding: '4px',
177
179
  },
178
180
  '.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]': {
179
- background: 'var(--dx-hoverSurface)',
181
+ background: 'var(--dx-activeSurface)',
182
+ color: 'var(--dx-activeSurfaceText)',
180
183
  },
181
184
  '.cm-tooltip.cm-tooltip-autocomplete > ul > completion-section': {
182
185
  paddingLeft: '4px !important',
183
- borderBottom: 'none !important',
184
- color: 'var(--dx-accentText)',
186
+ color: 'var(--dx-hoverSurfaceText)',
185
187
  },
186
188
 
187
189
  '.cm-completionInfo': {
@@ -195,10 +197,12 @@ export const defaultTheme: ThemeStyles = {
195
197
  },
196
198
  '.cm-completionLabel': {
197
199
  fontFamily: fontBody,
200
+ color: 'var(--dx-description)',
201
+ padding: '0 4px',
198
202
  },
199
203
  '.cm-completionMatchedText': {
200
204
  textDecoration: 'none !important',
201
- opacity: 0.5,
205
+ color: 'var(--dx-baseText)',
202
206
  },
203
207
 
204
208
  /**
@@ -232,7 +236,7 @@ export const defaultTheme: ThemeStyles = {
232
236
  outline: '1px solid transparent',
233
237
  },
234
238
  '.cm-panel input, .cm-panel button': {
235
- backgroundColor: 'var(--dx-input)',
239
+ backgroundColor: 'var(--dx-inputSurface)',
236
240
  },
237
241
  '.cm-panel input:focus, .cm-panel button:focus': {
238
242
  outline: '1px solid var(--dx-neutralFocusIndicator)',