@dxos/react-ui-editor 0.8.4-main.422d1c7879 → 0.8.4-main.4f23b4e393

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 (90) hide show
  1. package/dist/lib/browser/index.mjs +61 -139
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/translations.mjs +39 -0
  5. package/dist/lib/browser/translations.mjs.map +7 -0
  6. package/dist/lib/node-esm/index.mjs +61 -139
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/translations.mjs +41 -0
  10. package/dist/lib/node-esm/translations.mjs.map +7 -0
  11. package/dist/types/src/components/Editor/Editor.d.ts +17 -5
  12. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  13. package/dist/types/src/components/Editor/Editor.stories.d.ts +1 -1
  14. package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Editor/EditorView.d.ts.map +1 -1
  16. package/dist/types/src/components/Editor/controller.d.ts.map +1 -1
  17. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
  18. package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -1
  19. package/dist/types/src/components/EditorMenuProvider/popover.d.ts +2 -1
  20. package/dist/types/src/components/EditorMenuProvider/popover.d.ts.map +1 -1
  21. package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
  23. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
  24. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  25. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  26. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  27. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  29. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  31. package/dist/types/src/components/EditorToolbar/types.d.ts +2 -1
  32. package/dist/types/src/components/EditorToolbar/types.d.ts.map +1 -1
  33. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +1 -1
  34. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  35. package/dist/types/src/extensions/Assistant.stories.d.ts.map +1 -1
  36. package/dist/types/src/extensions/assistant-extension.d.ts.map +1 -1
  37. package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts.map +1 -1
  38. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  39. package/dist/types/src/index.d.ts +0 -2
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/stories/Automerge.stories.d.ts +24 -24
  42. package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
  43. package/dist/types/src/stories/Comments.stories.d.ts +1 -1
  44. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  45. package/dist/types/src/stories/EditorToolbar.stories.d.ts +25 -25
  46. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  47. package/dist/types/src/stories/Experimental.stories.d.ts +2 -2
  48. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  49. package/dist/types/src/stories/Markdown.stories.d.ts +1 -1
  50. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  51. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  52. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
  53. package/dist/types/src/stories/Preview.stories.d.ts +1 -1
  54. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  55. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
  56. package/dist/types/src/stories/TextEditor.stories.d.ts +1 -1
  57. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  58. package/dist/types/src/stories/Theme.stories.d.ts.map +1 -1
  59. package/dist/types/src/stories/components/EditorStory.d.ts +1 -1
  60. package/dist/types/src/stories/components/util.d.ts +2 -1
  61. package/dist/types/src/stories/components/util.d.ts.map +1 -1
  62. package/dist/types/src/translations.d.ts +24 -24
  63. package/dist/types/src/translations.d.ts.map +1 -1
  64. package/dist/types/src/util/react.d.ts +1 -1
  65. package/dist/types/src/util/react.d.ts.map +1 -1
  66. package/dist/types/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +54 -45
  68. package/src/components/Editor/Editor.tsx +2 -8
  69. package/src/components/Editor/EditorView.tsx +29 -10
  70. package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +1 -1
  71. package/src/components/EditorMenuProvider/popover.ts +3 -1
  72. package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +1 -1
  73. package/src/components/EditorToolbar/EditorToolbar.tsx +8 -6
  74. package/src/components/EditorToolbar/blocks.ts +2 -1
  75. package/src/components/EditorToolbar/formatting.ts +2 -1
  76. package/src/components/EditorToolbar/headings.ts +2 -1
  77. package/src/components/EditorToolbar/image.ts +1 -1
  78. package/src/components/EditorToolbar/lists.ts +2 -1
  79. package/src/components/EditorToolbar/search.ts +1 -1
  80. package/src/components/EditorToolbar/types.ts +2 -1
  81. package/src/components/EditorToolbar/view-mode.ts +3 -2
  82. package/src/extensions/Assistant.stories.tsx +2 -1
  83. package/src/extensions/assistant-extension.tsx +3 -3
  84. package/src/index.ts +0 -4
  85. package/src/stories/Automerge.stories.tsx +4 -3
  86. package/src/stories/Comments.stories.tsx +2 -1
  87. package/src/stories/EditorToolbar.stories.tsx +4 -3
  88. package/src/stories/Experimental.stories.tsx +7 -7
  89. package/src/stories/components/util.tsx +2 -2
  90. package/src/util/react.tsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-editor",
3
- "version": "0.8.4-main.422d1c7879",
3
+ "version": "0.8.4-main.4f23b4e393",
4
4
  "description": "Text editor components.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -12,12 +12,21 @@
12
12
  "author": "DXOS.org",
13
13
  "sideEffects": false,
