@dxos/react-ui-editor 0.8.3-staging.0fa589b → 0.8.4-main.1da679c

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 (269) hide show
  1. package/dist/lib/browser/chunk-22UMM3QJ.mjs +22 -0
  2. package/dist/lib/browser/chunk-22UMM3QJ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +2502 -1384
  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 +72 -2
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/browser/types/index.mjs +13 -0
  9. package/dist/lib/browser/types/index.mjs.map +7 -0
  10. package/dist/lib/node-esm/chunk-YXYQPV6R.mjs +24 -0
  11. package/dist/lib/node-esm/chunk-YXYQPV6R.mjs.map +7 -0
  12. package/dist/lib/node-esm/index.mjs +2504 -1387
  13. package/dist/lib/node-esm/index.mjs.map +4 -4
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/testing/index.mjs +72 -2
  16. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/types/index.mjs +14 -0
  18. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  19. package/dist/types/src/components/{Popover → CommandMenu}/CommandMenu.d.ts +10 -6
  20. package/dist/types/src/components/CommandMenu/CommandMenu.d.ts.map +1 -0
  21. package/dist/types/src/components/CommandMenu/index.d.ts +2 -0
  22. package/dist/types/src/components/CommandMenu/index.d.ts.map +1 -0
  23. package/dist/types/src/components/Editor/Editor.d.ts +19 -0
  24. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -0
  25. package/dist/types/src/components/Editor/index.d.ts +2 -0
  26. package/dist/types/src/components/Editor/index.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  29. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  31. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  32. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  33. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  34. package/dist/types/src/components/EditorToolbar/util.d.ts +6 -5
  35. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  36. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +1 -1
  37. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  38. package/dist/types/src/components/index.d.ts +2 -1
  39. package/dist/types/src/components/index.d.ts.map +1 -1
  40. package/dist/types/src/defaults.d.ts.map +1 -1
  41. package/dist/types/src/extensions/autocomplete.d.ts +20 -7
  42. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  43. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  44. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +36 -45
  45. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  46. package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
  47. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  48. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  49. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  50. package/dist/types/src/extensions/autoscroll.d.ts +10 -0
  51. package/dist/types/src/extensions/autoscroll.d.ts.map +1 -0
  52. package/dist/types/src/extensions/blast.d.ts.map +1 -1
  53. package/dist/types/src/extensions/command/action.d.ts +1 -1
  54. package/dist/types/src/extensions/command/action.d.ts.map +1 -1
  55. package/dist/types/src/extensions/command/command-menu.d.ts +1 -1
  56. package/dist/types/src/extensions/command/command-menu.d.ts.map +1 -1
  57. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  58. package/dist/types/src/extensions/command/floating-menu.d.ts.map +1 -1
  59. package/dist/types/src/extensions/command/hint.d.ts +2 -7
  60. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  61. package/dist/types/src/extensions/command/index.d.ts +1 -1
  62. package/dist/types/src/extensions/command/index.d.ts.map +1 -1
  63. package/dist/types/src/extensions/command/state.d.ts +1 -1
  64. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  65. package/dist/types/src/extensions/command/typeahead.d.ts +7 -2
  66. package/dist/types/src/extensions/command/typeahead.d.ts.map +1 -1
  67. package/dist/types/src/extensions/command/useCommandMenu.d.ts +3 -4
  68. package/dist/types/src/extensions/command/useCommandMenu.d.ts.map +1 -1
  69. package/dist/types/src/extensions/comments.d.ts +1 -1
  70. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  71. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  72. package/dist/types/src/extensions/factories.d.ts +15 -1
  73. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  74. package/dist/types/src/extensions/index.d.ts +2 -0
  75. package/dist/types/src/extensions/index.d.ts.map +1 -1
  76. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
  77. package/dist/types/src/extensions/markdown/bundle.d.ts +8 -2
  78. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  79. package/dist/types/src/extensions/markdown/changes.d.ts +1 -1
  80. package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
  81. package/dist/types/src/extensions/markdown/decorate.d.ts +9 -1
  82. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  83. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  84. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  85. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
  86. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  87. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  88. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  89. package/dist/types/src/extensions/modes.d.ts +0 -7
  90. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  91. package/dist/types/src/extensions/outliner/outliner.d.ts +1 -1
  92. package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
  93. package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
  94. package/dist/types/src/extensions/outliner/tree.d.ts +2 -2
  95. package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
  96. package/dist/types/src/extensions/preview/preview.d.ts +3 -6
  97. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  98. package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
  99. package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
  100. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
  101. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
  102. package/dist/types/src/extensions/tags/index.d.ts +4 -0
  103. package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
  104. package/dist/types/src/extensions/tags/streamer.d.ts +12 -0
  105. package/dist/types/src/extensions/tags/streamer.d.ts.map +1 -0
  106. package/dist/types/src/extensions/tags/xml-tags.d.ts +71 -0
  107. package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
  108. package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
  109. package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
  110. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  111. package/dist/types/src/index.d.ts +1 -1
  112. package/dist/types/src/index.d.ts.map +1 -1
  113. package/dist/types/src/stories/Command.stories.d.ts +12 -4
  114. package/dist/types/src/stories/Command.stories.d.ts.map +1 -1
  115. package/dist/types/src/stories/CommandMenu.stories.d.ts +11 -4
  116. package/dist/types/src/stories/CommandMenu.stories.d.ts.map +1 -1
  117. package/dist/types/src/stories/Comments.stories.d.ts +21 -9
  118. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  119. package/dist/types/src/stories/EditorToolbar.stories.d.ts +40 -3
  120. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  121. package/dist/types/src/stories/Experimental.stories.d.ts +22 -12
  122. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  123. package/dist/types/src/stories/Markdown.stories.d.ts +32 -42
  124. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  125. package/dist/types/src/stories/Outliner.stories.d.ts +15 -20
  126. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  127. package/dist/types/src/stories/Preview.stories.d.ts +21 -6
  128. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  129. package/dist/types/src/stories/Tags.stories.d.ts +17 -0
  130. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -0
  131. package/dist/types/src/stories/TextEditor.stories.d.ts +38 -51
  132. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  133. package/dist/types/src/stories/components/EditorStory.d.ts +3 -6
  134. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  135. package/dist/types/src/styles/theme.d.ts.map +1 -1
  136. package/dist/types/src/testing/PreviewPopover.d.ts +20 -0
  137. package/dist/types/src/testing/PreviewPopover.d.ts.map +1 -0
  138. package/dist/types/src/testing/index.d.ts +1 -0
  139. package/dist/types/src/testing/index.d.ts.map +1 -1
  140. package/dist/types/src/testing/util.d.ts +1 -0
  141. package/dist/types/src/testing/util.d.ts.map +1 -1
  142. package/dist/types/src/translations.d.ts +28 -29
  143. package/dist/types/src/translations.d.ts.map +1 -1
  144. package/dist/types/src/types/index.d.ts +2 -0
  145. package/dist/types/src/types/index.d.ts.map +1 -0
  146. package/dist/types/src/types/types.d.ts +21 -0
  147. package/dist/types/src/types/types.d.ts.map +1 -0
  148. package/dist/types/src/util/cursor.d.ts.map +1 -1
  149. package/dist/types/src/util/debug.d.ts +1 -1
  150. package/dist/types/src/util/debug.d.ts.map +1 -1
  151. package/dist/types/src/util/decorations.d.ts +4 -0
  152. package/dist/types/src/util/decorations.d.ts.map +1 -0
  153. package/dist/types/src/util/dom.d.ts +2 -12
  154. package/dist/types/src/util/dom.d.ts.map +1 -1
  155. package/dist/types/src/util/domino.d.ts +18 -0
  156. package/dist/types/src/util/domino.d.ts.map +1 -0
  157. package/dist/types/src/util/index.d.ts +2 -0
  158. package/dist/types/src/util/index.d.ts.map +1 -1
  159. package/dist/types/src/util/react.d.ts +1 -1
  160. package/dist/types/src/util/react.d.ts.map +1 -1
  161. package/dist/types/tsconfig.tsbuildinfo +1 -1
  162. package/package.json +65 -55
  163. package/src/components/{Popover → CommandMenu}/CommandMenu.tsx +93 -26
  164. package/src/components/{Popover → CommandMenu}/index.ts +0 -2
  165. package/src/components/Editor/Editor.tsx +39 -0
  166. package/src/components/Editor/index.ts +5 -0
  167. package/src/components/EditorToolbar/EditorToolbar.tsx +40 -30
  168. package/src/components/EditorToolbar/blocks.ts +22 -25
  169. package/src/components/EditorToolbar/formatting.ts +22 -25
  170. package/src/components/EditorToolbar/headings.ts +10 -5
  171. package/src/components/EditorToolbar/image.ts +8 -4
  172. package/src/components/EditorToolbar/lists.ts +16 -19
  173. package/src/components/EditorToolbar/search.ts +8 -4
  174. package/src/components/EditorToolbar/util.ts +21 -9
  175. package/src/components/EditorToolbar/view-mode.ts +12 -7
  176. package/src/components/index.ts +2 -1
  177. package/src/defaults.ts +5 -2
  178. package/src/extensions/autocomplete.ts +204 -54
  179. package/src/extensions/automerge/automerge.stories.tsx +26 -17
  180. package/src/extensions/automerge/automerge.ts +4 -3
  181. package/src/extensions/automerge/defs.ts +1 -1
  182. package/src/extensions/automerge/sync.ts +1 -1
  183. package/src/extensions/automerge/update-automerge.ts +1 -1
  184. package/src/extensions/autoscroll.ts +157 -0
  185. package/src/extensions/awareness/awareness.ts +2 -2
  186. package/src/extensions/blast.ts +3 -16
  187. package/src/extensions/command/action.ts +1 -2
  188. package/src/extensions/command/command-menu.ts +7 -6
  189. package/src/extensions/command/command.ts +3 -3
  190. package/src/extensions/command/floating-menu.ts +10 -15
  191. package/src/extensions/command/hint.ts +2 -1
  192. package/src/extensions/command/index.ts +1 -1
  193. package/src/extensions/command/placeholder.ts +1 -1
  194. package/src/extensions/command/state.ts +4 -3
  195. package/src/extensions/command/typeahead.ts +28 -15
  196. package/src/extensions/command/useCommandMenu.ts +6 -9
  197. package/src/extensions/comments.ts +18 -13
  198. package/src/extensions/dnd.ts +1 -1
  199. package/src/extensions/factories.ts +22 -15
  200. package/src/extensions/folding.tsx +2 -2
  201. package/src/extensions/index.ts +2 -0
  202. package/src/extensions/markdown/action.ts +2 -1
  203. package/src/extensions/markdown/bundle.ts +25 -3
  204. package/src/extensions/markdown/changes.ts +1 -1
  205. package/src/extensions/markdown/decorate.ts +23 -14
  206. package/src/extensions/markdown/formatting.test.ts +7 -7
  207. package/src/extensions/markdown/formatting.ts +16 -14
  208. package/src/extensions/markdown/highlight.ts +1 -1
  209. package/src/extensions/markdown/image.ts +3 -4
  210. package/src/extensions/markdown/link.ts +3 -0
  211. package/src/extensions/markdown/table.ts +7 -1
  212. package/src/extensions/mention.ts +1 -1
  213. package/src/extensions/modes.ts +0 -9
  214. package/src/extensions/outliner/outliner.test.ts +3 -2
  215. package/src/extensions/outliner/outliner.ts +6 -5
  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/preview/preview.ts +59 -62
  220. package/src/extensions/tags/extended-markdown.test.ts +261 -0
  221. package/src/extensions/tags/extended-markdown.ts +78 -0
  222. package/src/extensions/tags/index.ts +7 -0
  223. package/src/extensions/tags/streamer.ts +244 -0
  224. package/src/extensions/tags/xml-tags.ts +335 -0
  225. package/src/extensions/tags/xml-util.ts +94 -0
  226. package/src/hooks/useTextEditor.ts +3 -15
  227. package/src/index.ts +1 -1
  228. package/src/stories/Command.stories.tsx +24 -31
  229. package/src/stories/CommandMenu.stories.tsx +29 -30
  230. package/src/stories/Comments.stories.tsx +10 -6
  231. package/src/stories/EditorToolbar.stories.tsx +10 -11
  232. package/src/stories/Experimental.stories.tsx +12 -8
  233. package/src/stories/Markdown.stories.tsx +21 -17
  234. package/src/stories/Outliner.stories.tsx +42 -30
  235. package/src/stories/Preview.stories.tsx +34 -33
  236. package/src/stories/Tags.stories.tsx +81 -0
  237. package/src/stories/TextEditor.stories.tsx +41 -35
  238. package/src/stories/components/EditorStory.tsx +9 -10
  239. package/src/styles/theme.ts +11 -10
  240. package/src/testing/PreviewPopover.tsx +78 -0
  241. package/src/testing/index.ts +1 -0
  242. package/src/testing/util.ts +2 -0
  243. package/src/translations.ts +5 -3
  244. package/src/types/index.ts +5 -0
  245. package/src/types/types.ts +32 -0
  246. package/src/util/cursor.ts +2 -1
  247. package/src/util/debug.ts +2 -2
  248. package/src/util/decorations.ts +21 -0
  249. package/src/util/dom.ts +5 -27
  250. package/src/util/domino.ts +51 -0
  251. package/src/util/index.ts +2 -0
  252. package/src/util/react.tsx +1 -1
  253. package/dist/lib/node/index.cjs +0 -7754
  254. package/dist/lib/node/index.cjs.map +0 -7
  255. package/dist/lib/node/meta.json +0 -1
  256. package/dist/lib/node/testing/index.cjs +0 -29
  257. package/dist/lib/node/testing/index.cjs.map +0 -7
  258. package/dist/types/src/components/Popover/CommandMenu.d.ts.map +0 -1
  259. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +0 -21
  260. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +0 -1
  261. package/dist/types/src/components/Popover/RefPopover.d.ts +0 -34
  262. package/dist/types/src/components/Popover/RefPopover.d.ts.map +0 -1
  263. package/dist/types/src/components/Popover/index.d.ts +0 -4
  264. package/dist/types/src/components/Popover/index.d.ts.map +0 -1
  265. package/dist/types/src/types.d.ts +0 -14
  266. package/dist/types/src/types.d.ts.map +0 -1
  267. package/src/components/Popover/RefDropdownMenu.tsx +0 -79
  268. package/src/components/Popover/RefPopover.tsx +0 -99
  269. package/src/types.ts +0 -23
