@dxos/react-ui-editor 0.8.2-main.12df754 → 0.8.2-main.30e4dbb
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/browser/index.mjs +1178 -1110
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/node/index.cjs +1386 -1319
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs.map +2 -2
- package/dist/lib/node-esm/index.mjs +1178 -1110
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs.map +2 -2
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/{stories/InputMode.stories.d.ts → components/EditorToolbar/EditorToolbar.stories.d.ts} +3 -7
- package/dist/types/src/components/EditorToolbar/EditorToolbar.stories.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/comment.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/image.d.ts +16 -0
- package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
- package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts +11 -17
- package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/command/command.d.ts.map +1 -1
- package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
- package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +5 -5
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/typewriter.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/story-utils.d.ts.map +1 -1
- package/dist/types/src/testing/RefPopover.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/dom.d.ts.map +1 -1
- package/dist/types/src/util/facet.d.ts.map +1 -1
- package/dist/types/src/util/react.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -28
- package/src/components/EditorToolbar/EditorToolbar.stories.tsx +90 -0
- package/src/components/EditorToolbar/EditorToolbar.tsx +30 -31
- package/src/components/EditorToolbar/blocks.ts +27 -6
- package/src/components/EditorToolbar/comment.ts +11 -4
- package/src/components/EditorToolbar/formatting.ts +34 -7
- package/src/components/EditorToolbar/headings.ts +9 -8
- package/src/components/EditorToolbar/image.ts +16 -0
- package/src/components/EditorToolbar/lists.ts +26 -7
- package/src/components/EditorToolbar/search.ts +19 -0
- package/src/components/EditorToolbar/util.ts +14 -14
- package/src/components/EditorToolbar/view-mode.ts +9 -8
- package/src/extensions/modes.ts +5 -6
- package/src/extensions/preview/preview.ts +1 -1
- package/src/hooks/index.ts +0 -1
- package/src/testing/RefPopover.tsx +4 -4
- package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
- package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
- package/dist/types/src/stories/InputMode.stories.d.ts.map +0 -1
- package/src/hooks/useActionHandler.ts +0 -12
- package/src/stories/InputMode.stories.tsx +0 -124
@@ -42,7 +42,7 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
42
42
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
43
43
|
|
44
44
|
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
45
|
-
import
|
45
|
+
import React3, { memo, useCallback } from "react";
|
46
46
|
import { ElevationProvider } from "@dxos/react-ui";
|
47
47
|
import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
|
48
48
|
import { textBlockWidth } from "@dxos/react-ui-theme";
|
@@ -54,692 +54,110 @@ import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
|
|
54
54
|
var useEditorToolbarState = (initialState = {}) => {
|
55
55
|
return useMemo(() => live(initialState), []);
|
56
56
|
};
|
57
|
-
var createEditorAction = (
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
57
|
+
var createEditorAction = (id, invoke, properties) => {
|
58
|
+
const { label = [
|
59
|
+
`${id} label`,
|
60
|
+
{
|
61
|
+
ns: translationKey
|
62
|
+
}
|
63
|
+
], ...rest } = properties;
|
64
|
+
return createMenuAction(id, invoke, {
|
65
|
+
label,
|
66
|
+
...rest
|
67
|
+
});
|
68
|
+
};
|
67
69
|
var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
|
68
70
|
icon,
|
69
71
|
iconOnly: true,
|
70
72
|
...props
|
71
73
|
});
|
72
|
-
var editorToolbarSearch = createEditorAction({
|
73
|
-
type: "search"
|
74
|
-
}, "ph--magnifying-glass--regular");
|
75
74
|
|
76
|
-
// packages/ui/react-ui-editor/src/
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
value
|
81
|
-
});
|
82
|
-
var createBlockActions = (value, blankLine) => Object.entries({
|
83
|
-
blockquote: "ph--quotes--regular",
|
84
|
-
codeblock: "ph--code-block--regular",
|
85
|
-
table: "ph--table--regular"
|
86
|
-
}).map(([type, icon]) => {
|
87
|
-
return createEditorAction({
|
88
|
-
type,
|
89
|
-
checked: type === value,
|
90
|
-
...type === "table" && {
|
91
|
-
disabled: !!blankLine
|
92
|
-
}
|
93
|
-
}, icon);
|
94
|
-
});
|
95
|
-
var createBlocks = (state) => {
|
96
|
-
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
97
|
-
const blockGroupAction = createBlockGroupAction(value);
|
98
|
-
const blockActions = createBlockActions(value, state.blankLine);
|
99
|
-
return {
|
100
|
-
nodes: [
|
101
|
-
blockGroupAction,
|
102
|
-
...blockActions
|
103
|
-
],
|
104
|
-
edges: [
|
105
|
-
{
|
106
|
-
source: "root",
|
107
|
-
target: "block"
|
108
|
-
},
|
109
|
-
...blockActions.map(({ id }) => ({
|
110
|
-
source: blockGroupAction.id,
|
111
|
-
target: id
|
112
|
-
}))
|
113
|
-
]
|
114
|
-
};
|
115
|
-
};
|
75
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
76
|
+
import { StateField } from "@codemirror/state";
|
77
|
+
import { Decoration, EditorView } from "@codemirror/view";
|
78
|
+
import { isNotFalsy } from "@dxos/util";
|
116
79
|
|
117
|
-
// packages/ui/react-ui-editor/src/
|
118
|
-
|
119
|
-
var
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
nodes: [
|
125
|
-
createCommentAction([
|
126
|
-
commentLabel(state.comment, state.selection),
|
127
|
-
{
|
128
|
-
ns: translationKey
|
129
|
-
}
|
130
|
-
])
|
131
|
-
],
|
132
|
-
edges: [
|
133
|
-
{
|
134
|
-
source: "root",
|
135
|
-
target: "comment"
|
136
|
-
}
|
137
|
-
]
|
80
|
+
// packages/ui/react-ui-editor/src/util/facet.ts
|
81
|
+
import { Facet } from "@codemirror/state";
|
82
|
+
var singleValueFacet = (defaultValue) => Facet.define({
|
83
|
+
// Called immediately.
|
84
|
+
combine: (providers) => {
|
85
|
+
return providers[0] ?? defaultValue;
|
86
|
+
}
|
138
87
|
});
|
139
88
|
|
140
|
-
// packages/ui/react-ui-editor/src/
|
141
|
-
var
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
code: "ph--code--regular",
|
146
|
-
link: "ph--link--regular"
|
89
|
+
// packages/ui/react-ui-editor/src/util/cursor.ts
|
90
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
91
|
+
var defaultCursorConverter = {
|
92
|
+
toCursor: (position) => position.toString(),
|
93
|
+
fromCursor: (cursor) => parseInt(cursor)
|
147
94
|
};
|
148
|
-
var
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
};
|
95
|
+
var Cursor = class _Cursor {
|
96
|
+
static {
|
97
|
+
this.converter = singleValueFacet(defaultCursorConverter);
|
98
|
+
}
|
99
|
+
static {
|
100
|
+
this.getCursorFromRange = (state, range) => {
|
101
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
102
|
+
const from = cursorConverter2.toCursor(range.from);
|
103
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
104
|
+
return [
|
105
|
+
from,
|
106
|
+
to
|
107
|
+
].join(":");
|
108
|
+
};
|
109
|
+
}
|
110
|
+
static {
|
111
|
+
this.getRangeFromCursor = (state, cursor) => {
|
112
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
113
|
+
const parts = cursor.split(":");
|
114
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
115
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
116
|
+
return from !== void 0 && to !== void 0 ? {
|
117
|
+
from,
|
118
|
+
to
|
119
|
+
} : void 0;
|
120
|
+
};
|
121
|
+
}
|
176
122
|
};
|
177
123
|
|
178
|
-
// packages/ui/react-ui-editor/src/
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
"6": "ph--text-h-six--regular"
|
193
|
-
}).map(([levelStr, icon]) => {
|
194
|
-
const level = parseInt(levelStr);
|
195
|
-
return createEditorAction({
|
196
|
-
type: "heading",
|
197
|
-
data: level,
|
198
|
-
checked: value === levelStr
|
199
|
-
}, icon, [
|
200
|
-
"heading level label",
|
201
|
-
{
|
202
|
-
count: level,
|
203
|
-
ns: translationKey
|
124
|
+
// packages/ui/react-ui-editor/src/util/debug.ts
|
125
|
+
import { log } from "@dxos/log";
|
126
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
127
|
+
var wrapWithCatch = (fn) => {
|
128
|
+
return (...args) => {
|
129
|
+
try {
|
130
|
+
return fn(...args);
|
131
|
+
} catch (err) {
|
132
|
+
log.catch(err, void 0, {
|
133
|
+
F: __dxlog_file,
|
134
|
+
L: 15,
|
135
|
+
S: void 0,
|
136
|
+
C: (f, a) => f(...a)
|
137
|
+
});
|
204
138
|
}
|
205
|
-
], `heading--${levelStr}`);
|
206
|
-
});
|
207
|
-
var computeHeadingValue = (state) => {
|
208
|
-
const blockType = state ? state.blockType : "paragraph";
|
209
|
-
const header = blockType && /heading(\d)/.exec(blockType);
|
210
|
-
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
211
|
-
};
|
212
|
-
var createHeadings = (state) => {
|
213
|
-
const headingValue = computeHeadingValue(state);
|
214
|
-
const headingGroupAction = createHeadingGroupAction(headingValue);
|
215
|
-
const headingActions = createHeadingActions(headingValue);
|
216
|
-
return {
|
217
|
-
nodes: [
|
218
|
-
headingGroupAction,
|
219
|
-
...headingActions
|
220
|
-
],
|
221
|
-
edges: [
|
222
|
-
{
|
223
|
-
source: "root",
|
224
|
-
target: "heading"
|
225
|
-
},
|
226
|
-
...headingActions.map(({ id }) => ({
|
227
|
-
source: headingGroupAction.id,
|
228
|
-
target: id
|
229
|
-
}))
|
230
|
-
]
|
231
139
|
};
|
232
140
|
};
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
141
|
+
var callbackWrapper = (fn) => (...args) => {
|
142
|
+
try {
|
143
|
+
return fn(...args);
|
144
|
+
} catch (err) {
|
145
|
+
log.catch(err, void 0, {
|
146
|
+
F: __dxlog_file,
|
147
|
+
L: 29,
|
148
|
+
S: void 0,
|
149
|
+
C: (f, a) => f(...a)
|
150
|
+
});
|
151
|
+
}
|
239
152
|
};
|
240
|
-
var
|
241
|
-
|
242
|
-
|
243
|
-
value
|
244
|
-
});
|
245
|
-
var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
|
246
|
-
type: `list-${listStyle}`,
|
247
|
-
checked: value === listStyle
|
248
|
-
}, icon));
|
249
|
-
var createLists = (state) => {
|
250
|
-
const value = state.listStyle ?? "";
|
251
|
-
const listGroupAction = createListGroupAction(value);
|
252
|
-
const listActionsMap = createListActions(value);
|
253
|
-
return {
|
254
|
-
nodes: [
|
255
|
-
listGroupAction,
|
256
|
-
...listActionsMap
|
257
|
-
],
|
258
|
-
edges: [
|
259
|
-
{
|
260
|
-
source: "root",
|
261
|
-
target: "list"
|
262
|
-
},
|
263
|
-
...listActionsMap.map(({ id }) => ({
|
264
|
-
source: listGroupAction.id,
|
265
|
-
target: id
|
266
|
-
}))
|
267
|
-
]
|
268
|
-
};
|
153
|
+
var debugDispatcher = (trs, view) => {
|
154
|
+
logChanges(trs);
|
155
|
+
view.update(trs);
|
269
156
|
};
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
applyActive: true,
|
275
|
-
selectCardinality: "single",
|
276
|
-
value
|
277
|
-
}, "ph--eye--regular");
|
278
|
-
var createViewModeActions = (value) => Object.entries({
|
279
|
-
preview: "ph--eye--regular",
|
280
|
-
source: "ph--pencil-simple--regular",
|
281
|
-
readonly: "ph--pencil-slash--regular"
|
282
|
-
}).map(([viewMode, icon]) => {
|
283
|
-
return createEditorAction({
|
284
|
-
type: "view-mode",
|
285
|
-
data: viewMode,
|
286
|
-
checked: viewMode === value
|
287
|
-
}, icon, [
|
288
|
-
`${viewMode} mode label`,
|
289
|
-
{
|
290
|
-
ns: translationKey
|
291
|
-
}
|
292
|
-
], `view-mode--${viewMode}`);
|
293
|
-
});
|
294
|
-
var createViewMode = (state) => {
|
295
|
-
const value = state.viewMode ?? "source";
|
296
|
-
const viewModeGroupAction = createViewModeGroupAction(value);
|
297
|
-
const viewModeActions = createViewModeActions(value);
|
298
|
-
return {
|
299
|
-
nodes: [
|
300
|
-
viewModeGroupAction,
|
301
|
-
...viewModeActions
|
302
|
-
],
|
303
|
-
edges: [
|
304
|
-
{
|
305
|
-
source: "root",
|
306
|
-
target: "viewMode"
|
307
|
-
},
|
308
|
-
...viewModeActions.map(({ id }) => ({
|
309
|
-
source: viewModeGroupAction.id,
|
310
|
-
target: id
|
311
|
-
}))
|
312
|
-
]
|
313
|
-
};
|
314
|
-
};
|
315
|
-
|
316
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
317
|
-
import { EditorView } from "@codemirror/view";
|
318
|
-
import { mx as mx2 } from "@dxos/react-ui-theme";
|
319
|
-
|
320
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
321
|
-
import { mx } from "@dxos/react-ui-theme";
|
322
|
-
var headings = {
|
323
|
-
1: "text-4xl",
|
324
|
-
2: "text-3xl",
|
325
|
-
3: "text-2xl",
|
326
|
-
4: "text-xl",
|
327
|
-
5: "text-lg",
|
328
|
-
6: ""
|
329
|
-
};
|
330
|
-
var theme = {
|
331
|
-
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
332
|
-
codeMark: "font-mono text-primary-500",
|
333
|
-
mark: "opacity-50",
|
334
|
-
heading: (level) => {
|
335
|
-
return mx(headings[level], "dark:text-primary-400");
|
336
|
-
}
|
337
|
-
};
|
338
|
-
|
339
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
340
|
-
import get from "lodash.get";
|
341
|
-
import { tokens } from "@dxos/react-ui-theme";
|
342
|
-
var getToken = (path, defaultValue) => {
|
343
|
-
const value = get(tokens, path, defaultValue);
|
344
|
-
return value?.toString() ?? "";
|
345
|
-
};
|
346
|
-
var fontBody = getToken("fontFamily.body");
|
347
|
-
var fontMono = getToken("fontFamily.mono");
|
348
|
-
|
349
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
350
|
-
var defaultTheme = {
|
351
|
-
"&": {},
|
352
|
-
"&.cm-focused": {
|
353
|
-
outline: "none"
|
354
|
-
},
|
355
|
-
/**
|
356
|
-
* Scroller
|
357
|
-
*/
|
358
|
-
".cm-scroller": {
|
359
|
-
overflowY: "auto"
|
360
|
-
},
|
361
|
-
/**
|
362
|
-
* Content
|
363
|
-
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
364
|
-
*/
|
365
|
-
".cm-content": {
|
366
|
-
padding: "unset",
|
367
|
-
fontFamily: fontBody,
|
368
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
369
|
-
fontSize: "16px",
|
370
|
-
lineHeight: 1.5,
|
371
|
-
color: "unset"
|
372
|
-
},
|
373
|
-
/**
|
374
|
-
* Gutters
|
375
|
-
* NOTE: Gutters should have the same top margin as the content.
|
376
|
-
*/
|
377
|
-
".cm-gutters": {
|
378
|
-
borderRight: "none",
|
379
|
-
background: "transparent"
|
380
|
-
},
|
381
|
-
".cm-gutter": {},
|
382
|
-
".cm-gutter.cm-lineNumbers": {
|
383
|
-
paddingRight: "4px",
|
384
|
-
borderRight: "1px solid var(--dx-separator)"
|
385
|
-
},
|
386
|
-
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
387
|
-
minWidth: "40px",
|
388
|
-
alignContent: "center"
|
389
|
-
},
|
390
|
-
/**
|
391
|
-
* Height is set to match the corresponding line.
|
392
|
-
*/
|
393
|
-
".cm-gutterElement": {
|
394
|
-
alignItems: "center",
|
395
|
-
fontSize: "12px"
|
396
|
-
},
|
397
|
-
/**
|
398
|
-
* Line.
|
399
|
-
*/
|
400
|
-
".cm-line": {
|
401
|
-
paddingInline: 0
|
402
|
-
},
|
403
|
-
".cm-activeLine": {
|
404
|
-
background: "var(--dx-cmActiveLine)"
|
405
|
-
},
|
406
|
-
/**
|
407
|
-
* Cursor (layer).
|
408
|
-
*/
|
409
|
-
".cm-cursor, .cm-dropCursor": {
|
410
|
-
borderLeft: "2px solid var(--dx-cmCursor)"
|
411
|
-
},
|
412
|
-
".cm-placeholder": {
|
413
|
-
color: "var(--dx-subdued)"
|
414
|
-
},
|
415
|
-
/**
|
416
|
-
* Selection (layer).
|
417
|
-
*/
|
418
|
-
".cm-selectionBackground": {
|
419
|
-
background: "var(--dx-cmSelection)"
|
420
|
-
},
|
421
|
-
/**
|
422
|
-
* Search.
|
423
|
-
* NOTE: Matches comment.
|
424
|
-
*/
|
425
|
-
".cm-searchMatch": {
|
426
|
-
margin: "0 -3px",
|
427
|
-
padding: "3px",
|
428
|
-
borderRadius: "3px",
|
429
|
-
background: "var(--dx-cmHighlightSurface)",
|
430
|
-
color: "var(--dx-cmHighlight)"
|
431
|
-
},
|
432
|
-
".cm-searchMatch-selected": {
|
433
|
-
textDecoration: "underline"
|
434
|
-
},
|
435
|
-
/**
|
436
|
-
* Link.
|
437
|
-
*/
|
438
|
-
".cm-link": {
|
439
|
-
textDecorationLine: "underline",
|
440
|
-
textDecorationThickness: "1px",
|
441
|
-
textDecorationColor: "var(--dx-separator)",
|
442
|
-
textUnderlineOffset: "2px",
|
443
|
-
borderRadius: ".125rem"
|
444
|
-
},
|
445
|
-
".cm-link > span": {
|
446
|
-
color: "var(--dx-accentText)"
|
447
|
-
},
|
448
|
-
/**
|
449
|
-
* Tooltip.
|
450
|
-
*/
|
451
|
-
".cm-tooltip": {
|
452
|
-
background: "var(--dx-baseSurface)"
|
453
|
-
},
|
454
|
-
".cm-tooltip-below": {},
|
455
|
-
/**
|
456
|
-
* Autocomplete.
|
457
|
-
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
458
|
-
*/
|
459
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
460
|
-
marginTop: "4px",
|
461
|
-
marginLeft: "-3px"
|
462
|
-
},
|
463
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
464
|
-
maxHeight: "20em"
|
465
|
-
},
|
466
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
467
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
468
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
469
|
-
paddingLeft: "4px !important",
|
470
|
-
borderBottom: "none !important",
|
471
|
-
color: "var(--dx-accentText)"
|
472
|
-
},
|
473
|
-
".cm-tooltip.cm-completionInfo": {
|
474
|
-
width: "360px !important",
|
475
|
-
margin: "-10px 1px 0 1px",
|
476
|
-
padding: "8px !important",
|
477
|
-
borderColor: "var(--dx-separator)"
|
478
|
-
},
|
479
|
-
".cm-completionIcon": {
|
480
|
-
display: "none"
|
481
|
-
},
|
482
|
-
".cm-completionLabel": {
|
483
|
-
fontFamily: fontBody
|
484
|
-
},
|
485
|
-
".cm-completionMatchedText": {
|
486
|
-
textDecoration: "none !important",
|
487
|
-
opacity: 0.5
|
488
|
-
},
|
489
|
-
/**
|
490
|
-
* Panels
|
491
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
492
|
-
*
|
493
|
-
* Find/replace panel.
|
494
|
-
* <div class="cm-announced">...</div>
|
495
|
-
* <div class="cm-scroller">...</div>
|
496
|
-
* <div class="cm-panels cm-panels-bottom">
|
497
|
-
* <div class="cm-search cm-panel">
|
498
|
-
* <input class="cm-textfield" />
|
499
|
-
* <button class="cm-button">...</button>
|
500
|
-
* <label><input type="checkbox" />...</label>
|
501
|
-
* </div>
|
502
|
-
* </div
|
503
|
-
*/
|
504
|
-
// TODO(burdon): Implement custom panel (with icon buttons).
|
505
|
-
".cm-panels": {},
|
506
|
-
".cm-panel": {
|
507
|
-
fontFamily: fontBody,
|
508
|
-
backgroundColor: "var(--surface-bg)"
|
509
|
-
},
|
510
|
-
".cm-panel input, .cm-panel button, .cm-panel label": {
|
511
|
-
color: "var(--dx-subdued)",
|
512
|
-
fontFamily: fontBody,
|
513
|
-
fontSize: "14px",
|
514
|
-
all: "unset",
|
515
|
-
margin: "3px !important",
|
516
|
-
padding: "2px 6px !important",
|
517
|
-
outline: "1px solid transparent"
|
518
|
-
},
|
519
|
-
".cm-panel input, .cm-panel button": {
|
520
|
-
backgroundColor: "var(--dx-input)"
|
521
|
-
},
|
522
|
-
".cm-panel input:focus, .cm-panel button:focus": {
|
523
|
-
outline: "1px solid var(--dx-accentFocusIndicator)"
|
524
|
-
},
|
525
|
-
".cm-panel label": {
|
526
|
-
display: "inline-flex",
|
527
|
-
alignItems: "center",
|
528
|
-
cursor: "pointer"
|
529
|
-
},
|
530
|
-
".cm-panel input.cm-textfield": {},
|
531
|
-
".cm-panel input[type=checkbox]": {
|
532
|
-
width: "8px",
|
533
|
-
height: "8px",
|
534
|
-
marginRight: "6px !important",
|
535
|
-
padding: "2px !important",
|
536
|
-
color: "var(--dx-accentFocusIndicator)"
|
537
|
-
},
|
538
|
-
".cm-panel button": {
|
539
|
-
"&:hover": {
|
540
|
-
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
541
|
-
},
|
542
|
-
"&:active": {
|
543
|
-
backgroundColor: "var(--dx-accentSurfaceHover)"
|
544
|
-
}
|
545
|
-
},
|
546
|
-
".cm-panel.cm-search": {
|
547
|
-
padding: "4px",
|
548
|
-
borderTop: "1px solid var(--dx-separator)"
|
549
|
-
}
|
550
|
-
};
|
551
|
-
|
552
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
553
|
-
var margin = "!mt-[1rem]";
|
554
|
-
var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
|
555
|
-
var editorContent = mx2(margin, editorWidth);
|
556
|
-
var editorFullWidth = mx2(margin);
|
557
|
-
var editorGutter = EditorView.theme({
|
558
|
-
// Match margin from content.
|
559
|
-
// Gutter = 2rem + 1rem margin.
|
560
|
-
".cm-gutters": {
|
561
|
-
marginTop: "1rem",
|
562
|
-
paddingRight: "1rem"
|
563
|
-
}
|
564
|
-
});
|
565
|
-
var editorMonospace = EditorView.theme({
|
566
|
-
".cm-content": {
|
567
|
-
fontFamily: fontMono
|
568
|
-
}
|
569
|
-
});
|
570
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
571
|
-
var stackItemContentEditorClassNames = (role) => mx2("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
|
572
|
-
var stackItemContentToolbarClassNames = (role) => mx2("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
|
573
|
-
|
574
|
-
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
575
|
-
var createToolbar = ({ state, customActions, ...features }) => {
|
576
|
-
const nodes = [];
|
577
|
-
const edges = [];
|
578
|
-
if (features.headings ?? true) {
|
579
|
-
const headings2 = createHeadings(state);
|
580
|
-
nodes.push(...headings2.nodes);
|
581
|
-
edges.push(...headings2.edges);
|
582
|
-
}
|
583
|
-
if (features.formatting ?? true) {
|
584
|
-
const formatting = createFormatting(state);
|
585
|
-
nodes.push(...formatting.nodes);
|
586
|
-
edges.push(...formatting.edges);
|
587
|
-
}
|
588
|
-
if (features.lists ?? true) {
|
589
|
-
const lists = createLists(state);
|
590
|
-
nodes.push(...lists.nodes);
|
591
|
-
edges.push(...lists.edges);
|
592
|
-
}
|
593
|
-
if (features.blocks ?? true) {
|
594
|
-
const blocks = createBlocks(state);
|
595
|
-
nodes.push(...blocks.nodes);
|
596
|
-
edges.push(...blocks.edges);
|
597
|
-
}
|
598
|
-
if (customActions) {
|
599
|
-
const custom = customActions();
|
600
|
-
nodes.push(...custom.nodes);
|
601
|
-
edges.push(...custom.edges);
|
602
|
-
}
|
603
|
-
const editorToolbarGap = createGapSeparator();
|
604
|
-
nodes.push(...editorToolbarGap.nodes);
|
605
|
-
edges.push(...editorToolbarGap.edges);
|
606
|
-
if (features.comment ?? true) {
|
607
|
-
const comment = createComment(state);
|
608
|
-
nodes.push(...comment.nodes);
|
609
|
-
edges.push(...comment.edges);
|
610
|
-
}
|
611
|
-
if (features.search ?? true) {
|
612
|
-
nodes.push(editorToolbarSearch);
|
613
|
-
edges.push({
|
614
|
-
source: "root",
|
615
|
-
target: editorToolbarSearch.id
|
616
|
-
});
|
617
|
-
}
|
618
|
-
if (features.viewMode ?? true) {
|
619
|
-
const viewMode = createViewMode(state);
|
620
|
-
nodes.push(...viewMode.nodes);
|
621
|
-
edges.push(...viewMode.edges);
|
622
|
-
}
|
623
|
-
return {
|
624
|
-
nodes,
|
625
|
-
edges
|
626
|
-
};
|
627
|
-
};
|
628
|
-
var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
|
629
|
-
const menuCreator = useCallback(() => createToolbar(props), [
|
630
|
-
props
|
631
|
-
]);
|
632
|
-
const { resolveGroupItems } = useMenuActions(menuCreator);
|
633
|
-
return {
|
634
|
-
resolveGroupItems,
|
635
|
-
onAction
|
636
|
-
};
|
637
|
-
};
|
638
|
-
var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
|
639
|
-
const menuProps = useEditorToolbarActionGraph(props);
|
640
|
-
return /* @__PURE__ */ React.createElement("div", {
|
641
|
-
role: "none",
|
642
|
-
className: stackItemContentToolbarClassNames(role)
|
643
|
-
}, /* @__PURE__ */ React.createElement(ElevationProvider, {
|
644
|
-
elevation: role === "section" ? "positioned" : "base"
|
645
|
-
}, /* @__PURE__ */ React.createElement(MenuProvider, {
|
646
|
-
...menuProps,
|
647
|
-
attendableId
|
648
|
-
}, /* @__PURE__ */ React.createElement(ToolbarMenu, {
|
649
|
-
classNames: [
|
650
|
-
textBlockWidth,
|
651
|
-
"!bg-transparent",
|
652
|
-
classNames
|
653
|
-
]
|
654
|
-
}))));
|
655
|
-
};
|
656
|
-
|
657
|
-
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
658
|
-
import { StateField } from "@codemirror/state";
|
659
|
-
import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
|
660
|
-
import { isNotFalsy } from "@dxos/util";
|
661
|
-
|
662
|
-
// packages/ui/react-ui-editor/src/util/facet.ts
|
663
|
-
import { Facet } from "@codemirror/state";
|
664
|
-
var singleValueFacet = (defaultValue) => Facet.define({
|
665
|
-
// Called immediately.
|
666
|
-
combine: (providers) => {
|
667
|
-
return providers[0] ?? defaultValue;
|
668
|
-
}
|
669
|
-
});
|
670
|
-
|
671
|
-
// packages/ui/react-ui-editor/src/util/cursor.ts
|
672
|
-
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
673
|
-
var defaultCursorConverter = {
|
674
|
-
toCursor: (position) => position.toString(),
|
675
|
-
fromCursor: (cursor) => parseInt(cursor)
|
676
|
-
};
|
677
|
-
var Cursor = class _Cursor {
|
678
|
-
static {
|
679
|
-
this.converter = singleValueFacet(defaultCursorConverter);
|
680
|
-
}
|
681
|
-
static {
|
682
|
-
this.getCursorFromRange = (state, range) => {
|
683
|
-
const cursorConverter2 = state.facet(_Cursor.converter);
|
684
|
-
const from = cursorConverter2.toCursor(range.from);
|
685
|
-
const to = cursorConverter2.toCursor(range.to, -1);
|
686
|
-
return [
|
687
|
-
from,
|
688
|
-
to
|
689
|
-
].join(":");
|
690
|
-
};
|
691
|
-
}
|
692
|
-
static {
|
693
|
-
this.getRangeFromCursor = (state, cursor) => {
|
694
|
-
const cursorConverter2 = state.facet(_Cursor.converter);
|
695
|
-
const parts = cursor.split(":");
|
696
|
-
const from = cursorConverter2.fromCursor(parts[0]);
|
697
|
-
const to = cursorConverter2.fromCursor(parts[1]);
|
698
|
-
return from !== void 0 && to !== void 0 ? {
|
699
|
-
from,
|
700
|
-
to
|
701
|
-
} : void 0;
|
702
|
-
};
|
703
|
-
}
|
704
|
-
};
|
705
|
-
|
706
|
-
// packages/ui/react-ui-editor/src/util/debug.ts
|
707
|
-
import { log } from "@dxos/log";
|
708
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
709
|
-
var wrapWithCatch = (fn) => {
|
710
|
-
return (...args) => {
|
711
|
-
try {
|
712
|
-
return fn(...args);
|
713
|
-
} catch (err) {
|
714
|
-
log.catch(err, void 0, {
|
715
|
-
F: __dxlog_file,
|
716
|
-
L: 15,
|
717
|
-
S: void 0,
|
718
|
-
C: (f, a) => f(...a)
|
719
|
-
});
|
720
|
-
}
|
721
|
-
};
|
722
|
-
};
|
723
|
-
var callbackWrapper = (fn) => (...args) => {
|
724
|
-
try {
|
725
|
-
return fn(...args);
|
726
|
-
} catch (err) {
|
727
|
-
log.catch(err, void 0, {
|
728
|
-
F: __dxlog_file,
|
729
|
-
L: 29,
|
730
|
-
S: void 0,
|
731
|
-
C: (f, a) => f(...a)
|
732
|
-
});
|
733
|
-
}
|
734
|
-
};
|
735
|
-
var debugDispatcher = (trs, view) => {
|
736
|
-
logChanges(trs);
|
737
|
-
view.update(trs);
|
738
|
-
};
|
739
|
-
var logChanges = (trs) => {
|
740
|
-
const changes = trs.flatMap((tr) => {
|
741
|
-
if (tr.changes.empty) {
|
742
|
-
return void 0;
|
157
|
+
var logChanges = (trs) => {
|
158
|
+
const changes = trs.flatMap((tr) => {
|
159
|
+
if (tr.changes.empty) {
|
160
|
+
return void 0;
|
743
161
|
}
|
744
162
|
const changes2 = [];
|
745
163
|
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
|
@@ -791,7 +209,7 @@ var clientRectsFor = (dom) => {
|
|
791
209
|
};
|
792
210
|
|
793
211
|
// packages/ui/react-ui-editor/src/util/react.tsx
|
794
|
-
import
|
212
|
+
import React from "react";
|
795
213
|
import { createRoot } from "react-dom/client";
|
796
214
|
import { ThemeProvider, Tooltip } from "@dxos/react-ui";
|
797
215
|
import { defaultTx } from "@dxos/react-ui-theme";
|
@@ -808,15 +226,15 @@ var createElement = (tag, options, children) => {
|
|
808
226
|
return el;
|
809
227
|
};
|
810
228
|
var renderRoot = (root, node) => {
|
811
|
-
createRoot(root).render(/* @__PURE__ */
|
229
|
+
createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
|
812
230
|
tx: defaultTx
|
813
231
|
}, node));
|
814
232
|
return root;
|
815
233
|
};
|
816
234
|
var createRenderer = (Component) => (el, props) => {
|
817
|
-
renderRoot(el, /* @__PURE__ */
|
235
|
+
renderRoot(el, /* @__PURE__ */ React.createElement(ThemeProvider, {
|
818
236
|
tx: defaultTx
|
819
|
-
}, /* @__PURE__ */
|
237
|
+
}, /* @__PURE__ */ React.createElement(Tooltip.Provider, null, /* @__PURE__ */ React.createElement(Component, props))));
|
820
238
|
};
|
821
239
|
|
822
240
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
@@ -856,7 +274,7 @@ var annotations = (options = {}) => {
|
|
856
274
|
});
|
857
275
|
return [
|
858
276
|
annotationsState,
|
859
|
-
|
277
|
+
EditorView.decorations.compute([
|
860
278
|
annotationsState
|
861
279
|
], (state) => {
|
862
280
|
const annotations2 = state.field(annotationsState);
|
@@ -869,7 +287,7 @@ var annotations = (options = {}) => {
|
|
869
287
|
styles
|
870
288
|
];
|
871
289
|
};
|
872
|
-
var styles =
|
290
|
+
var styles = EditorView.theme({
|
873
291
|
".cm-annotation": {
|
874
292
|
textDecoration: "underline",
|
875
293
|
textDecorationStyle: "wavy",
|
@@ -918,7 +336,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
|
918
336
|
|
919
337
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
920
338
|
import { StateField as StateField2 } from "@codemirror/state";
|
921
|
-
import { EditorView as
|
339
|
+
import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
|
922
340
|
import { next as A3 } from "@dxos/automerge/automerge";
|
923
341
|
|
924
342
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
@@ -1202,7 +620,7 @@ var automerge = (accessor) => {
|
|
1202
620
|
}
|
1203
621
|
}),
|
1204
622
|
// Reconcile local updates.
|
1205
|
-
|
623
|
+
EditorView2.updateListener.of(({ view, changes }) => {
|
1206
624
|
if (!changes.empty) {
|
1207
625
|
syncer.reconcile(view, true);
|
1208
626
|
}
|
@@ -1212,7 +630,7 @@ var automerge = (accessor) => {
|
|
1212
630
|
|
1213
631
|
// packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
|
1214
632
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
1215
|
-
import { Decoration as Decoration2, EditorView as
|
633
|
+
import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
1216
634
|
import { Event } from "@dxos/async";
|
1217
635
|
import { Context } from "@dxos/context";
|
1218
636
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
|
@@ -1386,7 +804,7 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
1386
804
|
return true;
|
1387
805
|
}
|
1388
806
|
};
|
1389
|
-
var styles2 =
|
807
|
+
var styles2 = EditorView3.theme({
|
1390
808
|
".cm-collab-selection": {},
|
1391
809
|
".cm-collab-selectionLine": {
|
1392
810
|
padding: 0,
|
@@ -1552,7 +970,7 @@ var SpaceAwarenessProvider = class {
|
|
1552
970
|
};
|
1553
971
|
|
1554
972
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
1555
|
-
import { EditorView as
|
973
|
+
import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
|
1556
974
|
import defaultsDeep from "lodash.defaultsdeep";
|
1557
975
|
import { invariant as invariant2 } from "@dxos/invariant";
|
1558
976
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
@@ -1600,7 +1018,7 @@ var blast = (options = defaultOptions) => {
|
|
1600
1018
|
};
|
1601
1019
|
return [
|
1602
1020
|
// Cursor moved.
|
1603
|
-
|
1021
|
+
EditorView4.updateListener.of((update2) => {
|
1604
1022
|
if (blaster?.node !== update2.view.scrollDOM) {
|
1605
1023
|
if (blaster) {
|
1606
1024
|
blaster.destroy();
|
@@ -1974,11 +1392,11 @@ var commandKeyBindings = [
|
|
1974
1392
|
];
|
1975
1393
|
|
1976
1394
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
1977
|
-
import { EditorView as
|
1395
|
+
import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
|
1978
1396
|
|
1979
1397
|
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
1980
1398
|
import { RangeSetBuilder } from "@codemirror/state";
|
1981
|
-
import { Decoration as Decoration3, EditorView as
|
1399
|
+
import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
1982
1400
|
var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
1983
1401
|
constructor() {
|
1984
1402
|
this.deco = Decoration3.none;
|
@@ -2002,7 +1420,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
2002
1420
|
}
|
2003
1421
|
}, {
|
2004
1422
|
provide: (plugin) => [
|
2005
|
-
|
1423
|
+
EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
2006
1424
|
]
|
2007
1425
|
});
|
2008
1426
|
var CommandHint = class extends WidgetType2 {
|
@@ -2121,10 +1539,10 @@ var command = (options = {}) => {
|
|
2121
1539
|
options.onHint ? hintViewPlugin({
|
2122
1540
|
onHint: options.onHint
|
2123
1541
|
}) : [],
|
2124
|
-
|
1542
|
+
EditorView6.focusChangeEffect.of((_, focusing) => {
|
2125
1543
|
return focusing ? closeEffect.of(null) : null;
|
2126
1544
|
}),
|
2127
|
-
|
1545
|
+
EditorView6.theme({
|
2128
1546
|
".cm-tooltip": {
|
2129
1547
|
background: "transparent"
|
2130
1548
|
}
|
@@ -2135,7 +1553,7 @@ var command = (options = {}) => {
|
|
2135
1553
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
2136
1554
|
import { invertedEffects } from "@codemirror/commands";
|
2137
1555
|
import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
2138
|
-
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as
|
1556
|
+
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
2139
1557
|
import sortBy from "lodash.sortby";
|
2140
1558
|
import { useEffect, useMemo as useMemo2 } from "react";
|
2141
1559
|
import { debounce as debounce2 } from "@dxos/async";
|
@@ -2144,7 +1562,7 @@ import { isNonNullable } from "@dxos/util";
|
|
2144
1562
|
|
2145
1563
|
// packages/ui/react-ui-editor/src/extensions/selection.ts
|
2146
1564
|
import { Transaction } from "@codemirror/state";
|
2147
|
-
import { EditorView as
|
1565
|
+
import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
|
2148
1566
|
import { debounce } from "@dxos/async";
|
2149
1567
|
import { invariant as invariant3 } from "@dxos/invariant";
|
2150
1568
|
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
@@ -2155,7 +1573,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
2155
1573
|
return {
|
2156
1574
|
selection,
|
2157
1575
|
scrollIntoView: !scrollTo,
|
2158
|
-
effects: scrollTo ?
|
1576
|
+
effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
|
2159
1577
|
yMargin: 96
|
2160
1578
|
}) : void 0,
|
2161
1579
|
annotations: Transaction.userEvent.of(stateRestoreAnnotation)
|
@@ -2197,7 +1615,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
2197
1615
|
// setStateDebounced(id, {});
|
2198
1616
|
// },
|
2199
1617
|
// }),
|
2200
|
-
|
1618
|
+
EditorView7.updateListener.of(({ view, transactions }) => {
|
2201
1619
|
const id = view.state.facet(documentId);
|
2202
1620
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
2203
1621
|
return;
|
@@ -2278,7 +1696,7 @@ var commentsState = StateField4.define({
|
|
2278
1696
|
return value;
|
2279
1697
|
}
|
2280
1698
|
});
|
2281
|
-
var styles3 =
|
1699
|
+
var styles3 = EditorView8.theme({
|
2282
1700
|
".cm-comment, .cm-comment-current": {
|
2283
1701
|
margin: "0 -3px",
|
2284
1702
|
padding: "3px",
|
@@ -2298,7 +1716,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
|
|
2298
1716
|
"data-comment-id": id
|
2299
1717
|
}
|
2300
1718
|
});
|
2301
|
-
var commentsDecorations =
|
1719
|
+
var commentsDecorations = EditorView8.decorations.compute([
|
2302
1720
|
commentsState
|
2303
1721
|
], (state) => {
|
2304
1722
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
@@ -2321,7 +1739,7 @@ var commentsDecorations = EditorView9.decorations.compute([
|
|
2321
1739
|
return Decoration4.set(decorations);
|
2322
1740
|
});
|
2323
1741
|
var commentClickedEffect = StateEffect3.define();
|
2324
|
-
var handleCommentClick =
|
1742
|
+
var handleCommentClick = EditorView8.domEventHandlers({
|
2325
1743
|
click: (event, view) => {
|
2326
1744
|
let target = event.target;
|
2327
1745
|
const editorRoot = view.dom;
|
@@ -2360,7 +1778,7 @@ var trackPastedComments = (onUpdate) => {
|
|
2360
1778
|
}
|
2361
1779
|
};
|
2362
1780
|
return [
|
2363
|
-
|
1781
|
+
EditorView8.domEventHandlers({
|
2364
1782
|
cut: handleTrack,
|
2365
1783
|
copy: handleTrack
|
2366
1784
|
}),
|
@@ -2382,7 +1800,7 @@ var trackPastedComments = (onUpdate) => {
|
|
2382
1800
|
return effects;
|
2383
1801
|
}),
|
2384
1802
|
// Handle paste or the undo of comment deletion.
|
2385
|
-
|
1803
|
+
EditorView8.updateListener.of((update2) => {
|
2386
1804
|
const restore = [];
|
2387
1805
|
for (let i = 0; i < update2.transactions.length; i++) {
|
2388
1806
|
const tr = update2.transactions[i];
|
@@ -2441,7 +1859,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
2441
1859
|
var restoreCommentEffect = StateEffect3.define({
|
2442
1860
|
map: mapTrackedComment
|
2443
1861
|
});
|
2444
|
-
var
|
1862
|
+
var createComment = (view) => {
|
2445
1863
|
const options = view.state.facet(optionsFacet);
|
2446
1864
|
const { from, to } = view.state.selection.main;
|
2447
1865
|
if (from === to) {
|
@@ -2486,7 +1904,7 @@ var comments = (options = {}) => {
|
|
2486
1904
|
options.onCreate && keymap5.of([
|
2487
1905
|
{
|
2488
1906
|
key: shortcut,
|
2489
|
-
run: callbackWrapper(
|
1907
|
+
run: callbackWrapper(createComment)
|
2490
1908
|
}
|
2491
1909
|
]),
|
2492
1910
|
//
|
@@ -2524,7 +1942,7 @@ var comments = (options = {}) => {
|
|
2524
1942
|
//
|
2525
1943
|
// Track deleted ranges and update ranges for decorations.
|
2526
1944
|
//
|
2527
|
-
|
1945
|
+
EditorView8.updateListener.of(({ view, state, changes }) => {
|
2528
1946
|
let mod = false;
|
2529
1947
|
const { comments: comments2, ...value } = state.field(commentsState);
|
2530
1948
|
changes.iterChanges((from, to, from2, to2) => {
|
@@ -2556,7 +1974,7 @@ var comments = (options = {}) => {
|
|
2556
1974
|
//
|
2557
1975
|
// Track selection/proximity.
|
2558
1976
|
//
|
2559
|
-
|
1977
|
+
EditorView8.updateListener.of(({ view, state }) => {
|
2560
1978
|
let min = Infinity;
|
2561
1979
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
2562
1980
|
const { head } = state.selection.main;
|
@@ -2610,7 +2028,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
2610
2028
|
anchor: range.from
|
2611
2029
|
} : void 0,
|
2612
2030
|
effects: [
|
2613
|
-
needsScroll ?
|
2031
|
+
needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
|
2614
2032
|
y: "center"
|
2615
2033
|
} : void 0) : [],
|
2616
2034
|
needsSelectionUpdate ? setSelection.of({
|
@@ -2662,7 +2080,7 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.from
|
|
2662
2080
|
}
|
2663
2081
|
});
|
2664
2082
|
var useCommentState = (state) => {
|
2665
|
-
return useMemo2(() =>
|
2083
|
+
return useMemo2(() => EditorView8.updateListener.of((update2) => {
|
2666
2084
|
if (update2.docChanged || update2.selectionSet) {
|
2667
2085
|
state.comment = selectionOverlapsComment(update2.state);
|
2668
2086
|
state.selection = hasActiveSelection(update2.state);
|
@@ -2686,7 +2104,7 @@ var useComments = (view, id, comments2) => {
|
|
2686
2104
|
});
|
2687
2105
|
};
|
2688
2106
|
var useCommentClickListener = (onCommentClick) => {
|
2689
|
-
return useMemo2(() =>
|
2107
|
+
return useMemo2(() => EditorView8.updateListener.of((update2) => {
|
2690
2108
|
update2.transactions.forEach((transaction) => {
|
2691
2109
|
transaction.effects.forEach((effect) => {
|
2692
2110
|
if (effect.is(commentClickedEffect)) {
|
@@ -2713,8 +2131,8 @@ var debugNodeLogger = (log8 = console.log) => {
|
|
2713
2131
|
};
|
2714
2132
|
|
2715
2133
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2716
|
-
import { dropCursor, EditorView as
|
2717
|
-
var styles4 =
|
2134
|
+
import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
|
2135
|
+
var styles4 = EditorView9.theme({
|
2718
2136
|
".cm-dropCursor": {
|
2719
2137
|
borderLeft: "2px solid var(--dx-accentText)",
|
2720
2138
|
color: "var(--dx-accentText)",
|
@@ -2728,7 +2146,7 @@ var dropFile = (options = {}) => {
|
|
2728
2146
|
return [
|
2729
2147
|
styles4,
|
2730
2148
|
dropCursor(),
|
2731
|
-
|
2149
|
+
EditorView9.domEventHandlers({
|
2732
2150
|
drop: (event, view) => {
|
2733
2151
|
event.preventDefault();
|
2734
2152
|
const files = event.dataTransfer?.files;
|
@@ -2755,7 +2173,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
|
|
2755
2173
|
import { searchKeymap } from "@codemirror/search";
|
2756
2174
|
import { EditorState } from "@codemirror/state";
|
2757
2175
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2758
|
-
import { EditorView as
|
2176
|
+
import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2759
2177
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
2760
2178
|
import merge from "lodash.merge";
|
2761
2179
|
import { generateName } from "@dxos/display-name";
|
@@ -2764,7 +2182,7 @@ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
2764
2182
|
|
2765
2183
|
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2766
2184
|
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2767
|
-
import { EditorView as
|
2185
|
+
import { EditorView as EditorView10 } from "@codemirror/view";
|
2768
2186
|
var focusEffect = StateEffect4.define();
|
2769
2187
|
var focusField = StateField6.define({
|
2770
2188
|
create: () => false,
|
@@ -2779,7 +2197,7 @@ var focusField = StateField6.define({
|
|
2779
2197
|
});
|
2780
2198
|
var focus = [
|
2781
2199
|
focusField,
|
2782
|
-
|
2200
|
+
EditorView10.domEventHandlers({
|
2783
2201
|
focus: (event, view) => {
|
2784
2202
|
setTimeout(() => view.dispatch({
|
2785
2203
|
effects: focusEffect.of(true)
|
@@ -2793,6 +2211,238 @@ var focus = [
|
|
2793
2211
|
})
|
2794
2212
|
];
|
2795
2213
|
|
2214
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
2215
|
+
import { mx } from "@dxos/react-ui-theme";
|
2216
|
+
var headings = {
|
2217
|
+
1: "text-4xl",
|
2218
|
+
2: "text-3xl",
|
2219
|
+
3: "text-2xl",
|
2220
|
+
4: "text-xl",
|
2221
|
+
5: "text-lg",
|
2222
|
+
6: ""
|
2223
|
+
};
|
2224
|
+
var theme = {
|
2225
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
2226
|
+
codeMark: "font-mono text-primary-500",
|
2227
|
+
mark: "opacity-50",
|
2228
|
+
heading: (level) => {
|
2229
|
+
return mx(headings[level], "dark:text-primary-400");
|
2230
|
+
}
|
2231
|
+
};
|
2232
|
+
|
2233
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
2234
|
+
import get from "lodash.get";
|
2235
|
+
import { tokens } from "@dxos/react-ui-theme";
|
2236
|
+
var getToken = (path, defaultValue) => {
|
2237
|
+
const value = get(tokens, path, defaultValue);
|
2238
|
+
return value?.toString() ?? "";
|
2239
|
+
};
|
2240
|
+
var fontBody = getToken("fontFamily.body");
|
2241
|
+
var fontMono = getToken("fontFamily.mono");
|
2242
|
+
|
2243
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
2244
|
+
var defaultTheme = {
|
2245
|
+
"&": {},
|
2246
|
+
"&.cm-focused": {
|
2247
|
+
outline: "none"
|
2248
|
+
},
|
2249
|
+
/**
|
2250
|
+
* Scroller
|
2251
|
+
*/
|
2252
|
+
".cm-scroller": {
|
2253
|
+
overflowY: "auto"
|
2254
|
+
},
|
2255
|
+
/**
|
2256
|
+
* Content
|
2257
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
2258
|
+
*/
|
2259
|
+
".cm-content": {
|
2260
|
+
padding: "unset",
|
2261
|
+
fontFamily: fontBody,
|
2262
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
2263
|
+
fontSize: "16px",
|
2264
|
+
lineHeight: 1.5,
|
2265
|
+
color: "unset"
|
2266
|
+
},
|
2267
|
+
/**
|
2268
|
+
* Gutters
|
2269
|
+
* NOTE: Gutters should have the same top margin as the content.
|
2270
|
+
*/
|
2271
|
+
".cm-gutters": {
|
2272
|
+
borderRight: "none",
|
2273
|
+
background: "transparent"
|
2274
|
+
},
|
2275
|
+
".cm-gutter": {},
|
2276
|
+
".cm-gutter.cm-lineNumbers": {
|
2277
|
+
paddingRight: "4px",
|
2278
|
+
borderRight: "1px solid var(--dx-separator)"
|
2279
|
+
},
|
2280
|
+
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
2281
|
+
minWidth: "40px",
|
2282
|
+
alignContent: "center"
|
2283
|
+
},
|
2284
|
+
/**
|
2285
|
+
* Height is set to match the corresponding line.
|
2286
|
+
*/
|
2287
|
+
".cm-gutterElement": {
|
2288
|
+
alignItems: "center",
|
2289
|
+
fontSize: "12px"
|
2290
|
+
},
|
2291
|
+
/**
|
2292
|
+
* Line.
|
2293
|
+
*/
|
2294
|
+
".cm-line": {
|
2295
|
+
paddingInline: 0
|
2296
|
+
},
|
2297
|
+
".cm-activeLine": {
|
2298
|
+
background: "var(--dx-cmActiveLine)"
|
2299
|
+
},
|
2300
|
+
/**
|
2301
|
+
* Cursor (layer).
|
2302
|
+
*/
|
2303
|
+
".cm-cursor, .cm-dropCursor": {
|
2304
|
+
borderLeft: "2px solid var(--dx-cmCursor)"
|
2305
|
+
},
|
2306
|
+
".cm-placeholder": {
|
2307
|
+
color: "var(--dx-subdued)"
|
2308
|
+
},
|
2309
|
+
/**
|
2310
|
+
* Selection (layer).
|
2311
|
+
*/
|
2312
|
+
".cm-selectionBackground": {
|
2313
|
+
background: "var(--dx-cmSelection)"
|
2314
|
+
},
|
2315
|
+
/**
|
2316
|
+
* Search.
|
2317
|
+
* NOTE: Matches comment.
|
2318
|
+
*/
|
2319
|
+
".cm-searchMatch": {
|
2320
|
+
margin: "0 -3px",
|
2321
|
+
padding: "3px",
|
2322
|
+
borderRadius: "3px",
|
2323
|
+
background: "var(--dx-cmHighlightSurface)",
|
2324
|
+
color: "var(--dx-cmHighlight)"
|
2325
|
+
},
|
2326
|
+
".cm-searchMatch-selected": {
|
2327
|
+
textDecoration: "underline"
|
2328
|
+
},
|
2329
|
+
/**
|
2330
|
+
* Link.
|
2331
|
+
*/
|
2332
|
+
".cm-link": {
|
2333
|
+
textDecorationLine: "underline",
|
2334
|
+
textDecorationThickness: "1px",
|
2335
|
+
textDecorationColor: "var(--dx-separator)",
|
2336
|
+
textUnderlineOffset: "2px",
|
2337
|
+
borderRadius: ".125rem"
|
2338
|
+
},
|
2339
|
+
".cm-link > span": {
|
2340
|
+
color: "var(--dx-accentText)"
|
2341
|
+
},
|
2342
|
+
/**
|
2343
|
+
* Tooltip.
|
2344
|
+
*/
|
2345
|
+
".cm-tooltip": {
|
2346
|
+
background: "var(--dx-baseSurface)"
|
2347
|
+
},
|
2348
|
+
".cm-tooltip-below": {},
|
2349
|
+
/**
|
2350
|
+
* Autocomplete.
|
2351
|
+
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
2352
|
+
*/
|
2353
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
2354
|
+
marginTop: "4px",
|
2355
|
+
marginLeft: "-3px"
|
2356
|
+
},
|
2357
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
2358
|
+
maxHeight: "20em"
|
2359
|
+
},
|
2360
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
2361
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
2362
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
2363
|
+
paddingLeft: "4px !important",
|
2364
|
+
borderBottom: "none !important",
|
2365
|
+
color: "var(--dx-accentText)"
|
2366
|
+
},
|
2367
|
+
".cm-tooltip.cm-completionInfo": {
|
2368
|
+
width: "360px !important",
|
2369
|
+
margin: "-10px 1px 0 1px",
|
2370
|
+
padding: "8px !important",
|
2371
|
+
borderColor: "var(--dx-separator)"
|
2372
|
+
},
|
2373
|
+
".cm-completionIcon": {
|
2374
|
+
display: "none"
|
2375
|
+
},
|
2376
|
+
".cm-completionLabel": {
|
2377
|
+
fontFamily: fontBody
|
2378
|
+
},
|
2379
|
+
".cm-completionMatchedText": {
|
2380
|
+
textDecoration: "none !important",
|
2381
|
+
opacity: 0.5
|
2382
|
+
},
|
2383
|
+
/**
|
2384
|
+
* Panels
|
2385
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
2386
|
+
*
|
2387
|
+
* Find/replace panel.
|
2388
|
+
* <div class="cm-announced">...</div>
|
2389
|
+
* <div class="cm-scroller">...</div>
|
2390
|
+
* <div class="cm-panels cm-panels-bottom">
|
2391
|
+
* <div class="cm-search cm-panel">
|
2392
|
+
* <input class="cm-textfield" />
|
2393
|
+
* <button class="cm-button">...</button>
|
2394
|
+
* <label><input type="checkbox" />...</label>
|
2395
|
+
* </div>
|
2396
|
+
* </div
|
2397
|
+
*/
|
2398
|
+
// TODO(burdon): Implement custom panel (with icon buttons).
|
2399
|
+
".cm-panels": {},
|
2400
|
+
".cm-panel": {
|
2401
|
+
fontFamily: fontBody,
|
2402
|
+
backgroundColor: "var(--surface-bg)"
|
2403
|
+
},
|
2404
|
+
".cm-panel input, .cm-panel button, .cm-panel label": {
|
2405
|
+
color: "var(--dx-subdued)",
|
2406
|
+
fontFamily: fontBody,
|
2407
|
+
fontSize: "14px",
|
2408
|
+
all: "unset",
|
2409
|
+
margin: "3px !important",
|
2410
|
+
padding: "2px 6px !important",
|
2411
|
+
outline: "1px solid transparent"
|
2412
|
+
},
|
2413
|
+
".cm-panel input, .cm-panel button": {
|
2414
|
+
backgroundColor: "var(--dx-input)"
|
2415
|
+
},
|
2416
|
+
".cm-panel input:focus, .cm-panel button:focus": {
|
2417
|
+
outline: "1px solid var(--dx-accentFocusIndicator)"
|
2418
|
+
},
|
2419
|
+
".cm-panel label": {
|
2420
|
+
display: "inline-flex",
|
2421
|
+
alignItems: "center",
|
2422
|
+
cursor: "pointer"
|
2423
|
+
},
|
2424
|
+
".cm-panel input.cm-textfield": {},
|
2425
|
+
".cm-panel input[type=checkbox]": {
|
2426
|
+
width: "8px",
|
2427
|
+
height: "8px",
|
2428
|
+
marginRight: "6px !important",
|
2429
|
+
padding: "2px !important",
|
2430
|
+
color: "var(--dx-accentFocusIndicator)"
|
2431
|
+
},
|
2432
|
+
".cm-panel button": {
|
2433
|
+
"&:hover": {
|
2434
|
+
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
2435
|
+
},
|
2436
|
+
"&:active": {
|
2437
|
+
backgroundColor: "var(--dx-accentSurfaceHover)"
|
2438
|
+
}
|
2439
|
+
},
|
2440
|
+
".cm-panel.cm-search": {
|
2441
|
+
padding: "4px",
|
2442
|
+
borderTop: "1px solid var(--dx-separator)"
|
2443
|
+
}
|
2444
|
+
};
|
2445
|
+
|
2796
2446
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2797
2447
|
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
2798
2448
|
var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
|
@@ -2817,7 +2467,7 @@ var createBasicExtensions = (_props) => {
|
|
2817
2467
|
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
2818
2468
|
return [
|
2819
2469
|
// NOTE: Doesn't catch errors in keymap functions.
|
2820
|
-
|
2470
|
+
EditorView11.exceptionSink.of((err) => {
|
2821
2471
|
log5.catch(err, void 0, {
|
2822
2472
|
F: __dxlog_file8,
|
2823
2473
|
L: 96,
|
@@ -2832,12 +2482,12 @@ var createBasicExtensions = (_props) => {
|
|
2832
2482
|
props.drawSelection && drawSelection({
|
2833
2483
|
cursorBlinkRate: 1200
|
2834
2484
|
}),
|
2835
|
-
props.editable !== void 0 &&
|
2485
|
+
props.editable !== void 0 && EditorView11.editable.of(props.editable),
|
2836
2486
|
props.focus && focus,
|
2837
2487
|
props.highlightActiveLine && highlightActiveLine(),
|
2838
2488
|
props.history && history(),
|
2839
2489
|
props.lineNumbers && lineNumbers(),
|
2840
|
-
props.lineWrapping &&
|
2490
|
+
props.lineWrapping && EditorView11.lineWrapping,
|
2841
2491
|
props.placeholder && placeholder(props.placeholder),
|
2842
2492
|
props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
|
2843
2493
|
props.scrollPastEnd && scrollPastEnd(),
|
@@ -2874,14 +2524,14 @@ var defaultThemeSlots = {
|
|
2874
2524
|
var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
|
2875
2525
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
2876
2526
|
return [
|
2877
|
-
|
2878
|
-
|
2527
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
2528
|
+
EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
|
2879
2529
|
// https://github.com/codemirror/theme-one-dark
|
2880
2530
|
_syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
|
2881
|
-
slots.editor?.className &&
|
2531
|
+
slots.editor?.className && EditorView11.editorAttributes.of({
|
2882
2532
|
class: slots.editor.className
|
2883
2533
|
}),
|
2884
|
-
slots.content?.className &&
|
2534
|
+
slots.content?.className && EditorView11.contentAttributes.of({
|
2885
2535
|
class: slots.content.className
|
2886
2536
|
})
|
2887
2537
|
].filter(isNotFalsy3);
|
@@ -2910,8 +2560,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2910
2560
|
|
2911
2561
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
2912
2562
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
2913
|
-
import { EditorView as
|
2914
|
-
import
|
2563
|
+
import { EditorView as EditorView12 } from "@codemirror/view";
|
2564
|
+
import React2 from "react";
|
2915
2565
|
import { Icon } from "@dxos/react-ui";
|
2916
2566
|
var folding = (_props = {}) => [
|
2917
2567
|
codeFolding({
|
@@ -2924,7 +2574,7 @@ var folding = (_props = {}) => [
|
|
2924
2574
|
const el = createElement("div", {
|
2925
2575
|
className: "flex h-full items-center"
|
2926
2576
|
});
|
2927
|
-
return renderRoot(el, /* @__PURE__ */
|
2577
|
+
return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
|
2928
2578
|
icon: "ph--caret-right--bold",
|
2929
2579
|
size: 3,
|
2930
2580
|
classNames: [
|
@@ -2934,7 +2584,7 @@ var folding = (_props = {}) => [
|
|
2934
2584
|
}));
|
2935
2585
|
}
|
2936
2586
|
}),
|
2937
|
-
|
2587
|
+
EditorView12.theme({
|
2938
2588
|
".cm-foldGutter": {
|
2939
2589
|
opacity: 0.3,
|
2940
2590
|
transition: "opacity 0.3s",
|
@@ -2947,14 +2597,14 @@ var folding = (_props = {}) => [
|
|
2947
2597
|
];
|
2948
2598
|
|
2949
2599
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
2950
|
-
import { EditorView as
|
2600
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
2951
2601
|
var listener = ({ onFocus, onChange }) => {
|
2952
2602
|
const extensions = [];
|
2953
|
-
onFocus && extensions.push(
|
2603
|
+
onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
|
2954
2604
|
onFocus(focusing);
|
2955
2605
|
return null;
|
2956
2606
|
}));
|
2957
|
-
onChange && extensions.push(
|
2607
|
+
onChange && extensions.push(EditorView13.updateListener.of((update2) => {
|
2958
2608
|
onChange(update2.state.doc.toString(), update2.state.facet(documentId));
|
2959
2609
|
}));
|
2960
2610
|
return extensions;
|
@@ -2964,7 +2614,7 @@ var listener = ({ onFocus, onChange }) => {
|
|
2964
2614
|
import { snippet } from "@codemirror/autocomplete";
|
2965
2615
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
2966
2616
|
import { EditorSelection } from "@codemirror/state";
|
2967
|
-
import { EditorView as
|
2617
|
+
import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
|
2968
2618
|
import { useMemo as useMemo3 } from "react";
|
2969
2619
|
var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
2970
2620
|
var Inline;
|
@@ -4053,7 +3703,7 @@ var getFormatting = (state) => {
|
|
4053
3703
|
};
|
4054
3704
|
};
|
4055
3705
|
var useFormattingState = (state) => {
|
4056
|
-
return useMemo3(() =>
|
3706
|
+
return useMemo3(() => EditorView14.updateListener.of((update2) => {
|
4057
3707
|
if (update2.docChanged || update2.selectionSet) {
|
4058
3708
|
Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
|
4059
3709
|
state[key] = active;
|
@@ -4101,7 +3751,7 @@ var processEditorPayload = (view, { type, data }) => {
|
|
4101
3751
|
})(view);
|
4102
3752
|
break;
|
4103
3753
|
case "comment":
|
4104
|
-
|
3754
|
+
createComment(view);
|
4105
3755
|
break;
|
4106
3756
|
}
|
4107
3757
|
requestAnimationFrame(() => {
|
@@ -4365,9 +4015,9 @@ var convertTreeToJson = (state) => {
|
|
4365
4015
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
4366
4016
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
4367
4017
|
import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
|
4368
|
-
import { EditorView as
|
4018
|
+
import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
|
4369
4019
|
import { invariant as invariant4 } from "@dxos/invariant";
|
4370
|
-
import { mx as
|
4020
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
4371
4021
|
|
4372
4022
|
// packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
|
4373
4023
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
@@ -4516,7 +4166,7 @@ var getValidUrl = (str) => {
|
|
4516
4166
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
4517
4167
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
4518
4168
|
import { StateField as StateField8 } from "@codemirror/state";
|
4519
|
-
import { Decoration as Decoration5, EditorView as
|
4169
|
+
import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
|
4520
4170
|
var image = (_options = {}) => {
|
4521
4171
|
return [
|
4522
4172
|
StateField8.define({
|
@@ -4544,7 +4194,7 @@ var image = (_options = {}) => {
|
|
4544
4194
|
add: buildDecorations(from, to, tr.state)
|
4545
4195
|
});
|
4546
4196
|
},
|
4547
|
-
provide: (field) =>
|
4197
|
+
provide: (field) => EditorView15.decorations.from(field)
|
4548
4198
|
})
|
4549
4199
|
];
|
4550
4200
|
};
|
@@ -4604,10 +4254,10 @@ var ImageWidget = class extends WidgetType3 {
|
|
4604
4254
|
};
|
4605
4255
|
|
4606
4256
|
// packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
|
4607
|
-
import { EditorView as
|
4257
|
+
import { EditorView as EditorView16 } from "@codemirror/view";
|
4608
4258
|
var bulletListIndentationWidth = 24;
|
4609
4259
|
var orderedListIndentationWidth = 36;
|
4610
|
-
var formattingStyles =
|
4260
|
+
var formattingStyles = EditorView16.theme({
|
4611
4261
|
/**
|
4612
4262
|
* Horizontal rule.
|
4613
4263
|
*/
|
@@ -4728,12 +4378,12 @@ var formattingStyles = EditorView17.theme({
|
|
4728
4378
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
4729
4379
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
4730
4380
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
|
4731
|
-
import { Decoration as Decoration6, EditorView as
|
4381
|
+
import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
|
4732
4382
|
var table = (options = {}) => {
|
4733
4383
|
return StateField9.define({
|
4734
4384
|
create: (state) => update(state, options),
|
4735
4385
|
update: (_, tr) => update(tr.state, options),
|
4736
|
-
provide: (field) =>
|
4386
|
+
provide: (field) => EditorView17.decorations.from(field)
|
4737
4387
|
});
|
4738
4388
|
};
|
4739
4389
|
var update = (state, _options) => {
|
@@ -4919,16 +4569,16 @@ var TextWidget = class extends WidgetType5 {
|
|
4919
4569
|
};
|
4920
4570
|
var hide = Decoration7.replace({});
|
4921
4571
|
var blockQuote = Decoration7.line({
|
4922
|
-
class:
|
4572
|
+
class: mx2("cm-blockquote")
|
4923
4573
|
});
|
4924
4574
|
var fencedCodeLine = Decoration7.line({
|
4925
|
-
class:
|
4575
|
+
class: mx2("cm-code cm-codeblock-line")
|
4926
4576
|
});
|
4927
4577
|
var fencedCodeLineFirst = Decoration7.line({
|
4928
|
-
class:
|
4578
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
4929
4579
|
});
|
4930
4580
|
var fencedCodeLineLast = Decoration7.line({
|
4931
|
-
class:
|
4581
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
4932
4582
|
});
|
4933
4583
|
var commentBlockLine = fencedCodeLine;
|
4934
4584
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
@@ -5226,419 +4876,838 @@ var buildDecorations2 = (view, options, focus2) => {
|
|
5226
4876
|
leave: wrapWithCatch(leaveNode)
|
5227
4877
|
});
|
5228
4878
|
}
|
5229
|
-
} else {
|
5230
|
-
tree.iterate({
|
5231
|
-
enter: wrapWithCatch(enterNode),
|
5232
|
-
leave: wrapWithCatch(leaveNode)
|
5233
|
-
});
|
4879
|
+
} else {
|
4880
|
+
tree.iterate({
|
4881
|
+
enter: wrapWithCatch(enterNode),
|
4882
|
+
leave: wrapWithCatch(leaveNode)
|
4883
|
+
});
|
4884
|
+
}
|
4885
|
+
return {
|
4886
|
+
deco: deco.finish(),
|
4887
|
+
atomicDeco: atomicDeco.finish()
|
4888
|
+
};
|
4889
|
+
};
|
4890
|
+
var forceUpdate = StateEffect5.define();
|
4891
|
+
var decorateMarkdown = (options = {}) => {
|
4892
|
+
return [
|
4893
|
+
ViewPlugin7.fromClass(class {
|
4894
|
+
constructor(view) {
|
4895
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
|
4896
|
+
}
|
4897
|
+
update(update2) {
|
4898
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
4899
|
+
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
|
4900
|
+
this.clearUpdate();
|
4901
|
+
} else if (update2.selectionSet) {
|
4902
|
+
this.scheduleUpdate(update2.view);
|
4903
|
+
}
|
4904
|
+
}
|
4905
|
+
// Defer update in case moving through the document.
|
4906
|
+
scheduleUpdate(view) {
|
4907
|
+
this.clearUpdate();
|
4908
|
+
this.pendingUpdate = setTimeout(() => {
|
4909
|
+
view.dispatch({
|
4910
|
+
effects: forceUpdate.of(null)
|
4911
|
+
});
|
4912
|
+
}, options.selectionChangeDelay);
|
4913
|
+
}
|
4914
|
+
clearUpdate() {
|
4915
|
+
if (this.pendingUpdate) {
|
4916
|
+
clearTimeout(this.pendingUpdate);
|
4917
|
+
this.pendingUpdate = void 0;
|
4918
|
+
}
|
4919
|
+
}
|
4920
|
+
destroy() {
|
4921
|
+
this.clearUpdate();
|
4922
|
+
}
|
4923
|
+
}, {
|
4924
|
+
provide: (plugin) => [
|
4925
|
+
EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
4926
|
+
EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
4927
|
+
EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
4928
|
+
]
|
4929
|
+
}),
|
4930
|
+
image(),
|
4931
|
+
table(),
|
4932
|
+
adjustChanges(),
|
4933
|
+
formattingStyles
|
4934
|
+
];
|
4935
|
+
};
|
4936
|
+
|
4937
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
4938
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
4939
|
+
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
4940
|
+
import { tooltipContent } from "@dxos/react-ui-theme";
|
4941
|
+
var linkTooltip = (renderTooltip) => {
|
4942
|
+
return hoverTooltip2((view, pos, side) => {
|
4943
|
+
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
4944
|
+
let link = null;
|
4945
|
+
for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
|
4946
|
+
link = node.name === "Link" ? node : null;
|
4947
|
+
}
|
4948
|
+
const url = link && link.getChild("URL");
|
4949
|
+
if (!url || !link) {
|
4950
|
+
return null;
|
4951
|
+
}
|
4952
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
4953
|
+
return {
|
4954
|
+
pos: link.from,
|
4955
|
+
end: link.to,
|
4956
|
+
// NOTE: Forcing above causes the tooltip to flicker.
|
4957
|
+
// above: true,
|
4958
|
+
create: () => {
|
4959
|
+
const el = document.createElement("div");
|
4960
|
+
el.className = tooltipContent({});
|
4961
|
+
renderTooltip(el, {
|
4962
|
+
url: urlText
|
4963
|
+
}, view);
|
4964
|
+
return {
|
4965
|
+
dom: el,
|
4966
|
+
offset: {
|
4967
|
+
x: 0,
|
4968
|
+
y: 4
|
4969
|
+
}
|
4970
|
+
};
|
4971
|
+
}
|
4972
|
+
};
|
4973
|
+
}, {
|
4974
|
+
// NOTE: 0 = default of 300ms.
|
4975
|
+
hoverTime: 1
|
4976
|
+
});
|
4977
|
+
};
|
4978
|
+
|
4979
|
+
// packages/ui/react-ui-editor/src/extensions/mention.ts
|
4980
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
4981
|
+
import { log as log6 } from "@dxos/log";
|
4982
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
|
4983
|
+
var mention = ({ debug, onSearch }) => {
|
4984
|
+
return autocompletion2({
|
4985
|
+
// TODO(burdon): Not working.
|
4986
|
+
activateOnTyping: true,
|
4987
|
+
// activateOnTypingDelay: 100,
|
4988
|
+
// selectOnOpen: true,
|
4989
|
+
closeOnBlur: !debug,
|
4990
|
+
// defaultKeymap: false,
|
4991
|
+
icons: false,
|
4992
|
+
override: [
|
4993
|
+
(context) => {
|
4994
|
+
log6.info("completion context", {
|
4995
|
+
context
|
4996
|
+
}, {
|
4997
|
+
F: __dxlog_file10,
|
4998
|
+
L: 27,
|
4999
|
+
S: void 0,
|
5000
|
+
C: (f, a) => f(...a)
|
5001
|
+
});
|
5002
|
+
const match = context.matchBefore(/@(\w+)?/);
|
5003
|
+
if (!match || match.from === match.to && !context.explicit) {
|
5004
|
+
return null;
|
5005
|
+
}
|
5006
|
+
return {
|
5007
|
+
from: match.from,
|
5008
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
5009
|
+
label: `@${value}`
|
5010
|
+
}))
|
5011
|
+
};
|
5012
|
+
}
|
5013
|
+
]
|
5014
|
+
});
|
5015
|
+
};
|
5016
|
+
|
5017
|
+
// packages/ui/react-ui-editor/src/extensions/modes.ts
|
5018
|
+
import { keymap as keymap9 } from "@codemirror/view";
|
5019
|
+
import { vim } from "@replit/codemirror-vim";
|
5020
|
+
import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
|
5021
|
+
import { Schema } from "effect";
|
5022
|
+
var EditorViewModes = [
|
5023
|
+
"preview",
|
5024
|
+
"readonly",
|
5025
|
+
"source"
|
5026
|
+
];
|
5027
|
+
var EditorViewMode = Schema.Union(...EditorViewModes.map((mode) => Schema.Literal(mode)));
|
5028
|
+
var EditorInputModes = [
|
5029
|
+
"default",
|
5030
|
+
"vim",
|
5031
|
+
"vscode"
|
5032
|
+
];
|
5033
|
+
var EditorInputMode = Schema.Union(...EditorInputModes.map((mode) => Schema.Literal(mode)));
|
5034
|
+
var editorInputMode = singleValueFacet({});
|
5035
|
+
var InputModeExtensions = {
|
5036
|
+
default: [],
|
5037
|
+
vscode: [
|
5038
|
+
// https://github.com/replit/codemirror-vscode-keymap
|
5039
|
+
editorInputMode.of({
|
5040
|
+
type: "vscode"
|
5041
|
+
}),
|
5042
|
+
keymap9.of(vscodeKeymap)
|
5043
|
+
],
|
5044
|
+
vim: [
|
5045
|
+
// https://github.com/replit/codemirror-vim
|
5046
|
+
vim(),
|
5047
|
+
editorInputMode.of({
|
5048
|
+
type: "vim",
|
5049
|
+
noTabster: true
|
5050
|
+
}),
|
5051
|
+
keymap9.of([
|
5052
|
+
{
|
5053
|
+
key: "Alt-Escape",
|
5054
|
+
run: (view) => {
|
5055
|
+
view.dom.parentElement?.focus();
|
5056
|
+
return true;
|
5057
|
+
}
|
5058
|
+
}
|
5059
|
+
])
|
5060
|
+
]
|
5061
|
+
};
|
5062
|
+
|
5063
|
+
// packages/ui/react-ui-editor/src/extensions/preview/preview.ts
|
5064
|
+
import "@dxos/lit-ui/dx-ref-tag.pcss";
|
5065
|
+
import { syntaxTree as syntaxTree9 } from "@codemirror/language";
|
5066
|
+
import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField10 } from "@codemirror/state";
|
5067
|
+
import { Decoration as Decoration8, EditorView as EditorView19, WidgetType as WidgetType6 } from "@codemirror/view";
|
5068
|
+
var preview = (options = {}) => {
|
5069
|
+
return [
|
5070
|
+
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
5071
|
+
// "Block decorations may not be specified via plugins"
|
5072
|
+
StateField10.define({
|
5073
|
+
create: (state) => buildDecorations3(state, options),
|
5074
|
+
update: (_, tr) => buildDecorations3(tr.state, options),
|
5075
|
+
provide: (field) => [
|
5076
|
+
EditorView19.decorations.from(field),
|
5077
|
+
EditorView19.atomicRanges.of((view) => view.state.field(field))
|
5078
|
+
]
|
5079
|
+
}),
|
5080
|
+
EditorView19.theme({
|
5081
|
+
".cm-preview-block": {
|
5082
|
+
marginLeft: "-1rem",
|
5083
|
+
marginRight: "-1rem",
|
5084
|
+
padding: "1rem",
|
5085
|
+
borderRadius: "0.5rem",
|
5086
|
+
background: "var(--dx-modalSurface)",
|
5087
|
+
border: "1px solid var(--dx-separator)"
|
5088
|
+
}
|
5089
|
+
})
|
5090
|
+
];
|
5091
|
+
};
|
5092
|
+
var getLinkRef = (state, node) => {
|
5093
|
+
const mark = node.getChild("LinkMark");
|
5094
|
+
const label = node.getChild("LinkLabel");
|
5095
|
+
if (mark && label) {
|
5096
|
+
const ref = state.sliceDoc(label.from + 1, label.to - 1);
|
5097
|
+
return {
|
5098
|
+
suggest: ref.startsWith("?"),
|
5099
|
+
block: state.sliceDoc(mark.from, mark.from + 1) === "!",
|
5100
|
+
label: state.sliceDoc(mark.to, label.from - 1),
|
5101
|
+
ref: ref.startsWith("?") ? ref.slice(1) : ref
|
5102
|
+
};
|
5103
|
+
}
|
5104
|
+
};
|
5105
|
+
var buildDecorations3 = (state, options) => {
|
5106
|
+
const builder = new RangeSetBuilder4();
|
5107
|
+
syntaxTree9(state).iterate({
|
5108
|
+
enter: (node) => {
|
5109
|
+
switch (node.name) {
|
5110
|
+
//
|
5111
|
+
// Decoration.
|
5112
|
+
// [Label][dxn:echo:123]
|
5113
|
+
//
|
5114
|
+
case "Link": {
|
5115
|
+
const link = getLinkRef(state, node.node);
|
5116
|
+
if (link) {
|
5117
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
5118
|
+
widget: new PreviewInlineWidget(options, link)
|
5119
|
+
}));
|
5120
|
+
}
|
5121
|
+
break;
|
5122
|
+
}
|
5123
|
+
//
|
5124
|
+
// Block widget.
|
5125
|
+
// ![Label][dxn:echo:123]
|
5126
|
+
//
|
5127
|
+
case "Image": {
|
5128
|
+
const link = getLinkRef(state, node.node);
|
5129
|
+
if (options.renderBlock && link) {
|
5130
|
+
builder.add(node.from, node.to, Decoration8.replace({
|
5131
|
+
block: true,
|
5132
|
+
// atomic: true,
|
5133
|
+
widget: new PreviewBlockWidget(options, link)
|
5134
|
+
}));
|
5135
|
+
}
|
5136
|
+
break;
|
5137
|
+
}
|
5138
|
+
}
|
5139
|
+
}
|
5140
|
+
});
|
5141
|
+
return builder.finish();
|
5142
|
+
};
|
5143
|
+
var PreviewInlineWidget = class extends WidgetType6 {
|
5144
|
+
constructor(_options, _link) {
|
5145
|
+
super();
|
5146
|
+
this._options = _options;
|
5147
|
+
this._link = _link;
|
5148
|
+
}
|
5149
|
+
// override ignoreEvent() {
|
5150
|
+
// return false;
|
5151
|
+
// }
|
5152
|
+
eq(other) {
|
5153
|
+
return this._link.ref === other._link.ref && this._link.label === other._link.label;
|
5154
|
+
}
|
5155
|
+
toDOM(view) {
|
5156
|
+
const root = document.createElement("dx-ref-tag");
|
5157
|
+
root.textContent = this._link.label;
|
5158
|
+
root.setAttribute("ref", this._link.ref);
|
5159
|
+
return root;
|
5234
5160
|
}
|
5235
|
-
return {
|
5236
|
-
deco: deco.finish(),
|
5237
|
-
atomicDeco: atomicDeco.finish()
|
5238
|
-
};
|
5239
5161
|
};
|
5240
|
-
var
|
5241
|
-
|
5242
|
-
|
5243
|
-
|
5244
|
-
|
5245
|
-
|
5162
|
+
var PreviewBlockWidget = class extends WidgetType6 {
|
5163
|
+
constructor(_options, _link) {
|
5164
|
+
super();
|
5165
|
+
this._options = _options;
|
5166
|
+
this._link = _link;
|
5167
|
+
}
|
5168
|
+
// override ignoreEvent() {
|
5169
|
+
// return true;
|
5170
|
+
// }
|
5171
|
+
eq(other) {
|
5172
|
+
return this._link.ref === other._link.ref;
|
5173
|
+
}
|
5174
|
+
toDOM(view) {
|
5175
|
+
const root = document.createElement("div");
|
5176
|
+
root.classList.add("cm-preview-block");
|
5177
|
+
const handleAction = (action) => {
|
5178
|
+
const pos = view.posAtDOM(root);
|
5179
|
+
const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
|
5180
|
+
if (!node) {
|
5181
|
+
return;
|
5246
5182
|
}
|
5247
|
-
|
5248
|
-
|
5249
|
-
|
5250
|
-
this.clearUpdate();
|
5251
|
-
} else if (update2.selectionSet) {
|
5252
|
-
this.scheduleUpdate(update2.view);
|
5253
|
-
}
|
5183
|
+
const link = getLinkRef(view.state, node);
|
5184
|
+
if (link?.ref !== action.link.ref) {
|
5185
|
+
return;
|
5254
5186
|
}
|
5255
|
-
|
5256
|
-
|
5257
|
-
|
5258
|
-
|
5187
|
+
switch (action.type) {
|
5188
|
+
// TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
|
5189
|
+
// Insert ref text.
|
5190
|
+
case "insert": {
|
5259
5191
|
view.dispatch({
|
5260
|
-
|
5192
|
+
changes: {
|
5193
|
+
from: node.from,
|
5194
|
+
to: node.to,
|
5195
|
+
insert: action.target.text
|
5196
|
+
}
|
5261
5197
|
});
|
5262
|
-
|
5263
|
-
|
5264
|
-
|
5265
|
-
|
5266
|
-
|
5267
|
-
|
5198
|
+
break;
|
5199
|
+
}
|
5200
|
+
// Remove ref.
|
5201
|
+
case "delete": {
|
5202
|
+
view.dispatch({
|
5203
|
+
changes: {
|
5204
|
+
from: node.from,
|
5205
|
+
to: node.to
|
5206
|
+
}
|
5207
|
+
});
|
5208
|
+
break;
|
5268
5209
|
}
|
5269
5210
|
}
|
5270
|
-
|
5271
|
-
|
5211
|
+
};
|
5212
|
+
this._options.renderBlock(root, {
|
5213
|
+
readonly: view.state.readOnly,
|
5214
|
+
link: this._link,
|
5215
|
+
onAction: handleAction,
|
5216
|
+
onLookup: this._options.onLookup
|
5217
|
+
}, view);
|
5218
|
+
return root;
|
5219
|
+
}
|
5220
|
+
};
|
5221
|
+
|
5222
|
+
// packages/ui/react-ui-editor/src/extensions/typewriter.ts
|
5223
|
+
import { keymap as keymap10 } from "@codemirror/view";
|
5224
|
+
var defaultItems = [
|
5225
|
+
"hello world!",
|
5226
|
+
"this is a test.",
|
5227
|
+
"this is [DXOS](https://dxos.org)"
|
5228
|
+
];
|
5229
|
+
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
5230
|
+
let t;
|
5231
|
+
let idx = 0;
|
5232
|
+
return [
|
5233
|
+
keymap10.of([
|
5234
|
+
{
|
5235
|
+
// Reset.
|
5236
|
+
key: "alt-meta-'",
|
5237
|
+
run: (view) => {
|
5238
|
+
clearTimeout(t);
|
5239
|
+
idx = 0;
|
5240
|
+
return true;
|
5241
|
+
}
|
5242
|
+
},
|
5243
|
+
{
|
5244
|
+
// Next prompt.
|
5245
|
+
// TODO(burdon): Press 1-9 to select prompt?
|
5246
|
+
key: "shift-meta-'",
|
5247
|
+
run: (view) => {
|
5248
|
+
clearTimeout(t);
|
5249
|
+
const text = items[idx++];
|
5250
|
+
if (idx === items?.length) {
|
5251
|
+
idx = 0;
|
5252
|
+
}
|
5253
|
+
let i = 0;
|
5254
|
+
const insert = (d = 0) => {
|
5255
|
+
t = setTimeout(() => {
|
5256
|
+
const pos = view.state.selection.main.head;
|
5257
|
+
view.dispatch({
|
5258
|
+
changes: {
|
5259
|
+
from: pos,
|
5260
|
+
insert: text[i++]
|
5261
|
+
},
|
5262
|
+
selection: {
|
5263
|
+
anchor: pos + 1
|
5264
|
+
}
|
5265
|
+
});
|
5266
|
+
if (i < text.length) {
|
5267
|
+
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
5268
|
+
}
|
5269
|
+
}, d);
|
5270
|
+
};
|
5271
|
+
insert();
|
5272
|
+
return true;
|
5273
|
+
}
|
5272
5274
|
}
|
5273
|
-
|
5274
|
-
provide: (plugin) => [
|
5275
|
-
EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5276
|
-
EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5277
|
-
EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
5278
|
-
]
|
5279
|
-
}),
|
5280
|
-
image(),
|
5281
|
-
table(),
|
5282
|
-
adjustChanges(),
|
5283
|
-
formattingStyles
|
5275
|
+
])
|
5284
5276
|
];
|
5285
5277
|
};
|
5286
5278
|
|
5287
|
-
// packages/ui/react-ui-editor/src/
|
5288
|
-
|
5289
|
-
|
5290
|
-
|
5291
|
-
|
5292
|
-
|
5293
|
-
|
5294
|
-
|
5295
|
-
|
5296
|
-
|
5279
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
|
5280
|
+
var createBlockGroupAction = (value) => createEditorActionGroup("block", {
|
5281
|
+
variant: "toggleGroup",
|
5282
|
+
selectCardinality: "single",
|
5283
|
+
value
|
5284
|
+
});
|
5285
|
+
var createBlockActions = (value, getView, blankLine) => Object.entries({
|
5286
|
+
blockquote: "ph--quotes--regular",
|
5287
|
+
codeblock: "ph--code-block--regular",
|
5288
|
+
table: "ph--table--regular"
|
5289
|
+
}).map(([type, icon]) => {
|
5290
|
+
const checked = type === value;
|
5291
|
+
return createEditorAction(type, () => {
|
5292
|
+
const view = getView();
|
5293
|
+
if (!view) {
|
5294
|
+
return;
|
5297
5295
|
}
|
5298
|
-
|
5299
|
-
|
5300
|
-
|
5296
|
+
switch (type) {
|
5297
|
+
case "blockquote":
|
5298
|
+
checked ? removeBlockquote(view) : addBlockquote(view);
|
5299
|
+
break;
|
5300
|
+
case "codeblock":
|
5301
|
+
checked ? removeCodeblock(view) : addCodeblock(view);
|
5302
|
+
break;
|
5303
|
+
case "table":
|
5304
|
+
insertTable(view);
|
5305
|
+
break;
|
5301
5306
|
}
|
5302
|
-
|
5303
|
-
|
5304
|
-
|
5305
|
-
|
5306
|
-
|
5307
|
-
|
5308
|
-
|
5309
|
-
|
5310
|
-
|
5311
|
-
|
5312
|
-
|
5313
|
-
|
5314
|
-
|
5315
|
-
|
5316
|
-
|
5317
|
-
|
5318
|
-
|
5319
|
-
|
5320
|
-
|
5307
|
+
}, {
|
5308
|
+
checked,
|
5309
|
+
...type === "table" && {
|
5310
|
+
disabled: !!blankLine
|
5311
|
+
},
|
5312
|
+
icon
|
5313
|
+
});
|
5314
|
+
});
|
5315
|
+
var createBlocks = (state, getView) => {
|
5316
|
+
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
5317
|
+
const blockGroupAction = createBlockGroupAction(value);
|
5318
|
+
const blockActions = createBlockActions(value, getView, state.blankLine);
|
5319
|
+
return {
|
5320
|
+
nodes: [
|
5321
|
+
blockGroupAction,
|
5322
|
+
...blockActions
|
5323
|
+
],
|
5324
|
+
edges: [
|
5325
|
+
{
|
5326
|
+
source: "root",
|
5327
|
+
target: "block"
|
5328
|
+
},
|
5329
|
+
...blockActions.map(({ id }) => ({
|
5330
|
+
source: blockGroupAction.id,
|
5331
|
+
target: id
|
5332
|
+
}))
|
5333
|
+
]
|
5334
|
+
};
|
5335
|
+
};
|
5336
|
+
|
5337
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
|
5338
|
+
var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
|
5339
|
+
var createCommentAction = (label, getView) => createEditorAction("comment", () => createComment(getView()), {
|
5340
|
+
testId: "editor.toolbar.comment",
|
5341
|
+
icon: "ph--chat-text--regular",
|
5342
|
+
label
|
5343
|
+
});
|
5344
|
+
var createComment2 = (state, getView) => ({
|
5345
|
+
nodes: [
|
5346
|
+
createCommentAction([
|
5347
|
+
commentLabel(state.comment, state.selection),
|
5348
|
+
{
|
5349
|
+
ns: translationKey
|
5321
5350
|
}
|
5322
|
-
|
5351
|
+
], getView)
|
5352
|
+
],
|
5353
|
+
edges: [
|
5354
|
+
{
|
5355
|
+
source: "root",
|
5356
|
+
target: "comment"
|
5357
|
+
}
|
5358
|
+
]
|
5359
|
+
});
|
5360
|
+
|
5361
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
|
5362
|
+
var formats = {
|
5363
|
+
strong: "ph--text-b--regular",
|
5364
|
+
emphasis: "ph--text-italic--regular",
|
5365
|
+
strikethrough: "ph--text-strikethrough--regular",
|
5366
|
+
code: "ph--code--regular",
|
5367
|
+
link: "ph--link--regular"
|
5368
|
+
};
|
5369
|
+
var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
|
5370
|
+
variant: "toggleGroup",
|
5371
|
+
selectCardinality: "multiple",
|
5372
|
+
value: Object.keys(formats).filter((key) => !!formatting[key])
|
5373
|
+
});
|
5374
|
+
var createFormattingActions = (formatting, getView) => Object.entries(formats).map(([type, icon]) => {
|
5375
|
+
const checked = !!formatting[type];
|
5376
|
+
return createEditorAction(type, () => {
|
5377
|
+
const view = getView();
|
5378
|
+
if (!view) {
|
5379
|
+
return;
|
5380
|
+
}
|
5381
|
+
if (type === "link") {
|
5382
|
+
checked ? removeLink(view) : addLink()(view);
|
5383
|
+
return;
|
5384
|
+
}
|
5385
|
+
const inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
5386
|
+
setStyle(inlineType, !checked)(view);
|
5323
5387
|
}, {
|
5324
|
-
|
5325
|
-
|
5388
|
+
checked,
|
5389
|
+
icon
|
5326
5390
|
});
|
5391
|
+
});
|
5392
|
+
var createFormatting = (state, getView) => {
|
5393
|
+
const formattingGroupAction = createFormattingGroup(state);
|
5394
|
+
const formattingActions = createFormattingActions(state, getView);
|
5395
|
+
return {
|
5396
|
+
nodes: [
|
5397
|
+
formattingGroupAction,
|
5398
|
+
...formattingActions
|
5399
|
+
],
|
5400
|
+
edges: [
|
5401
|
+
{
|
5402
|
+
source: "root",
|
5403
|
+
target: "formatting"
|
5404
|
+
},
|
5405
|
+
...formattingActions.map(({ id }) => ({
|
5406
|
+
source: formattingGroupAction.id,
|
5407
|
+
target: id
|
5408
|
+
}))
|
5409
|
+
]
|
5410
|
+
};
|
5327
5411
|
};
|
5328
5412
|
|
5329
|
-
// packages/ui/react-ui-editor/src/
|
5330
|
-
|
5331
|
-
|
5332
|
-
|
5333
|
-
|
5334
|
-
|
5335
|
-
|
5336
|
-
|
5337
|
-
|
5338
|
-
|
5339
|
-
|
5340
|
-
|
5341
|
-
|
5342
|
-
|
5343
|
-
|
5344
|
-
|
5345
|
-
|
5346
|
-
|
5347
|
-
|
5348
|
-
|
5349
|
-
|
5350
|
-
|
5351
|
-
|
5352
|
-
const match = context.matchBefore(/@(\w+)?/);
|
5353
|
-
if (!match || match.from === match.to && !context.explicit) {
|
5354
|
-
return null;
|
5355
|
-
}
|
5356
|
-
return {
|
5357
|
-
from: match.from,
|
5358
|
-
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
5359
|
-
label: `@${value}`
|
5360
|
-
}))
|
5361
|
-
};
|
5413
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
|
5414
|
+
var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
|
5415
|
+
variant: "dropdownMenu",
|
5416
|
+
applyActive: true,
|
5417
|
+
selectCardinality: "single",
|
5418
|
+
value
|
5419
|
+
}, "ph--text-h--regular");
|
5420
|
+
var createHeadingActions = (getView) => Object.entries({
|
5421
|
+
"0": "ph--paragraph--regular",
|
5422
|
+
"1": "ph--text-h-one--regular",
|
5423
|
+
"2": "ph--text-h-two--regular",
|
5424
|
+
"3": "ph--text-h-three--regular",
|
5425
|
+
"4": "ph--text-h-four--regular",
|
5426
|
+
"5": "ph--text-h-five--regular",
|
5427
|
+
"6": "ph--text-h-six--regular"
|
5428
|
+
}).map(([levelStr, icon]) => {
|
5429
|
+
const level = parseInt(levelStr);
|
5430
|
+
return createEditorAction(`heading--${levelStr}`, () => setHeading(level)(getView()), {
|
5431
|
+
label: [
|
5432
|
+
"heading level label",
|
5433
|
+
{
|
5434
|
+
count: level,
|
5435
|
+
ns: translationKey
|
5362
5436
|
}
|
5363
|
-
]
|
5437
|
+
],
|
5438
|
+
icon
|
5364
5439
|
});
|
5440
|
+
});
|
5441
|
+
var computeHeadingValue = (state) => {
|
5442
|
+
const blockType = state ? state.blockType : "paragraph";
|
5443
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
5444
|
+
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
5445
|
+
};
|
5446
|
+
var createHeadings = (state, getView) => {
|
5447
|
+
const headingValue = computeHeadingValue(state);
|
5448
|
+
const headingGroupAction = createHeadingGroupAction(headingValue);
|
5449
|
+
const headingActions = createHeadingActions(getView);
|
5450
|
+
return {
|
5451
|
+
nodes: [
|
5452
|
+
headingGroupAction,
|
5453
|
+
...headingActions
|
5454
|
+
],
|
5455
|
+
edges: [
|
5456
|
+
{
|
5457
|
+
source: "root",
|
5458
|
+
target: "heading"
|
5459
|
+
},
|
5460
|
+
...headingActions.map(({ id }) => ({
|
5461
|
+
source: headingGroupAction.id,
|
5462
|
+
target: id
|
5463
|
+
}))
|
5464
|
+
]
|
5465
|
+
};
|
5365
5466
|
};
|
5366
5467
|
|
5367
|
-
// packages/ui/react-ui-editor/src/
|
5368
|
-
|
5369
|
-
|
5370
|
-
|
5371
|
-
|
5372
|
-
var
|
5373
|
-
|
5374
|
-
|
5375
|
-
"source"
|
5376
|
-
];
|
5377
|
-
var EditorViewMode = S.Union(...EditorViewModes.map((mode) => S.Literal(mode)));
|
5378
|
-
var EditorInputModes = [
|
5379
|
-
"default",
|
5380
|
-
"vim",
|
5381
|
-
"vscode"
|
5382
|
-
];
|
5383
|
-
var EditorInputMode = S.Union(...EditorInputModes.map((mode) => S.Literal(mode)));
|
5384
|
-
var editorInputMode = singleValueFacet({});
|
5385
|
-
var InputModeExtensions = {
|
5386
|
-
default: [],
|
5387
|
-
vscode: [
|
5388
|
-
// https://github.com/replit/codemirror-vscode-keymap
|
5389
|
-
editorInputMode.of({
|
5390
|
-
type: "vscode"
|
5391
|
-
}),
|
5392
|
-
keymap9.of(vscodeKeymap)
|
5468
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/image.ts
|
5469
|
+
var createImageUploadAction = (onImageUpload) => createEditorAction("image", onImageUpload, {
|
5470
|
+
testId: "editor.toolbar.image",
|
5471
|
+
icon: "ph--image-square--regular"
|
5472
|
+
});
|
5473
|
+
var createImageUpload = (onImageUpload) => ({
|
5474
|
+
nodes: [
|
5475
|
+
createImageUploadAction(onImageUpload)
|
5393
5476
|
],
|
5394
|
-
|
5395
|
-
|
5396
|
-
|
5397
|
-
|
5398
|
-
|
5399
|
-
noTabster: true
|
5400
|
-
}),
|
5401
|
-
keymap9.of([
|
5402
|
-
{
|
5403
|
-
key: "Alt-Escape",
|
5404
|
-
run: (view) => {
|
5405
|
-
view.dom.parentElement?.focus();
|
5406
|
-
return true;
|
5407
|
-
}
|
5408
|
-
}
|
5409
|
-
])
|
5477
|
+
edges: [
|
5478
|
+
{
|
5479
|
+
source: "root",
|
5480
|
+
target: "image"
|
5481
|
+
}
|
5410
5482
|
]
|
5411
|
-
};
|
5483
|
+
});
|
5412
5484
|
|
5413
|
-
// packages/ui/react-ui-editor/src/
|
5414
|
-
|
5415
|
-
|
5416
|
-
|
5417
|
-
|
5418
|
-
var preview = (options = {}) => {
|
5419
|
-
return [
|
5420
|
-
// NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
|
5421
|
-
// "Block decorations may not be specified via plugins"
|
5422
|
-
StateField10.define({
|
5423
|
-
create: (state) => buildDecorations3(state, options),
|
5424
|
-
update: (_, tr) => buildDecorations3(tr.state, options),
|
5425
|
-
provide: (field) => [
|
5426
|
-
EditorView20.decorations.from(field),
|
5427
|
-
EditorView20.atomicRanges.of((view) => view.state.field(field))
|
5428
|
-
]
|
5429
|
-
}),
|
5430
|
-
EditorView20.theme({
|
5431
|
-
".cm-preview-block": {
|
5432
|
-
marginLeft: "-1rem",
|
5433
|
-
marginRight: "-1rem",
|
5434
|
-
padding: "1rem",
|
5435
|
-
borderRadius: "0.5rem",
|
5436
|
-
background: "var(--dx-modalSurface)",
|
5437
|
-
border: "1px solid var(--dx-separator)"
|
5438
|
-
}
|
5439
|
-
})
|
5440
|
-
];
|
5441
|
-
};
|
5442
|
-
var getLinkRef = (state, node) => {
|
5443
|
-
const mark = node.getChild("LinkMark");
|
5444
|
-
const label = node.getChild("LinkLabel");
|
5445
|
-
if (mark && label) {
|
5446
|
-
const ref = state.sliceDoc(label.from + 1, label.to - 1);
|
5447
|
-
return {
|
5448
|
-
suggest: ref.startsWith("?"),
|
5449
|
-
block: state.sliceDoc(mark.from, mark.from + 1) === "!",
|
5450
|
-
label: state.sliceDoc(mark.to, label.from - 1),
|
5451
|
-
ref: ref.startsWith("?") ? ref.slice(1) : ref
|
5452
|
-
};
|
5453
|
-
}
|
5485
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
|
5486
|
+
var listStyles = {
|
5487
|
+
bullet: "ph--list-bullets--regular",
|
5488
|
+
ordered: "ph--list-numbers--regular",
|
5489
|
+
task: "ph--list-checks--regular"
|
5454
5490
|
};
|
5455
|
-
var
|
5456
|
-
|
5457
|
-
|
5458
|
-
|
5459
|
-
|
5460
|
-
|
5461
|
-
|
5462
|
-
|
5463
|
-
|
5464
|
-
|
5465
|
-
|
5466
|
-
|
5467
|
-
|
5468
|
-
|
5469
|
-
|
5470
|
-
|
5471
|
-
|
5472
|
-
|
5473
|
-
|
5474
|
-
|
5475
|
-
|
5476
|
-
|
5477
|
-
|
5478
|
-
|
5479
|
-
|
5480
|
-
|
5481
|
-
|
5482
|
-
|
5483
|
-
|
5484
|
-
|
5485
|
-
|
5486
|
-
|
5487
|
-
|
5488
|
-
|
5491
|
+
var createListGroupAction = (value) => createEditorActionGroup("list", {
|
5492
|
+
variant: "toggleGroup",
|
5493
|
+
selectCardinality: "single",
|
5494
|
+
value
|
5495
|
+
});
|
5496
|
+
var createListActions = (value, getView) => Object.entries(listStyles).map(([listStyle, icon]) => {
|
5497
|
+
const checked = value === listStyle;
|
5498
|
+
return createEditorAction(`list-${listStyle}`, () => {
|
5499
|
+
const view = getView();
|
5500
|
+
if (!view) {
|
5501
|
+
return;
|
5502
|
+
}
|
5503
|
+
const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
|
5504
|
+
if (checked) {
|
5505
|
+
removeList(listType)(view);
|
5506
|
+
} else {
|
5507
|
+
addList(listType)(view);
|
5508
|
+
}
|
5509
|
+
}, {
|
5510
|
+
checked,
|
5511
|
+
icon
|
5512
|
+
});
|
5513
|
+
});
|
5514
|
+
var createLists = (state, getView) => {
|
5515
|
+
const value = state.listStyle ?? "";
|
5516
|
+
const listGroupAction = createListGroupAction(value);
|
5517
|
+
const listActionsMap = createListActions(value, getView);
|
5518
|
+
return {
|
5519
|
+
nodes: [
|
5520
|
+
listGroupAction,
|
5521
|
+
...listActionsMap
|
5522
|
+
],
|
5523
|
+
edges: [
|
5524
|
+
{
|
5525
|
+
source: "root",
|
5526
|
+
target: "list"
|
5527
|
+
},
|
5528
|
+
...listActionsMap.map(({ id }) => ({
|
5529
|
+
source: listGroupAction.id,
|
5530
|
+
target: id
|
5531
|
+
}))
|
5532
|
+
]
|
5533
|
+
};
|
5534
|
+
};
|
5535
|
+
|
5536
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/search.ts
|
5537
|
+
import { openSearchPanel } from "@codemirror/search";
|
5538
|
+
var createSearchAction = (getView) => createEditorAction("search", () => openSearchPanel(getView()), {
|
5539
|
+
testId: "editor.toolbar.search",
|
5540
|
+
icon: "ph--magnifying-glass--regular"
|
5541
|
+
});
|
5542
|
+
var createSearch = (getView) => ({
|
5543
|
+
nodes: [
|
5544
|
+
createSearchAction(getView)
|
5545
|
+
],
|
5546
|
+
edges: [
|
5547
|
+
{
|
5548
|
+
source: "root",
|
5549
|
+
target: "search"
|
5489
5550
|
}
|
5551
|
+
]
|
5552
|
+
});
|
5553
|
+
|
5554
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
|
5555
|
+
var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
|
5556
|
+
variant: "dropdownMenu",
|
5557
|
+
applyActive: true,
|
5558
|
+
selectCardinality: "single",
|
5559
|
+
value
|
5560
|
+
}, "ph--eye--regular");
|
5561
|
+
var createViewModeActions = (value, onViewModeChange) => Object.entries({
|
5562
|
+
preview: "ph--eye--regular",
|
5563
|
+
source: "ph--pencil-simple--regular",
|
5564
|
+
readonly: "ph--pencil-slash--regular"
|
5565
|
+
}).map(([viewMode, icon]) => {
|
5566
|
+
const checked = viewMode === value;
|
5567
|
+
return createEditorAction(`view-mode--${viewMode}`, () => onViewModeChange(viewMode), {
|
5568
|
+
label: [
|
5569
|
+
`${viewMode} mode label`,
|
5570
|
+
{
|
5571
|
+
ns: translationKey
|
5572
|
+
}
|
5573
|
+
],
|
5574
|
+
checked,
|
5575
|
+
icon
|
5490
5576
|
});
|
5491
|
-
|
5577
|
+
});
|
5578
|
+
var createViewMode = (state, onViewModeChange) => {
|
5579
|
+
const value = state.viewMode ?? "source";
|
5580
|
+
const viewModeGroupAction = createViewModeGroupAction(value);
|
5581
|
+
const viewModeActions = createViewModeActions(value, onViewModeChange);
|
5582
|
+
return {
|
5583
|
+
nodes: [
|
5584
|
+
viewModeGroupAction,
|
5585
|
+
...viewModeActions
|
5586
|
+
],
|
5587
|
+
edges: [
|
5588
|
+
{
|
5589
|
+
source: "root",
|
5590
|
+
target: "viewMode"
|
5591
|
+
},
|
5592
|
+
...viewModeActions.map(({ id }) => ({
|
5593
|
+
source: viewModeGroupAction.id,
|
5594
|
+
target: id
|
5595
|
+
}))
|
5596
|
+
]
|
5597
|
+
};
|
5492
5598
|
};
|
5493
|
-
|
5494
|
-
|
5495
|
-
|
5496
|
-
|
5497
|
-
|
5599
|
+
|
5600
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
5601
|
+
import { EditorView as EditorView20 } from "@codemirror/view";
|
5602
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
5603
|
+
var margin = "!mt-[1rem]";
|
5604
|
+
var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
|
5605
|
+
var editorContent = mx3(margin, editorWidth);
|
5606
|
+
var editorFullWidth = mx3(margin);
|
5607
|
+
var editorGutter = EditorView20.theme({
|
5608
|
+
// Match margin from content.
|
5609
|
+
// Gutter = 2rem + 1rem margin.
|
5610
|
+
".cm-gutters": {
|
5611
|
+
marginTop: "1rem",
|
5612
|
+
paddingRight: "1rem"
|
5498
5613
|
}
|
5499
|
-
|
5500
|
-
|
5501
|
-
|
5502
|
-
|
5503
|
-
return this._link.ref === other._link.ref && this._link.label === other._link.label;
|
5614
|
+
});
|
5615
|
+
var editorMonospace = EditorView20.theme({
|
5616
|
+
".cm-content": {
|
5617
|
+
fontFamily: fontMono
|
5504
5618
|
}
|
5505
|
-
|
5506
|
-
|
5507
|
-
|
5508
|
-
|
5509
|
-
|
5619
|
+
});
|
5620
|
+
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
5621
|
+
var stackItemContentEditorClassNames = (role) => mx3("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
|
5622
|
+
var stackItemContentToolbarClassNames = (role) => mx3("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
|
5623
|
+
|
5624
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
5625
|
+
var createToolbar = ({ getView, state, customActions, ...features }) => {
|
5626
|
+
const nodes = [];
|
5627
|
+
const edges = [];
|
5628
|
+
if (features.headings ?? true) {
|
5629
|
+
const headings2 = createHeadings(state, getView);
|
5630
|
+
nodes.push(...headings2.nodes);
|
5631
|
+
edges.push(...headings2.edges);
|
5510
5632
|
}
|
5511
|
-
|
5512
|
-
|
5513
|
-
|
5514
|
-
|
5515
|
-
this._options = _options;
|
5516
|
-
this._link = _link;
|
5633
|
+
if (features.formatting ?? true) {
|
5634
|
+
const formatting = createFormatting(state, getView);
|
5635
|
+
nodes.push(...formatting.nodes);
|
5636
|
+
edges.push(...formatting.edges);
|
5517
5637
|
}
|
5518
|
-
|
5519
|
-
|
5520
|
-
|
5521
|
-
|
5522
|
-
return this._link.ref === other._link.ref;
|
5638
|
+
if (features.lists ?? true) {
|
5639
|
+
const lists = createLists(state, getView);
|
5640
|
+
nodes.push(...lists.nodes);
|
5641
|
+
edges.push(...lists.edges);
|
5523
5642
|
}
|
5524
|
-
|
5525
|
-
const
|
5526
|
-
|
5527
|
-
|
5528
|
-
const pos = view.posAtDOM(root);
|
5529
|
-
const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
|
5530
|
-
if (!node) {
|
5531
|
-
return;
|
5532
|
-
}
|
5533
|
-
const link = getLinkRef(view.state, node);
|
5534
|
-
if (link?.ref !== action.link.ref) {
|
5535
|
-
return;
|
5536
|
-
}
|
5537
|
-
switch (action.type) {
|
5538
|
-
// TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
|
5539
|
-
// Insert ref text.
|
5540
|
-
case "insert": {
|
5541
|
-
view.dispatch({
|
5542
|
-
changes: {
|
5543
|
-
from: node.from,
|
5544
|
-
to: node.to,
|
5545
|
-
insert: action.target.text
|
5546
|
-
}
|
5547
|
-
});
|
5548
|
-
break;
|
5549
|
-
}
|
5550
|
-
// Remove ref.
|
5551
|
-
case "delete": {
|
5552
|
-
view.dispatch({
|
5553
|
-
changes: {
|
5554
|
-
from: node.from,
|
5555
|
-
to: node.to
|
5556
|
-
}
|
5557
|
-
});
|
5558
|
-
break;
|
5559
|
-
}
|
5560
|
-
}
|
5561
|
-
};
|
5562
|
-
this._options.renderBlock(root, {
|
5563
|
-
readonly: view.state.readOnly,
|
5564
|
-
link: this._link,
|
5565
|
-
onAction: handleAction,
|
5566
|
-
onLookup: this._options.onLookup
|
5567
|
-
}, view);
|
5568
|
-
return root;
|
5643
|
+
if (features.blocks ?? true) {
|
5644
|
+
const blocks = createBlocks(state, getView);
|
5645
|
+
nodes.push(...blocks.nodes);
|
5646
|
+
edges.push(...blocks.edges);
|
5569
5647
|
}
|
5648
|
+
if (features.image) {
|
5649
|
+
const image2 = createImageUpload(features.image);
|
5650
|
+
nodes.push(...image2.nodes);
|
5651
|
+
edges.push(...image2.edges);
|
5652
|
+
}
|
5653
|
+
if (customActions) {
|
5654
|
+
const custom = customActions();
|
5655
|
+
nodes.push(...custom.nodes);
|
5656
|
+
edges.push(...custom.edges);
|
5657
|
+
}
|
5658
|
+
const editorToolbarGap = createGapSeparator();
|
5659
|
+
nodes.push(...editorToolbarGap.nodes);
|
5660
|
+
edges.push(...editorToolbarGap.edges);
|
5661
|
+
if (features.comment) {
|
5662
|
+
const comment = createComment2(state, getView);
|
5663
|
+
nodes.push(...comment.nodes);
|
5664
|
+
edges.push(...comment.edges);
|
5665
|
+
}
|
5666
|
+
if (features.search ?? true) {
|
5667
|
+
const search = createSearch(getView);
|
5668
|
+
nodes.push(...search.nodes);
|
5669
|
+
edges.push(...search.edges);
|
5670
|
+
}
|
5671
|
+
if (features.viewMode) {
|
5672
|
+
const viewMode = createViewMode(state, features.viewMode);
|
5673
|
+
nodes.push(...viewMode.nodes);
|
5674
|
+
edges.push(...viewMode.edges);
|
5675
|
+
}
|
5676
|
+
return {
|
5677
|
+
nodes,
|
5678
|
+
edges
|
5679
|
+
};
|
5570
5680
|
};
|
5571
|
-
|
5572
|
-
|
5573
|
-
|
5574
|
-
var defaultItems = [
|
5575
|
-
"hello world!",
|
5576
|
-
"this is a test.",
|
5577
|
-
"this is [DXOS](https://dxos.org)"
|
5578
|
-
];
|
5579
|
-
var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
5580
|
-
let t;
|
5581
|
-
let idx = 0;
|
5582
|
-
return [
|
5583
|
-
keymap10.of([
|
5584
|
-
{
|
5585
|
-
// Reset.
|
5586
|
-
key: "alt-meta-'",
|
5587
|
-
run: (view) => {
|
5588
|
-
clearTimeout(t);
|
5589
|
-
idx = 0;
|
5590
|
-
return true;
|
5591
|
-
}
|
5592
|
-
},
|
5593
|
-
{
|
5594
|
-
// Next prompt.
|
5595
|
-
// TODO(burdon): Press 1-9 to select prompt?
|
5596
|
-
key: "shift-meta-'",
|
5597
|
-
run: (view) => {
|
5598
|
-
clearTimeout(t);
|
5599
|
-
const text = items[idx++];
|
5600
|
-
if (idx === items?.length) {
|
5601
|
-
idx = 0;
|
5602
|
-
}
|
5603
|
-
let i = 0;
|
5604
|
-
const insert = (d = 0) => {
|
5605
|
-
t = setTimeout(() => {
|
5606
|
-
const pos = view.state.selection.main.head;
|
5607
|
-
view.dispatch({
|
5608
|
-
changes: {
|
5609
|
-
from: pos,
|
5610
|
-
insert: text[i++]
|
5611
|
-
},
|
5612
|
-
selection: {
|
5613
|
-
anchor: pos + 1
|
5614
|
-
}
|
5615
|
-
});
|
5616
|
-
if (i < text.length) {
|
5617
|
-
insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
|
5618
|
-
}
|
5619
|
-
}, d);
|
5620
|
-
};
|
5621
|
-
insert();
|
5622
|
-
return true;
|
5623
|
-
}
|
5624
|
-
}
|
5625
|
-
])
|
5626
|
-
];
|
5627
|
-
};
|
5628
|
-
|
5629
|
-
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
5630
|
-
import { useCallback as useCallback2 } from "react";
|
5631
|
-
var useActionHandler = (view) => {
|
5632
|
-
return useCallback2((action) => view && processEditorPayload(view, action.properties), [
|
5633
|
-
view
|
5681
|
+
var useEditorToolbarActionGraph = (props) => {
|
5682
|
+
const menuCreator = useCallback(() => createToolbar(props), [
|
5683
|
+
props
|
5634
5684
|
]);
|
5685
|
+
return useMenuActions(menuCreator);
|
5635
5686
|
};
|
5687
|
+
var EditorToolbar = /* @__PURE__ */ memo(({ classNames, attendableId, role, ...props }) => {
|
5688
|
+
const menuProps = useEditorToolbarActionGraph(props);
|
5689
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
5690
|
+
role: "none",
|
5691
|
+
className: stackItemContentToolbarClassNames(role)
|
5692
|
+
}, /* @__PURE__ */ React3.createElement(ElevationProvider, {
|
5693
|
+
elevation: role === "section" ? "positioned" : "base"
|
5694
|
+
}, /* @__PURE__ */ React3.createElement(MenuProvider, {
|
5695
|
+
...menuProps,
|
5696
|
+
attendableId
|
5697
|
+
}, /* @__PURE__ */ React3.createElement(ToolbarMenu, {
|
5698
|
+
classNames: [
|
5699
|
+
textBlockWidth,
|
5700
|
+
"!bg-transparent",
|
5701
|
+
classNames
|
5702
|
+
]
|
5703
|
+
}))));
|
5704
|
+
});
|
5636
5705
|
|
5637
5706
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
5638
5707
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
5639
5708
|
import { EditorView as EditorView21 } from "@codemirror/view";
|
5640
5709
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
5641
|
-
import { useCallback as
|
5710
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
|
5642
5711
|
import { log as log7 } from "@dxos/log";
|
5643
5712
|
import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
5644
5713
|
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
@@ -5763,7 +5832,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5763
5832
|
Escape: view?.state.facet(editorInputMode).noTabster
|
5764
5833
|
}
|
5765
5834
|
});
|
5766
|
-
const handleKeyUp =
|
5835
|
+
const handleKeyUp = useCallback2((event) => {
|
5767
5836
|
const { key, target, currentTarget } = event;
|
5768
5837
|
if (target === currentTarget) {
|
5769
5838
|
switch (key) {
|
@@ -5822,7 +5891,7 @@ export {
|
|
5822
5891
|
commentsState,
|
5823
5892
|
convertTreeToJson,
|
5824
5893
|
createBasicExtensions,
|
5825
|
-
|
5894
|
+
createComment,
|
5826
5895
|
createDataExtensions,
|
5827
5896
|
createEditorAction,
|
5828
5897
|
createEditorActionGroup,
|
@@ -5900,7 +5969,6 @@ export {
|
|
5900
5969
|
toggleStyle,
|
5901
5970
|
translations_default as translations,
|
5902
5971
|
typewriter,
|
5903
|
-
useActionHandler,
|
5904
5972
|
useCommentClickListener,
|
5905
5973
|
useCommentState,
|
5906
5974
|
useComments,
|