14
14
  "type": "module",
15
+ "imports": {
16
+ "#translations": "./src/translations.ts"
17
+ },
15
18
  "exports": {
16
19
  ".": {
17
20
  "source": "./src/index.ts",
18
21
  "types": "./dist/types/src/index.d.ts",
19
22
  "browser": "./dist/lib/browser/index.mjs",
20
23
  "node": "./dist/lib/node-esm/index.mjs"
24
+ },
25
+ "./translations": {
26
+ "source": "./src/translations.ts",
27
+ "types": "./dist/types/src/translations.d.ts",
28
+ "browser": "./dist/lib/browser/translations.mjs",
29
+ "node": "./dist/lib/node-esm/translations.mjs"
21
30
  }
22
31
  },
23
32
  "types": "dist/types/src/index.d.ts",
@@ -26,7 +35,7 @@
26
35
  "src"
27
36
  ],
28
37
  "dependencies": {
29
- "@automerge/automerge": "3.2.3",
38
+ "@automerge/automerge": "3.2.6",
30
39
  "@codemirror/autocomplete": "^6.19.0",
31
40
  "@codemirror/commands": "^6.8.1",
32
41
  "@codemirror/lang-html": "^6.4.11",
@@ -41,7 +50,7 @@
41
50
  "@codemirror/search": "^6.5.11",
42
51
  "@codemirror/state": "^6.5.2",
43
52
  "@codemirror/theme-one-dark": "^6.1.3",
44
- "@codemirror/view": "^6.38.4",
53
+ "@codemirror/view": "^6.38.5",
45
54
  "@fluentui/react-tabster": "9.26.11",
46
55
  "@lezer/common": "^1.2.2",
47
56
  "@lezer/generator": "^1.7.1",
@@ -60,31 +69,31 @@
60
69
  "lodash.merge": "^4.6.2",
61
70
  "lodash.sortby": "^4.7.0",
62
71
  "style-mod": "^4.1.0",
63
- "@dxos/async": "0.8.4-main.422d1c7879",
64
- "@dxos/app-graph": "0.8.4-main.422d1c7879",
65
- "@dxos/debug": "0.8.4-main.422d1c7879",
66
- "@dxos/client": "0.8.4-main.422d1c7879",
67
- "@dxos/display-name": "0.8.4-main.422d1c7879",
68
- "@dxos/echo": "0.8.4-main.422d1c7879",
69
- "@dxos/context": "0.8.4-main.422d1c7879",
70
- "@dxos/effect": "0.8.4-main.422d1c7879",
71
- "@dxos/invariant": "0.8.4-main.422d1c7879",
72
- "@dxos/echo-db": "0.8.4-main.422d1c7879",
73
- "@dxos/lit-ui": "0.8.4-main.422d1c7879",
74
- "@dxos/log": "0.8.4-main.422d1c7879",
75
- "@dxos/protocols": "0.8.4-main.422d1c7879",
76
- "@dxos/react-ui-menu": "0.8.4-main.422d1c7879",
77
- "@dxos/react-hooks": "0.8.4-main.422d1c7879",
78
- "@dxos/react-ui-mosaic": "0.8.4-main.422d1c7879",
79
- "@dxos/ui-editor": "0.8.4-main.422d1c7879",
80
- "@dxos/ui-theme": "0.8.4-main.422d1c7879",
81
- "@dxos/util": "0.8.4-main.422d1c7879",
82
- "@dxos/ui": "0.8.4-main.422d1c7879"
72
+ "@dxos/async": "0.8.4-main.4f23b4e393",
73
+ "@dxos/app-graph": "0.8.4-main.4f23b4e393",
74
+ "@dxos/client": "0.8.4-main.4f23b4e393",
75
+ "@dxos/debug": "0.8.4-main.4f23b4e393",
76
+ "@dxos/context": "0.8.4-main.4f23b4e393",
77
+ "@dxos/display-name": "0.8.4-main.4f23b4e393",
78
+ "@dxos/echo": "0.8.4-main.4f23b4e393",
79
+ "@dxos/echo-db": "0.8.4-main.4f23b4e393",
80
+ "@dxos/effect": "0.8.4-main.4f23b4e393",
81
+ "@dxos/lit-ui": "0.8.4-main.4f23b4e393",
82
+ "@dxos/log": "0.8.4-main.4f23b4e393",
83
+ "@dxos/protocols": "0.8.4-main.4f23b4e393",
84
+ "@dxos/invariant": "0.8.4-main.4f23b4e393",
85
+ "@dxos/react-hooks": "0.8.4-main.4f23b4e393",
86
+ "@dxos/ui": "0.8.4-main.4f23b4e393",
87
+ "@dxos/ui-editor": "0.8.4-main.4f23b4e393",
88
+ "@dxos/ui-theme": "0.8.4-main.4f23b4e393",
89
+ "@dxos/util": "0.8.4-main.4f23b4e393",
90
+ "@dxos/react-ui-mosaic": "0.8.4-main.4f23b4e393",
91
+ "@dxos/react-ui-menu": "0.8.4-main.4f23b4e393"
83
92
  },
