@dxos/react-ui-editor 0.10.0 → 0.11.0
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.
- package/dist/lib/index.mjs +1477 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/translations.mjs +32 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/types/src/components/Editor/Editor.d.ts +22 -17
- package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
- package/dist/types/src/components/Editor/EditorContext.d.ts +20 -0
- package/dist/types/src/components/Editor/EditorContext.d.ts.map +1 -0
- package/dist/types/src/components/Editor/EditorView.d.ts +1 -2
- package/dist/types/src/components/Editor/EditorView.d.ts.map +1 -1
- package/dist/types/src/components/Editor/index.d.ts +2 -0
- package/dist/types/src/components/Editor/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +7 -1
- package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/menu.d.ts +4 -2
- package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts +7 -2
- package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewContext.d.ts +18 -0
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewContext.d.ts.map +1 -0
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts +0 -6
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
- package/dist/types/src/components/EditorPreviewProvider/index.d.ts +1 -0
- package/dist/types/src/components/EditorPreviewProvider/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +4 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/index.d.ts +1 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts +27 -2
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/stories/Assistant.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Automerge.stories.d.ts +16 -39
- package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Blocks.stories.d.ts +10 -0
- package/dist/types/src/stories/Blocks.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Comments.stories.d.ts +53 -14
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Diff.stories.d.ts +32 -0
- package/dist/types/src/stories/Diff.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Experimental.stories.d.ts +1 -0
- package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Folding.stories.d.ts +18 -0
- package/dist/types/src/stories/Folding.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Outliner.stories.d.ts +4 -4
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Popover.stories.d.ts +3 -3
- package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Suggest.stories.d.ts +27 -0
- package/dist/types/src/stories/Suggest.stories.d.ts.map +1 -0
- package/dist/types/src/stories/TrackChanges.stories.d.ts +44 -0
- package/dist/types/src/stories/TrackChanges.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Widgets.stories.d.ts +12 -0
- package/dist/types/src/stories/Widgets.stories.d.ts.map +1 -1
- package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
- package/dist/types/src/stories/components/util.d.ts +16 -0
- package/dist/types/src/stories/components/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +40 -83
- package/src/components/Editor/Editor.tsx +142 -35
- package/src/components/Editor/EditorContext.ts +34 -0
- package/src/components/Editor/EditorView.tsx +9 -6
- package/src/components/Editor/index.ts +3 -0
- package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +98 -8
- package/src/components/EditorMenuProvider/menu.ts +4 -2
- package/src/components/EditorMenuProvider/useEditorMenu.ts +114 -29
- package/src/components/EditorPreviewProvider/EditorPreviewContext.ts +21 -0
- package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +1 -10
- package/src/components/EditorPreviewProvider/index.ts +2 -0
- package/src/components/EditorToolbar/EditorToolbar.tsx +6 -3
- package/src/components/EditorToolbar/index.ts +1 -0
- package/src/components/EditorToolbar/lists.ts +2 -6
- package/src/components/EditorToolbar/view-mode.ts +41 -12
- package/src/components/index.ts +1 -0
- package/src/index.ts +0 -1
- package/src/{extensions → stories}/Assistant.stories.tsx +7 -2
- package/src/stories/Automerge.stories.tsx +99 -78
- package/src/stories/Blocks.stories.tsx +83 -0
- package/src/stories/Comments.stories.tsx +273 -74
- package/src/stories/Diff.stories.tsx +48 -0
- package/src/stories/EditorToolbar.stories.tsx +2 -2
- package/src/stories/Experimental.stories.tsx +13 -2
- package/src/stories/Folding.stories.tsx +120 -0
- package/src/stories/Markdown.stories.tsx +1 -1
- package/src/stories/Outliner.stories.tsx +18 -7
- package/src/stories/Popover.stories.tsx +27 -5
- package/src/stories/Suggest.stories.tsx +199 -0
- package/src/stories/TrackChanges.stories.tsx +226 -0
- package/src/stories/Widgets.stories.tsx +162 -10
- package/src/stories/components/EditorStory.tsx +15 -6
- package/src/stories/components/util.tsx +40 -2
- package/dist/lib/browser/index.mjs +0 -1676
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/translations.mjs +0 -39
- package/dist/lib/browser/translations.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -1678
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/translations.mjs +0 -41
- package/dist/lib/node-esm/translations.mjs.map +0 -7
- package/dist/types/src/extensions/Assistant.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/assistant-extension.d.ts +0 -24
- package/dist/types/src/extensions/assistant-extension.d.ts.map +0 -1
- package/dist/types/src/extensions/index.d.ts +0 -2
- package/dist/types/src/extensions/index.d.ts.map +0 -1
- package/src/extensions/assistant-extension.tsx +0 -223
- package/src/extensions/index.ts +0 -5
- /package/dist/types/src/{extensions → stories}/Assistant.stories.d.ts +0 -0
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2026 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type Diagnostic, forEachDiagnostic, linter, setDiagnostics } from '@codemirror/lint';
|
|
6
|
-
import { ChangeSet, type Extension } from '@codemirror/state';
|
|
7
|
-
import { EditorView } from '@codemirror/view';
|
|
8
|
-
|
|
9
|
-
import { log } from '@dxos/log';
|
|
10
|
-
import { safeParseJson, trim } from '@dxos/util';
|
|
11
|
-
|
|
12
|
-
const DEFAULT_INSTRUCTIONS = trim`
|
|
13
|
-
Proofread the input text below.
|
|
14
|
-
Identify typos and grammatical errors.
|
|
15
|
-
Return ONLY a valid JSON array of objects with fields: "original" (string), "replacement" (string), "context" (string, 3-5 words around match).
|
|
16
|
-
--
|
|
17
|
-
`;
|
|
18
|
-
|
|
19
|
-
export type AssistantOptions = {
|
|
20
|
-
/**
|
|
21
|
-
* Invoke the language model with the given prompt and return the raw text response.
|
|
22
|
-
*/
|
|
23
|
-
generate: (request: { instructions: string; content: string }) => Promise<string>;
|
|
24
|
-
/**
|
|
25
|
-
* Instructions to use for the language model.
|
|
26
|
-
*/
|
|
27
|
-
instructions?: string;
|
|
28
|
-
/**
|
|
29
|
-
* Show panel automatically.
|
|
30
|
-
*/
|
|
31
|
-
autoPanel?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Debounce delay.
|
|
34
|
-
*/
|
|
35
|
-
delay?: number;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const underline = (color: string) => {
|
|
39
|
-
const svg = trim`
|
|
40
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="3">
|
|
41
|
-
<path d="m0 3 l2 -2 l1 0 l2 2 l1 0" stroke="${color}" fill="none" stroke-width="1"/>
|
|
42
|
-
</svg>
|
|
43
|
-
`;
|
|
44
|
-
|
|
45
|
-
return `url('data:image/svg+xml;base64,${btoa(svg)}') !important`;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const assistant = (options: AssistantOptions): Extension[] => {
|
|
49
|
-
const styles = getComputedStyle(document.documentElement);
|
|
50
|
-
const style = {
|
|
51
|
-
info: styles.getPropertyValue('--color-green-500').trim(),
|
|
52
|
-
warning: styles.getPropertyValue('--color-orange-500').trim(),
|
|
53
|
-
error: styles.getPropertyValue('--color-rose-500').trim(),
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
return [
|
|
57
|
-
assistantLinter(options),
|
|
58
|
-
EditorView.baseTheme({
|
|
59
|
-
'.cm-lintRange-info': {
|
|
60
|
-
backgroundImage: underline(style.info),
|
|
61
|
-
},
|
|
62
|
-
'.cm-lintRange-warning': {
|
|
63
|
-
backgroundImage: underline(style.warning),
|
|
64
|
-
},
|
|
65
|
-
'.cm-lintRange-error': {
|
|
66
|
-
backgroundImage: underline(style.error),
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
'.cm-panels-bottom': {
|
|
70
|
-
borderTop: '1px solid var(--color-separator) !important',
|
|
71
|
-
},
|
|
72
|
-
'.cm-panel-lint .cm-panel': {
|
|
73
|
-
outline: 'none !important',
|
|
74
|
-
},
|
|
75
|
-
/** @apply dx-button */
|
|
76
|
-
'.cm-panel button': {
|
|
77
|
-
color: 'var(--color-base-fg) !important',
|
|
78
|
-
},
|
|
79
|
-
'.cm-panel.cm-panel-lint ul': {
|
|
80
|
-
color: 'var(--color-base-fg) !important',
|
|
81
|
-
backgroundColor: 'var(--color-base-surface) !important',
|
|
82
|
-
marginRight: '2rem !important',
|
|
83
|
-
},
|
|
84
|
-
'.cm-panel.cm-panel-lint ul [aria-selected]': {
|
|
85
|
-
color: 'var(--color-base-fg) !important',
|
|
86
|
-
backgroundColor: 'var(--color-base-surface) !important',
|
|
87
|
-
},
|
|
88
|
-
'.cm-panel.cm-panel-lint ul li': {
|
|
89
|
-
display: 'grid',
|
|
90
|
-
gridTemplateColumns: '1fr auto',
|
|
91
|
-
alignItems: 'center',
|
|
92
|
-
},
|
|
93
|
-
'.cm-panel.cm-panel-lint ul li .cm-diagnosticText': {
|
|
94
|
-
paddingRight: '8px !important',
|
|
95
|
-
},
|
|
96
|
-
'.cm-panel.cm-panel-lint ul li button.cm-diagnosticAction': {
|
|
97
|
-
margin: 'none !important',
|
|
98
|
-
},
|
|
99
|
-
'.cm-diagnostic': {
|
|
100
|
-
padding: '0px 8px !important',
|
|
101
|
-
whiteSpace: 'pre-wrap !important',
|
|
102
|
-
},
|
|
103
|
-
'.cm-diagnostic-info': {
|
|
104
|
-
border: 'none !important',
|
|
105
|
-
},
|
|
106
|
-
}),
|
|
107
|
-
];
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
// Linter
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
type Suggestion = {
|
|
115
|
-
original: string;
|
|
116
|
-
replacement: string;
|
|
117
|
-
context: string;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const isSuggestion = (value: unknown): value is Suggestion =>
|
|
121
|
-
typeof value === 'object' &&
|
|
122
|
-
value !== null &&
|
|
123
|
-
typeof (value as Suggestion).original === 'string' &&
|
|
124
|
-
typeof (value as Suggestion).replacement === 'string' &&
|
|
125
|
-
typeof (value as Suggestion).context === 'string';
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Find the index of `original` within `content`, using `context` to disambiguate when there are multiple occurrences.
|
|
129
|
-
*/
|
|
130
|
-
const findSuggestionIndex = (content: string, suggestion: Suggestion): number => {
|
|
131
|
-
const firstIdx = content.indexOf(suggestion.original);
|
|
132
|
-
if (firstIdx === -1) {
|
|
133
|
-
return -1;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Check for duplicate occurrences; use context to disambiguate.
|
|
137
|
-
const secondIdx = content.indexOf(suggestion.original, firstIdx + 1);
|
|
138
|
-
if (secondIdx === -1) {
|
|
139
|
-
return firstIdx;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Find the occurrence whose surrounding text best matches the context.
|
|
143
|
-
const contextIdx = content.indexOf(suggestion.context);
|
|
144
|
-
if (contextIdx !== -1) {
|
|
145
|
-
const contextEnd = contextIdx + suggestion.context.length;
|
|
146
|
-
if (secondIdx >= contextIdx && secondIdx <= contextEnd) {
|
|
147
|
-
return secondIdx;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return firstIdx;
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const replaceTextAndDropLintAtRange = (view: EditorView, from: number, to: number, insert: string) => {
|
|
155
|
-
const kept: Diagnostic[] = [];
|
|
156
|
-
forEachDiagnostic(view.state, (diagnostic, diagnosticFrom, diagnosticTo) => {
|
|
157
|
-
if (diagnosticFrom < to && diagnosticTo > from) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
kept.push({ ...diagnostic, from: diagnosticFrom, to: diagnosticTo });
|
|
161
|
-
});
|
|
162
|
-
const changeSet = ChangeSet.of({ from, to, insert }, view.state.doc.length);
|
|
163
|
-
const next = kept.map((d) => ({
|
|
164
|
-
...d,
|
|
165
|
-
from: changeSet.mapPos(d.from, 1),
|
|
166
|
-
to: changeSet.mapPos(d.to, -1),
|
|
167
|
-
}));
|
|
168
|
-
view.dispatch({
|
|
169
|
-
changes: { from, to, insert },
|
|
170
|
-
...setDiagnostics(view.state, next),
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const assistantLinter = ({
|
|
175
|
-
generate,
|
|
176
|
-
instructions = DEFAULT_INSTRUCTIONS,
|
|
177
|
-
autoPanel = true,
|
|
178
|
-
delay = 2_000,
|
|
179
|
-
}: AssistantOptions) =>
|
|
180
|
-
linter(
|
|
181
|
-
async (view) => {
|
|
182
|
-
try {
|
|
183
|
-
const content = view.state.doc.toString();
|
|
184
|
-
const result = await generate({ instructions, content });
|
|
185
|
-
|
|
186
|
-
const [match] = result.match(/\[.*\]/s) ?? [];
|
|
187
|
-
const parsed = match ? safeParseJson<unknown[]>(match, []) : [];
|
|
188
|
-
const suggestions = Array.isArray(parsed) ? parsed.filter(isSuggestion) : [];
|
|
189
|
-
if (suggestions && suggestions.length > 0) {
|
|
190
|
-
const diagnostics: Diagnostic[] = [];
|
|
191
|
-
for (const suggestion of suggestions) {
|
|
192
|
-
const idx = findSuggestionIndex(content, suggestion);
|
|
193
|
-
if (idx !== -1) {
|
|
194
|
-
diagnostics.push({
|
|
195
|
-
from: idx,
|
|
196
|
-
to: idx + suggestion.original.length,
|
|
197
|
-
severity: 'info',
|
|
198
|
-
message: `Suggestion: ${suggestion.replacement}`,
|
|
199
|
-
actions: [
|
|
200
|
-
{
|
|
201
|
-
name: 'Apply',
|
|
202
|
-
apply: (view, from, to) => {
|
|
203
|
-
replaceTextAndDropLintAtRange(view, from, to, suggestion.replacement);
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
],
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return diagnostics;
|
|
212
|
-
}
|
|
213
|
-
} catch (err) {
|
|
214
|
-
log.catch(err);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return [];
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
delay,
|
|
221
|
-
autoPanel,
|
|
222
|
-
},
|
|
223
|
-
);
|
package/src/extensions/index.ts
DELETED
|
File without changes
|