@@ -2,9 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { type Resource } from '@dxos/react-ui';
6
+
5
7
  export const translationKey = 'react-ui-editor';
6
8
 
7
- export default [
9
+ export const translations = [
8
10
  {
9
11
  'en-US': {
10
12
  [translationKey]: {
@@ -22,8 +24,8 @@ export default [
22
24
  'selection overlaps existing comment label': 'Selection overlaps existing comment',
23
25
  'select text to comment label': 'Select text to comment',
24
26
  'image label': 'Insert image',
25
- 'heading label': 'Heading level',
26
27
  'table label': 'Create table',
28
+ 'heading label': 'Heading level',
27
29
  'heading level label_zero': 'Paragraph',
28
30
  'heading level label_one': 'Heading level {{count}}',
29
31
  'heading level label_other': 'Heading level {{count}}',
@@ -35,4 +37,4 @@ export default [
35
37
  },
36
38
  },
37
39
  },
38
- ];
40
+ ] as const satisfies Resource[];
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './types';
@@ -0,0 +1,32 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type EditorView } from '@codemirror/view';
6
+ import { Schema } from 'effect';
7
+
8
+ // Runtime data structure.
9
+ export type Range = {
10
+ from: number;
11
+ to: number;
12
+ };
13
+
14
+ // Persistent data structure.
15
+ // TODO(burdon): Rename annotation?
16
+ export type Comment = {
17
+ id: string;
18
+ cursor?: string;
19
+ };
20
+
21
+ /**
22
+ * Callback that renders into a DOM element within the editor.
23
+ */
24
+ export type RenderCallback<Props extends object> = (el: HTMLElement, props: Props, view: EditorView) => void;
25
+
26
+ export const EditorViewModes = ['preview', 'readonly', 'source'] as const;
27
+ export const EditorViewMode = Schema.Union(...EditorViewModes.map((mode) => Schema.Literal(mode)));
28
+ export type EditorViewMode = Schema.Schema.Type<typeof EditorViewMode>;
29
+
30
+ export const EditorInputModes = ['default', 'vim', 'vscode'] as const;
31
+ export const EditorInputMode = Schema.Union(...EditorInputModes.map((mode) => Schema.Literal(mode)));
32
+ export type EditorInputMode = Schema.Schema.Type<typeof EditorInputMode>;
@@ -4,9 +4,10 @@
4
4
 
5
5
  import { type EditorState } from '@codemirror/state';
6
6
 
7
- import { singleValueFacet } from './facet';
8
7
  import { type Range } from '../types';
9
8
 
9
+ import { singleValueFacet } from './facet';
10
+
10
11
  /**
11
12
  * Determines if two ranges overlap.
12
13
  * A range is considered to overlap if there is any intersection
package/src/util/debug.ts CHANGED
@@ -7,12 +7,12 @@ import { type EditorView } from '@codemirror/view';
7
7
 
8
8
  import { log } from '@dxos/log';
9
9
 
10
- export const wrapWithCatch = (fn: (...args: any[]) => any) => {
10
+ export const wrapWithCatch = (fn: (...args: any[]) => any, label?: string) => {
11
11
  return (...args: any[]) => {
12
12
  try {
13
13
  return fn(...args);
14
14
  } catch (err) {
15
- log.catch(err);
15
+ log.catch(err, { label });
16
16
  }
17
17
  };
18
18
  };
@@ -0,0 +1,21 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Range } from '@codemirror/state';
6
+ import { type Decoration, type DecorationSet } from '@codemirror/view';
7
+
8
+ export const decorationSetToArray = (deco: DecorationSet): readonly Range<Decoration>[] => {
9
+ const ranges: Range<Decoration>[] = [];
10
+ const iter = deco.iter();
11
+ while (iter.value) {
12
+ ranges.push({
13
+ from: iter.from,
14
+ to: iter.to,
15
+ value: iter.value,
16
+ });
17
+ iter.next();
18
+ }
19
+
20
+ return ranges;
21
+ };
package/src/util/dom.ts CHANGED
@@ -2,30 +2,28 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- // Copied from @codemirror/view
6
-
7
- export interface Rect {
5
+ export type Rect = {
8
6
  readonly left: number;
9
7
  readonly right: number;
10
8
  readonly top: number;
11
9
  readonly bottom: number;
12
- }
10
+ };
13
11
 
14
- export const flattenRect = (rect: Rect, left: boolean) => {
12
+ export const flattenRect = (rect: Rect, left: boolean): Rect => {
15
13
  const x = left ? rect.left : rect.right;
16
14
  return { left: x, right: x, top: rect.top, bottom: rect.bottom };
17
15
  };
18
16
 
19
17
  let scratchRange: Range | null;
20
18
 
21
- export const textRange = (node: Text, from: number, to = from) => {
19
+ export const textRange = (node: Text, from: number, to = from): Range => {
22
20
  const range = scratchRange || (scratchRange = document.createRange());
23
21
  range.setEnd(node, to);
24
22
  range.setStart(node, from);
25
23
  return range;
26
24
  };
27
25
 
28
- export const clientRectsFor = (dom: Node) => {
26
+ export const clientRectsFor = (dom: Node): DOMRectList => {
29
27
  if (dom.nodeType === 3) {
30
28
  return textRange(dom as Text, 0, dom.nodeValue!.length).getClientRects();
31
29
  } else if (dom.nodeType === 1) {
@@ -34,23 +32,3 @@ export const clientRectsFor = (dom: Node) => {
34
32
  return [] as any as DOMRectList;
35
33
  }
36
34
  };
37
-
38
- export type ElementOptions = {
39
- className?: string;
40
- text?: string;
41
- };
42
-
43
- export const createElement = (tag: string, options?: ElementOptions, children?: HTMLElement[]): HTMLElement => {
44
- const el = document.createElement(tag);
45
- if (options?.className) {
46
- el.className = options.className;
47
- }
48
- if (options?.text) {
49
- el.textContent = options.text;
50
- }
51
- if (children) {
52
- el.append(...(Array.isArray(children) ? children : [children]));
53
- }
54
-
55
- return el;
56
- };
@@ -0,0 +1,51 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { mx } from '@dxos/react-ui-theme';
6
+ import { type ClassNameValue } from '@dxos/react-ui-types';
7
+
8
+ /**
9
+ * Super lightweight chainable DOM builder.
10
+ */
11
+ export class Domino<T extends HTMLElement> {
12
+ static of<K extends keyof HTMLElementTagNameMap>(tag: K): Domino<HTMLElementTagNameMap[K]> {
13
+ return new Domino<HTMLElementTagNameMap[K]>(tag);
14
+ }
15
+
16
+ private readonly _el: T;
17
+ constructor(tag: keyof HTMLElementTagNameMap) {
18
+ this._el = document.createElement(tag) as T;
19
+ }
20
+ classNames(...classNames: ClassNameValue[]): this {
21
+ this._el.className = mx(classNames);
22
+ return this;
23
+ }
24
+ text(value: string): this {
25
+ this._el.textContent = value;
26
+ return this;
27
+ }
28
+ data(key: string, value: string): this {
29
+ this._el.dataset[key] = value;
30
+ return this;
31
+ }
32
+ style(styles: Partial<CSSStyleDeclaration>): this {
33
+ Object.assign(this._el.style, styles);
34
+ return this;
35
+ }
36
+ attr<K extends keyof T>(key: K, value: T[K]): this {
37
+ (this._el as any)[key] = value;
38
+ return this;
39
+ }
40
+ child<C extends HTMLElement>(...children: Domino<C>[]): this {
41
+ children.forEach((child) => this._el.appendChild(child.build()));
42
+ return this;
43
+ }
44
+ on(event: string, handler: (e: Event) => void): this {
45
+ this._el.addEventListener(event, handler);
46
+ return this;
47
+ }
48
+ build(): T {
49
+ return this._el;
50
+ }
51
+ }
package/src/util/index.ts CHANGED
@@ -3,7 +3,9 @@
3
3
  //
4
4
 
5
5
  export * from './cursor';
6
+ export * from './decorations';
6
7
  export * from './debug';
7
8
  export * from './dom';
9
+ export * from './domino';
8
10
  export * from './facet';
9
11
  export * from './react';
@@ -22,7 +22,7 @@ export const renderRoot = <T extends Element>(root: T, node: ReactNode): T => {
22
22
  * @deprecated
23
23
  */
24
24
  export const createRenderer =
25
- <Props extends object>(Component: FC<Props>): RenderCallback<Props> =>
25
+ <TProps extends object>(Component: FC<TProps>): RenderCallback<TProps> =>
26
26
  (el, props) => {
27
27
  renderRoot(
28
28
  el,