84
93
  "devDependencies": {
85
- "@automerge/automerge": "3.2.3",
86
- "@automerge/automerge-repo": "2.5.1",
87
- "@automerge/automerge-repo-network-broadcastchannel": "2.5.1",
94
+ "@automerge/automerge": "3.2.6",
95
+ "@automerge/automerge-repo": "2.6.0-subduction.17",
96
+ "@automerge/automerge-repo-network-broadcastchannel": "2.6.0-subduction.17",
88
97
  "@effect-atom/atom-react": "^0.5.0",
89
98
  "@effect/ai": "0.33.2",
90
99
  "@effect/platform": "0.94.4",
@@ -105,23 +114,23 @@
105
114
  "react": "~19.2.3",
106
115
  "react-dom": "~19.2.3",
107
116
  "react-test-renderer": "~19.2.0",
108
- "vite": "^7.1.11",
117
+ "vite": "^8.0.10",
109
118
  "vite-plugin-top-level-await": "^1.6.0",
110
- "vite-plugin-wasm": "^3.5.0",
111
- "@dxos/config": "0.8.4-main.422d1c7879",
112
- "@dxos/ai": "0.8.4-main.422d1c7879",
113
- "@dxos/echo-atom": "0.8.4-main.422d1c7879",
114
- "@dxos/echo": "0.8.4-main.422d1c7879",
115
- "@dxos/random": "0.8.4-main.422d1c7879",
116
- "@dxos/keyboard": "0.8.4-main.422d1c7879",
117
- "@dxos/react-client": "0.8.4-main.422d1c7879",
118
- "@dxos/react-ui-attention": "0.8.4-main.422d1c7879",
119
- "@dxos/schema": "0.8.4-main.422d1c7879",
120
- "@dxos/react-ui": "0.8.4-main.422d1c7879",
121
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.422d1c7879",
122
- "@dxos/storybook-utils": "0.8.4-main.422d1c7879",
123
- "@dxos/ui-types": "0.8.4-main.422d1c7879",
124
- "@dxos/ui-theme": "0.8.4-main.422d1c7879"
119
+ "vite-plugin-wasm": "^3.6.0",
120
+ "@dxos/ai": "0.8.4-main.4f23b4e393",
121
+ "@dxos/config": "0.8.4-main.4f23b4e393",
122
+ "@dxos/echo": "0.8.4-main.4f23b4e393",
123
+ "@dxos/echo-atom": "0.8.4-main.4f23b4e393",
124
+ "@dxos/keyboard": "0.8.4-main.4f23b4e393",
125
+ "@dxos/random": "0.8.4-main.4f23b4e393",
126
+ "@dxos/react-ui": "0.8.4-main.4f23b4e393",
127
+ "@dxos/react-ui-attention": "0.8.4-main.4f23b4e393",
128
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.4f23b4e393",
129
+ "@dxos/schema": "0.8.4-main.4f23b4e393",
130
+ "@dxos/storybook-utils": "0.8.4-main.4f23b4e393",
131
+ "@dxos/ui-theme": "0.8.4-main.4f23b4e393",
132
+ "@dxos/ui-types": "0.8.4-main.4f23b4e393",
133
+ "@dxos/react-client": "0.8.4-main.4f23b4e393"
125
134
  },
126
135
  "peerDependencies": {
127
136
  "@effect-atom/atom-react": "^0.5.0",
@@ -129,9 +138,9 @@
129
138
  "effect": "3.20.0",
130
139
  "react": "~19.2.3",
131
140
  "react-dom": "~19.2.3",
132
- "@dxos/react-client": "0.8.4-main.422d1c7879",
133
- "@dxos/react-ui": "0.8.4-main.422d1c7879",
134
- "@dxos/ui-theme": "0.8.4-main.422d1c7879"
141
+ "@dxos/react-client": "0.8.4-main.4f23b4e393",
142
+ "@dxos/react-ui": "0.8.4-main.4f23b4e393",
143
+ "@dxos/ui-theme": "0.8.4-main.4f23b4e393"
135
144
  },
136
145
  "publishConfig": {
137
146
  "access": "public"
@@ -110,11 +110,7 @@ type EditorContentProps = ThemedClassName<PropsWithChildren<{}>>;
110
110
  * Content component that wraps the toolbar and editor view area.
111
111
  */
112
112
  const EditorContent = ({ classNames, children }: EditorContentProps) => {
113
- return (
114
- <div role='none' className={mx('grid grid-rows-[min-content_1fr] h-full overflow-hidden', classNames)}>
115
- {children}
116
- </div>
117
- );
113
+ return <div className={mx('grid grid-rows-[min-content_1fr] h-full overflow-hidden', classNames)}>{children}</div>;
118
114
  };
119
115
 
120
116
  EditorContent.displayName = EDITOR_CONTENT_NAME;
@@ -157,8 +153,6 @@ type EditorToolbarProps = Omit<NaturalEditorToolbarProps, 'getView' | 'state'>;
157
153
  */
158
154
  const EditorToolbar = (props: EditorToolbarProps) => {
159
155
  const { controller, state } = useEditorContext(EDITOR_TOOLBAR_NAME);
160
-
161
- // TODO(burdon): Fix invariant.
162
156
  const getView = useCallback(() => {
163
157
  invariant(controller?.view);
164
158
  return controller?.view;
@@ -175,9 +169,9 @@ EditorToolbar.displayName = EDITOR_TOOLBAR_NAME;
175
169
 
176
170
  export const Editor = {
177
171
  Root: EditorRoot,
172
+ Toolbar: EditorToolbar,
178
173
  Content: EditorContent,
179
174
  View: EditorView,
180
- Toolbar: EditorToolbar,
181
175
  };
182
176
 
183
177
  export type {
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { Transaction } from '@codemirror/state';
6
6
  import { EditorView as NaturalEditorView } from '@codemirror/view';
7
- import React, { forwardRef, useEffect, useImperativeHandle } from 'react';
7
+ import React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
8
8
 
9
9
  import { type ThemedClassName } from '@dxos/react-ui';
10
10
  import { initialSync } from '@dxos/ui-editor';
@@ -25,8 +25,15 @@ export type EditorViewProps = ThemedClassName<
25
25
  * Minimal text editor.
26
26
  * NOTE: This shouold not be used with the automerge extension.
27
27
  */
28
+ // TODO(burdon): Move controller to Root component, then make composable.
28
29
  export const EditorView = forwardRef<EditorController, EditorViewProps>(
29
30
  ({ classNames, id, extensions, selectionEnd, focusable = true, value, onChange, ...props }, forwardedRef) => {
31
+ // Hold the latest onChange in a ref so callers may pass an inline callback
32
+ // without forcing the underlying editor to be destroyed and recreated on
33
+ // every render — which would blur the focused input on each keystroke.
34
+ const onChangeRef = useRef(onChange);
35
+ onChangeRef.current = onChange;
36
+
30
37
  const { parentRef, focusAttributes, view } = useTextEditor(
31
38
  () => ({
32
39
  id,
@@ -37,13 +44,13 @@ export const EditorView = forwardRef<EditorController, EditorViewProps>(
37
44
  NaturalEditorView.updateListener.of(({ view, docChanged, transactions }) => {
38
45
  const isInitialSync = transactions.some((tr) => tr.annotation(Transaction.userEvent) === initialSync.value);
39
46
  if (!isInitialSync && docChanged) {
40
- onChange?.(view.state.doc.toString());
47
+ onChangeRef.current?.(view.state.doc.toString());
41
48
  }
42
49
  }),
43
50
  ],
44
51
  ...props,
45
52
  }),
46
- [id, extensions, selectionEnd, onChange],
53
+ [id, extensions, selectionEnd],
47
54
  );
48
55
 
49
56
  // External controller.
@@ -51,26 +58,38 @@ export const EditorView = forwardRef<EditorController, EditorViewProps>(
51
58
  return createEditorController(view);
52
59
  }, [id, view]);
53
60
 
54
- // Set initial value and cursor position.
61
+ // Sync the editor doc to the controlled `value` prop, but only when they
62
+ // disagree. After internal typing the prop will already match the editor's
63
+ // doc, and dispatching anyway would race fast keystrokes — a stale rAF
64
+ // closure can replace doc content with an older value, dropping characters.
55
65
  useEffect(() => {
66
+ if (!view) {
67
+ return;
68
+ }
69
+ const next = value ?? '';
70
+ if (view.state.doc.toString() === next) {
71
+ return;
72
+ }
56
73
  requestAnimationFrame(() => {
57
- view?.dispatch({
74
+ if (view.state.doc.toString() === next) {
75
+ return;
76
+ }
77
+ view.dispatch({
58
78
  annotations: initialSync,
59
- changes: value ? [{ from: 0, to: view?.state.doc.length ?? 0, insert: value ?? '' }] : [],
60
- selection: selectionEnd ? { anchor: view?.state.doc.length ?? 0 } : undefined,
79
+ changes: [{ from: 0, to: view.state.doc.length, insert: next }],
80
+ selection: selectionEnd ? { anchor: next.length } : undefined,
61
81
  });
62
82
 
63
83
  if (selectionEnd) {
64
- view?.focus();
84
+ view.focus();
65
85
  }
66
86
  });
67
87
  }, [view, value, selectionEnd]);
68
88
 
69
89
  return (
70
90
  <div
71
- role='none'
72
91
  className={mx(
73
- 'w-full outline-hidden focus:border-accent-surface focus-within:border-neutral-focus-indicator',
92
+ 'w-full outline-hidden focus:border-accent-surface focus-within:border-focus-ring-subtle',
74
93
  classNames,
75
94
  )}
76
95
  {...(focusable ? focusAttributes : {})}
@@ -137,7 +137,7 @@ export const EditorMenuProvider = ({
137
137
  </Popover.Portal>
138
138
 
139
139
  {/* Content */}
140
- <div role='none' className='contents' ref={setRoot}>
140
+ <div className='contents' ref={setRoot}>
141
141
  {children}
142
142
  </div>
143
143
  </Popover.Root>
@@ -13,7 +13,8 @@ import {
13
13
  keymap,
14
14
  } from '@codemirror/view';
15
15
 
16
- import { type PlaceholderOptions, type Range, modalStateField, placeholder } from '@dxos/ui-editor';
16
+ import { type PlaceholderOptions, modalStateField, placeholder } from '@dxos/ui-editor';
17
+ import { type Range } from '@dxos/ui-editor/types';
17
18
  import { isNonNullable, isTruthy } from '@dxos/util';
18
19
 
19
20
  const DELIMITERS = [' ', ':'];
@@ -52,6 +53,7 @@ export const popover = (options: PopoverOptions = {}): Extension => {
52
53
  placeholder({
53
54
  // TODO(burdon): Translations.
54
55
  content: `Press '${Array.isArray(options.trigger) ? options.trigger[0] : options.trigger}' for commands`,
56
+ focusOnly: true,
55
57
  ...options.placeholder,
56
58
  }),
57
59
  ].filter(isTruthy);
@@ -68,7 +68,7 @@ export const EditorPreviewProvider = ({ children, onLookup }: EditorPreviewProvi
68
68
  <EditorPreviewContextProvider pending={value.pending} link={value.link} target={value.target}>
69
69
  <Popover.Root open={open} onOpenChange={setOpen}>
70
70
  <Popover.VirtualTrigger virtualRef={triggerRef as unknown as RefObject<HTMLButtonElement>} />
71
- <div role='none' className='contents' ref={setRoot}>
71
+ <div className='contents' ref={setRoot}>
72
72
  {children}
73
73
  </div>
74
74
  </Popover.Root>
@@ -9,7 +9,7 @@ import React, { memo, useMemo } from 'react';
9
9
  import { type Node } from '@dxos/app-graph';
10
10
  import { ElevationProvider, type ThemedClassName } from '@dxos/react-ui';
11
11
  import { type ActionGraphProps, Menu, type MenuAction, MenuBuilder, useMenuActions } from '@dxos/react-ui-menu';
12
- import { type EditorViewMode } from '@dxos/ui-editor';
12
+ import { type EditorViewMode } from '@dxos/ui-editor/types';
13
13
 
14
14
  import { addBlocks } from './blocks';
15
15
  import { addFormatting } from './formatting';
@@ -20,6 +20,8 @@ import { addSearch } from './search';
20
20
  import { type EditorToolbarState } from './types';
21
21
  import { addViewMode } from './view-mode';
22
22
 
23
+ // TODO(burdon): Enable toolbar variants (e.g., markdown, code).
24
+
23
25
  export type EditorToolbarFeatureFlags = Partial<{
24
26
  showHeadings: boolean;
25
27
  showFormatting: boolean;
@@ -49,7 +51,7 @@ export type EditorToolbarProps = ThemedClassName<
49
51
  >;
50
52
 
51
53
  export const EditorToolbar = memo(({ classNames, role, attendableId, onAction, ...props }: EditorToolbarProps) => {
52
- const menuActions = useEditorToolbarActionGraph(props);
54
+ const menuActions = useMarkdownMenuActions(props);
53
55
 
54
56
  return (
55
57
  <ElevationProvider elevation={role === 'section' ? 'positioned' : 'base'}>
@@ -63,13 +65,13 @@ export const EditorToolbar = memo(({ classNames, role, attendableId, onAction, .
63
65
  type ToolbarActionsProps = Pick<EditorToolbarActionGraphProps, 'state' | 'getView' | 'customActions'> &
64
66
  EditorToolbarFeatureFlags;
65
67
 
68
+ // TODO(burdon): Some actions should toggle the state (e.g., toggle bullets on/off depending on the current state).
66
69
  // TODO(wittjosiah): Toolbar re-rendering is causing this graph to be recreated and breaking reactivity in some cases.
67
70
  // E.g. for toolbar dropdowns which use active icon, the icon is not updated when the active item changes.
68
71
  // This is currently only happening in the markdown plugin usage and should be reproduced in an editor story.
69
- // TODO(burdon): Some actions should toggle the state (e.g., toggle bullets on/off depending on the current state).
70
- const useEditorToolbarActionGraph = ({ state, getView, customActions, ...features }: ToolbarActionsProps) => {
72
+ const useMarkdownMenuActions = ({ state, getView, customActions, ...features }: ToolbarActionsProps) => {
71
73
  const menuCreator = useMemo(
72
- () => createToolbarActions({ state, getView, customActions, ...features }),
74
+ () => createMarkdownActions({ state, getView, customActions, ...features }),
73
75
  [
74
76
  state,
75
77
  getView,
@@ -87,7 +89,7 @@ const useEditorToolbarActionGraph = ({ state, getView, customActions, ...feature
87
89
  return useMenuActions(menuCreator);
88
90
  };
89
91
 
90
- const createToolbarActions = ({
92
+ const createMarkdownActions = ({
91
93
  state,
92
94
  getView,
93
95
  customActions,
@@ -7,7 +7,8 @@ import { type EditorView } from '@codemirror/view';
7
7
  import { type ActionGroupBuilderFn, type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
8
8
  import { addBlockquote, addCodeblock, insertTable, removeBlockquote, removeCodeblock } from '@dxos/ui-editor';
9
9
 
10
- import { translationKey } from '../../translations';
10
+ import { translationKey } from '#translations';
11
+
11
12
  import { type EditorToolbarState } from './types';
12
13
 
13
14
  const blockTypes = {
@@ -7,7 +7,8 @@ import { type EditorView } from '@codemirror/view';
7
7
  import { type ActionGroupBuilderFn, type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
8
8
  import { type Formatting, Inline, addLink, removeLink, setStyle } from '@dxos/ui-editor';
9
9
 
10
- import { translationKey } from '../../translations';
10
+ import { translationKey } from '#translations';
11
+
11
12
  import { type EditorToolbarState } from './types';
12
13
 
13
14
  const formats = {
@@ -7,7 +7,8 @@ import { type EditorView } from '@codemirror/view';
7
7
  import { type ActionGroupBuilderFn, type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
8
8
  import { setHeading } from '@dxos/ui-editor';
9
9
 
10
- import { translationKey } from '../../translations';
10
+ import { translationKey } from '#translations';
11
+
11
12
  import { type EditorToolbarState } from './types';
12
13
 
13
14
  const headingIcons: Record<string, string> = {
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { type ActionGroupBuilderFn } from '@dxos/react-ui-menu';
6
6
 
7
- import { translationKey } from '../../translations';
7
+ import { translationKey } from '#translations';
8
8
 
9
9
  /** Add image upload action to the builder. */
10
10
  export const addImageUpload =
@@ -7,7 +7,8 @@ import { type EditorView } from '@codemirror/view';
7
7
  import { type ActionGroupBuilderFn, type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
8
8
  import { List, addList, removeList } from '@dxos/ui-editor';
9
9
 
10
- import { translationKey } from '../../translations';
10
+ import { translationKey } from '#translations';
11
+
11
12
  import { type EditorToolbarState } from './types';
12
13
 
13
14
  const listStyles = {
@@ -7,7 +7,7 @@ import { type EditorView } from '@codemirror/view';
7
7
 
8
8
  import { type ActionGroupBuilderFn } from '@dxos/react-ui-menu';
9
9
 
10
- import { translationKey } from '../../translations';
10
+ import { translationKey } from '#translations';
11
11
 
12
12
  /** Add search action to the builder. */
13
13
  export const addSearch =
@@ -2,6 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type EditorViewMode, type Formatting } from '@dxos/ui-editor';
5
+ import { type Formatting } from '@dxos/ui-editor';
6
+ import { type EditorViewMode } from '@dxos/ui-editor/types';
6
7
 
7
8
  export type EditorToolbarState = Formatting & { viewMode?: EditorViewMode };
@@ -3,9 +3,10 @@
3
3
  //
4
4
 
5
5
  import { type ActionGroupBuilderFn, type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
6
- import { type EditorViewMode } from '@dxos/ui-editor';
6
+ import { type EditorViewMode } from '@dxos/ui-editor/types';
7
+
8
+ import { translationKey } from '#translations';
7
9
 
8
- import { translationKey } from '../../translations';
9
10
  import { type EditorToolbarState } from './types';
10
11
 
11
12
  const viewModes = {
@@ -16,8 +16,9 @@ import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
16
16
  import { compactSlots, createBasicExtensions, createThemeExtensions } from '@dxos/ui-editor';
17
17
  import { trim } from '@dxos/util';
18
18
 
19
+ import { translations } from '#translations';
20
+
19
21
  import { Editor, type EditorViewProps } from '../components';
20
- import { translations } from '../translations';
21
22
  import { assistant, type AssistantOptions } from './assistant-extension';
22
23
 
23
24
  // TODO(burdon): Factor out.
@@ -74,15 +74,15 @@ export const assistant = (options: AssistantOptions): Extension[] => {
74
74
  },
75
75
  /** @apply dx-button */
76
76
  '.cm-panel button': {
77
- color: 'var(--color-base-surface-text) !important',
77
+ color: 'var(--color-base-foreground) !important',
78
78
  },
79
79
  '.cm-panel.cm-panel-lint ul': {
80
- color: 'var(--color-base-surface-text) !important',
80
+ color: 'var(--color-base-foreground) !important',
81
81
  backgroundColor: 'var(--color-base-surface) !important',
82
82
  marginRight: '2rem !important',
83
83
  },
84
84
  '.cm-panel.cm-panel-lint ul [aria-selected]': {
85
- color: 'var(--color-base-surface-text) !important',
85
+ color: 'var(--color-base-foreground) !important',
86
86
  backgroundColor: 'var(--color-base-surface) !important',
87
87
  },
88
88
  '.cm-panel.cm-panel-lint ul li': {
package/src/index.ts CHANGED
@@ -2,10 +2,6 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { translations } from './translations';
6
-
7
5
  export * from './components';
8
6
  export * from './extensions';
9
7
  export * from './hooks';
10
-
11
- export { translations };
@@ -7,20 +7,21 @@ import { BroadcastChannelNetworkAdapter } from '@automerge/automerge-repo-networ
7
7
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
8
  import React, { useCallback, useEffect, useState } from 'react';
9
9
 
10
- import { Obj, Ref } from '@dxos/echo';
10
+ import { Obj, Query, Ref } from '@dxos/echo';
11
11
  import { DocAccessor, createDocAccessor } from '@dxos/echo-db';
12
12
  import { TestSchema } from '@dxos/echo/testing';
13
13
  import { log } from '@dxos/log';
14
14
  import { type Messenger } from '@dxos/protocols';
15
- import { Query, useQuery, useSpace } from '@dxos/react-client/echo';
15
+ import { useQuery, useSpace } from '@dxos/react-client/echo';
16
16
  import { type Identity, useIdentity } from '@dxos/react-client/halo';
17
17
  import { useClientStory, withMultiClientProvider } from '@dxos/react-client/testing';
18
18
  import { Button, useThemeContext } from '@dxos/react-ui';
19
19
  import { withLayout, withTheme, Loading } from '@dxos/react-ui/testing';
20
20
  import { createBasicExtensions, createDataExtensions, createThemeExtensions } from '@dxos/ui-editor';
21
21
 
22
+ import { translations } from '#translations';
23
+
22
24
  import { useTextEditor } from '../hooks';
23
- import { translations } from '../translations';
24
25
 
25
26
  const initialContent = 'Hello world!';
26
27
 
@@ -11,7 +11,8 @@ import { PublicKey } from '@dxos/keys';
11
11
  import { log } from '@dxos/log';
12
12
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
13
13
  import { withRegistry } from '@dxos/storybook-utils';
14
- import { type Comment, annotations, comments, createExternalCommentSync } from '@dxos/ui-editor';
14
+ import { annotations, comments, createExternalCommentSync } from '@dxos/ui-editor';
15
+ import { type Comment } from '@dxos/ui-editor/types';
15
16
 
16
17
  import { createRenderer, str } from '../util';
17
18
  import { EditorStory, content, longText } from './components';
@@ -9,7 +9,6 @@ import { useThemeContext } from '@dxos/react-ui';
9
9
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
10
10
  import { withRegistry } from '@dxos/storybook-utils';
11
11
  import {
12
- type EditorViewMode,
13
12
  createBasicExtensions,
14
13
  createMarkdownExtensions,
15
14
  createThemeExtensions,
@@ -17,10 +16,12 @@ import {
17
16
  documentSlots,
18
17
  formattingKeymap,
19
18
  } from '@dxos/ui-editor';
19
+ import { type EditorViewMode } from '@dxos/ui-editor/types';
20
+
21
+ import { translations } from '#translations';
20
22
 
21
23
  import { Editor } from '../components';
22
24
  import { type UseTextEditorProps } from '../hooks';
23
- import { translations } from '../translations';
24
25
 
25
26
  type DefaultStoryProps = { placeholder?: string; viewMode?: EditorViewMode } & UseTextEditorProps;
26
27
 
@@ -51,7 +52,7 @@ const DefaultStory = ({ autoFocus, initialValue, placeholder, viewMode = 'source
51
52
  <Editor.Root extensions={extensions} viewMode={viewMode}>
52
53
  <Editor.Content>
53
54
  <Editor.Toolbar classNames='dx-document' />
54
- <div role='none' className='dx-container dx-document bg-base-surface'>
55
+ <div className='dx-container dx-document bg-base-surface'>
55
56
  <Editor.View autoFocus={autoFocus} initialValue={initialValue} selectionEnd />
56
57
  </div>
57
58
  </Editor.Content>
@@ -9,7 +9,7 @@ import React from 'react';
9
9
  import { log } from '@dxos/log';
10
10
  import { random } from '@dxos/random';
11
11
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
- import { blast, defaultOptions, dropFile, join, typewriter } from '@dxos/ui-editor';
12
+ import { blast, defaultOptions, dropFile, join, snippets } from '@dxos/ui-editor';
13
13
 
14
14
  import { EditorStory, content } from './components';
15
15
 
@@ -27,16 +27,16 @@ export default meta;
27
27
  type Story = StoryObj<typeof meta>;
28
28
 
29
29
  //
30
- // Typewriter
30
+ // Snippets
31
31
  //
32
32
 
33
- const typewriterItems = localStorage.getItem('org.dxos.testing.typewriter')?.split(',');
33
+ const snippetItems = localStorage.getItem('org.dxos.testing.snippets')?.split(',');
34
34
 
35
- export const Typewriter: Story = {
35
+ export const Snippets: Story = {
36
36
  render: () => (
37
37
  <EditorStory
38
- text={join('# Typewriter', '', content.paragraphs, content.footer)}
39
- extensions={[typewriter({ items: typewriterItems })]}
38
+ text={join('# Snippets', '', content.paragraphs, content.footer)}
39
+ extensions={[snippets({ items: snippetItems })]}
40
40
  />
41
41
  ),
42
42
  };
@@ -50,7 +50,7 @@ export const Blast: Story = {
50
50
  <EditorStory
51
51
  text={join('# Blast', '', content.paragraphs, content.codeblocks, content.paragraphs)}
52
52
  extensions={[
53
- typewriter({ items: typewriterItems }),
53
+ snippets({ items: snippetItems }),
54
54
  blast(
55
55
  defaultsDeep(
56
56
  {
@@ -9,7 +9,6 @@ import { random } from '@dxos/random';
9
9
  import { Domino } from '@dxos/ui';
10
10
  import {
11
11
  type EditorSelectionState,
12
- type RenderCallback,
13
12
  decorateMarkdown,
14
13
  folding,
15
14
  formattingKeymap,
@@ -17,6 +16,7 @@ import {
17
16
  linkTooltip,
18
17
  table,
19
18
  } from '@dxos/ui-editor';
19
+ import { type RenderCallback } from '@dxos/ui-editor/types';
20
20
  import { safeUrl } from '@dxos/util';
21
21
 
22
22
  import { str } from '../../util';
@@ -206,7 +206,7 @@ export const links: Completion[] = [
206
206
  export const names = ['adam', 'alice', 'alison', 'bob', 'carol', 'charlie', 'sayuri', 'shoko'];
207
207
 
208
208
  const hover =
209
- 'rounded-xs text-base-surface-text text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
209
+ 'rounded-xs text-base-foreground text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
210
210
 
211
211
  export const renderLinkTooltip: RenderCallback<{ url: string }> = (el, { url }) => {
212
212
  el.appendChild(
@@ -6,7 +6,7 @@ import React, { type FC } from 'react';
6
6
  import { createRoot } from 'react-dom/client';
7
7
 
8
8
  import { ThemeProvider, Tooltip } from '@dxos/react-ui';
9
- import { type RenderCallback } from '@dxos/ui-editor';
9
+ import { type RenderCallback } from '@dxos/ui-editor/types';
10
10
  import { defaultTx } from '@dxos/ui-theme';
11
11
 
12
12
  /**