@dxos/react-ui-editor 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b
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 +1110 -1127
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +1133 -1164
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +1110 -1127
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/InputMode.stories.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +4 -0
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/comment.d.ts +17 -0
- package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/headings.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts +3 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts +58 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/viewMode.d.ts +18 -0
- package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +3 -4
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/editorAction.d.ts +12 -0
- package/dist/types/src/extensions/markdown/editorAction.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +14 -12
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
- package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
- package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -29
- package/src/InputMode.stories.tsx +7 -10
- package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
- package/src/components/EditorToolbar/blocks.ts +41 -0
- package/src/components/EditorToolbar/comment.ts +23 -0
- package/src/components/EditorToolbar/formatting.ts +41 -0
- package/src/components/EditorToolbar/headings.ts +59 -0
- package/src/components/EditorToolbar/index.ts +6 -0
- package/src/components/EditorToolbar/lists.ts +40 -0
- package/src/components/EditorToolbar/util.ts +65 -0
- package/src/components/EditorToolbar/viewMode.ts +48 -0
- package/src/components/index.ts +1 -1
- package/src/extensions/comments.ts +8 -15
- package/src/extensions/markdown/decorate.ts +1 -1
- package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
- package/src/extensions/markdown/formatting.test.ts +7 -6
- package/src/extensions/markdown/formatting.ts +20 -24
- package/src/extensions/markdown/index.ts +1 -1
- package/src/extensions/markdown/styles.ts +21 -0
- package/src/hooks/useActionHandler.ts +4 -4
- package/src/index.ts +4 -0
- package/src/styles/markdown.ts +1 -1
- package/src/styles/stack-item-content-class-names.ts +17 -0
- package/src/styles/theme.ts +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/index.d.ts +0 -2
- package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/action.d.ts +0 -9
- package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
- package/src/components/Toolbar/Toolbar.tsx +0 -522
- package/src/components/Toolbar/index.ts +0 -5
@@ -39,258 +39,860 @@ import { EditorView as EditorView21, keymap as keymap11 } from "@codemirror/view
|
|
39
39
|
import { tags as tags2 } from "@lezer/highlight";
|
40
40
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
41
41
|
|
42
|
-
// packages/ui/react-ui-editor/src/components/
|
43
|
-
import
|
44
|
-
import {
|
45
|
-
import
|
46
|
-
import {
|
47
|
-
import { Button, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
48
|
-
import { getSize } from "@dxos/react-ui-theme";
|
42
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
43
|
+
import React, { useCallback } from "react";
|
44
|
+
import { ElevationProvider } from "@dxos/react-ui";
|
45
|
+
import { ToolbarMenu, MenuProvider, useMenuActions, createGapSeparator } from "@dxos/react-ui-menu";
|
46
|
+
import { textBlockWidth } from "@dxos/react-ui-theme";
|
49
47
|
|
50
|
-
// packages/ui/react-ui-editor/src/
|
51
|
-
import {
|
52
|
-
import {
|
53
|
-
import {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
var
|
58
|
-
|
59
|
-
|
60
|
-
|
48
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
|
49
|
+
import { useMemo } from "react";
|
50
|
+
import { create } from "@dxos/live-object";
|
51
|
+
import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
|
52
|
+
var useEditorToolbarState = (initialState = {}) => {
|
53
|
+
return useMemo(() => create(initialState), []);
|
54
|
+
};
|
55
|
+
var createEditorAction = (payload, icon, label = [
|
56
|
+
`${payload.type} label`,
|
57
|
+
{
|
58
|
+
ns: translationKey
|
61
59
|
}
|
60
|
+
], id = payload.type) => createMenuAction(id, {
|
61
|
+
icon,
|
62
|
+
label,
|
63
|
+
...payload
|
64
|
+
});
|
65
|
+
var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
|
66
|
+
icon,
|
67
|
+
iconOnly: true,
|
68
|
+
...props
|
62
69
|
});
|
70
|
+
var editorToolbarSearch = createEditorAction({
|
71
|
+
type: "search"
|
72
|
+
}, "ph--magnifying-glass--regular");
|
63
73
|
|
64
|
-
// packages/ui/react-ui-editor/src/
|
65
|
-
var
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
};
|
70
|
-
var
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
74
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
|
75
|
+
var createBlockGroupAction = (value) => createEditorActionGroup("block", {
|
76
|
+
variant: "toggleGroup",
|
77
|
+
selectCardinality: "single",
|
78
|
+
value
|
79
|
+
});
|
80
|
+
var createBlockActions = (value, blankLine) => Object.entries({
|
81
|
+
blockquote: "ph--quotes--regular",
|
82
|
+
codeblock: "ph--code-block--regular",
|
83
|
+
table: "ph--table--regular"
|
84
|
+
}).map(([type, icon]) => {
|
85
|
+
return createEditorAction({
|
86
|
+
type,
|
87
|
+
checked: type === value,
|
88
|
+
...type === "table" && {
|
89
|
+
disabled: !!blankLine
|
90
|
+
}
|
91
|
+
}, icon);
|
92
|
+
});
|
93
|
+
var createBlocks = (state) => {
|
94
|
+
const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
|
95
|
+
const blockGroupAction = createBlockGroupAction(value);
|
96
|
+
const blockActions = createBlockActions(value, state.blankLine);
|
97
|
+
return {
|
98
|
+
nodes: [
|
99
|
+
blockGroupAction,
|
100
|
+
...blockActions
|
101
|
+
],
|
102
|
+
edges: [
|
103
|
+
{
|
104
|
+
source: "root",
|
105
|
+
target: "block"
|
106
|
+
},
|
107
|
+
...blockActions.map(({ id }) => ({
|
108
|
+
source: blockGroupAction.id,
|
109
|
+
target: id
|
110
|
+
}))
|
111
|
+
]
|
112
|
+
};
|
97
113
|
};
|
98
114
|
|
99
|
-
// packages/ui/react-ui-editor/src/
|
100
|
-
|
101
|
-
var
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
|
116
|
+
var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
|
117
|
+
var createCommentAction = (label) => createEditorAction({
|
118
|
+
type: "comment",
|
119
|
+
testId: "editor.toolbar.comment"
|
120
|
+
}, "ph--chat-text--regular", label);
|
121
|
+
var createComment = (state) => ({
|
122
|
+
nodes: [
|
123
|
+
createCommentAction([
|
124
|
+
commentLabel(state.comment, state.selection),
|
125
|
+
{
|
126
|
+
ns: translationKey
|
127
|
+
}
|
128
|
+
])
|
129
|
+
],
|
130
|
+
edges: [
|
131
|
+
{
|
132
|
+
source: "root",
|
133
|
+
target: "comment"
|
113
134
|
}
|
135
|
+
]
|
136
|
+
});
|
137
|
+
|
138
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
|
139
|
+
var formats = {
|
140
|
+
strong: "ph--text-b--regular",
|
141
|
+
emphasis: "ph--text-italic--regular",
|
142
|
+
strikethrough: "ph--text-strikethrough--regular",
|
143
|
+
code: "ph--code--regular",
|
144
|
+
link: "ph--link--regular"
|
145
|
+
};
|
146
|
+
var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
|
147
|
+
variant: "toggleGroup",
|
148
|
+
selectCardinality: "multiple",
|
149
|
+
value: Object.keys(formats).filter((key) => !!formatting[key])
|
150
|
+
});
|
151
|
+
var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
|
152
|
+
type,
|
153
|
+
checked: !!formatting[type]
|
154
|
+
}, icon));
|
155
|
+
var createFormatting = (state) => {
|
156
|
+
const formattingGroupAction = createFormattingGroup(state);
|
157
|
+
const formattingActions = createFormattingActions(state);
|
158
|
+
return {
|
159
|
+
nodes: [
|
160
|
+
formattingGroupAction,
|
161
|
+
...formattingActions
|
162
|
+
],
|
163
|
+
edges: [
|
164
|
+
{
|
165
|
+
source: "root",
|
166
|
+
target: "formatting"
|
167
|
+
},
|
168
|
+
...formattingActions.map(({ id }) => ({
|
169
|
+
source: formattingGroupAction.id,
|
170
|
+
target: id
|
171
|
+
}))
|
172
|
+
]
|
114
173
|
};
|
115
174
|
};
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
175
|
+
|
176
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
|
177
|
+
var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
|
178
|
+
variant: "dropdownMenu",
|
179
|
+
applyActive: true,
|
180
|
+
selectCardinality: "single",
|
181
|
+
value
|
182
|
+
}, "ph--text-h--regular");
|
183
|
+
var createHeadingActions = (value) => Object.entries({
|
184
|
+
"0": "ph--paragraph--regular",
|
185
|
+
"1": "ph--text-h-one--regular",
|
186
|
+
"2": "ph--text-h-two--regular",
|
187
|
+
"3": "ph--text-h-three--regular",
|
188
|
+
"4": "ph--text-h-four--regular",
|
189
|
+
"5": "ph--text-h-five--regular",
|
190
|
+
"6": "ph--text-h-six--regular"
|
191
|
+
}).map(([levelStr, icon]) => {
|
192
|
+
const level = parseInt(levelStr);
|
193
|
+
return createEditorAction({
|
194
|
+
type: "heading",
|
195
|
+
data: level,
|
196
|
+
checked: value === levelStr
|
197
|
+
}, icon, [
|
198
|
+
"heading level label",
|
199
|
+
{
|
200
|
+
count: level,
|
201
|
+
ns: translationKey
|
202
|
+
}
|
203
|
+
], `heading--${levelStr}`);
|
204
|
+
});
|
205
|
+
var computeHeadingValue = (state) => {
|
206
|
+
const blockType = state ? state.blockType : "paragraph";
|
207
|
+
const header = blockType && /heading(\d)/.exec(blockType);
|
208
|
+
return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
|
127
209
|
};
|
128
|
-
var
|
129
|
-
|
130
|
-
|
210
|
+
var createHeadings = (state) => {
|
211
|
+
const headingValue = computeHeadingValue(state);
|
212
|
+
const headingGroupAction = createHeadingGroupAction(headingValue);
|
213
|
+
const headingActions = createHeadingActions(headingValue);
|
214
|
+
return {
|
215
|
+
nodes: [
|
216
|
+
headingGroupAction,
|
217
|
+
...headingActions
|
218
|
+
],
|
219
|
+
edges: [
|
220
|
+
{
|
221
|
+
source: "root",
|
222
|
+
target: "heading"
|
223
|
+
},
|
224
|
+
...headingActions.map(({ id }) => ({
|
225
|
+
source: headingGroupAction.id,
|
226
|
+
target: id
|
227
|
+
}))
|
228
|
+
]
|
229
|
+
};
|
131
230
|
};
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
231
|
+
|
232
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
|
233
|
+
var listStyles = {
|
234
|
+
bullet: "ph--list-bullets--regular",
|
235
|
+
ordered: "ph--list-numbers--regular",
|
236
|
+
task: "ph--list-checks--regular"
|
237
|
+
};
|
238
|
+
var createListGroupAction = (value) => createEditorActionGroup("list", {
|
239
|
+
variant: "toggleGroup",
|
240
|
+
selectCardinality: "single",
|
241
|
+
value
|
242
|
+
});
|
243
|
+
var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
|
244
|
+
type: `list-${listStyle}`,
|
245
|
+
checked: value === listStyle
|
246
|
+
}, icon));
|
247
|
+
var createLists = (state) => {
|
248
|
+
const value = state.listStyle ?? "";
|
249
|
+
const listGroupAction = createListGroupAction(value);
|
250
|
+
const listActionsMap = createListActions(value);
|
251
|
+
return {
|
252
|
+
nodes: [
|
253
|
+
listGroupAction,
|
254
|
+
...listActionsMap
|
255
|
+
],
|
256
|
+
edges: [
|
257
|
+
{
|
258
|
+
source: "root",
|
259
|
+
target: "list"
|
260
|
+
},
|
261
|
+
...listActionsMap.map(({ id }) => ({
|
262
|
+
source: listGroupAction.id,
|
263
|
+
target: id
|
264
|
+
}))
|
265
|
+
]
|
266
|
+
};
|
267
|
+
};
|
268
|
+
|
269
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/viewMode.ts
|
270
|
+
var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
|
271
|
+
variant: "dropdownMenu",
|
272
|
+
applyActive: true,
|
273
|
+
selectCardinality: "single",
|
274
|
+
value
|
275
|
+
}, "ph--eye--regular");
|
276
|
+
var createViewModeActions = (value) => Object.entries({
|
277
|
+
preview: "ph--eye--regular",
|
278
|
+
source: "ph--pencil-simple--regular",
|
279
|
+
readonly: "ph--pencil-slash--regular"
|
280
|
+
}).map(([viewMode, icon]) => {
|
281
|
+
return createEditorAction({
|
282
|
+
type: "view-mode",
|
283
|
+
data: viewMode,
|
284
|
+
checked: viewMode === value
|
285
|
+
}, icon, [
|
286
|
+
`${viewMode} mode label`,
|
287
|
+
{
|
288
|
+
ns: translationKey
|
136
289
|
}
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
290
|
+
], `view-mode--${viewMode}`);
|
291
|
+
});
|
292
|
+
var createViewMode = (state) => {
|
293
|
+
const value = state.viewMode ?? "source";
|
294
|
+
const viewModeGroupAction = createViewModeGroupAction(value);
|
295
|
+
const viewModeActions = createViewModeActions(value);
|
296
|
+
return {
|
297
|
+
nodes: [
|
298
|
+
viewModeGroupAction,
|
299
|
+
...viewModeActions
|
300
|
+
],
|
301
|
+
edges: [
|
302
|
+
{
|
303
|
+
source: "root",
|
304
|
+
target: "viewMode"
|
305
|
+
},
|
306
|
+
...viewModeActions.map(({ id }) => ({
|
307
|
+
source: viewModeGroupAction.id,
|
308
|
+
target: id
|
309
|
+
}))
|
310
|
+
]
|
311
|
+
};
|
157
312
|
};
|
158
313
|
|
159
|
-
// packages/ui/react-ui-editor/src/
|
160
|
-
|
161
|
-
|
314
|
+
// packages/ui/react-ui-editor/src/styles/stack-item-content-class-names.ts
|
315
|
+
import { mx } from "@dxos/react-ui-theme";
|
316
|
+
var stackItemContentEditorClassNames = (role) => mx("dx-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
|
317
|
+
var stackItemContentToolbarClassNames = (role) => mx("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
|
318
|
+
|
319
|
+
// packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
|
320
|
+
var createToolbar = ({ state, customActions, ...features }) => {
|
321
|
+
const nodes = [];
|
322
|
+
const edges = [];
|
323
|
+
if (features.headings ?? true) {
|
324
|
+
const headings2 = createHeadings(state);
|
325
|
+
nodes.push(...headings2.nodes);
|
326
|
+
edges.push(...headings2.edges);
|
327
|
+
}
|
328
|
+
if (features.formatting ?? true) {
|
329
|
+
const formatting = createFormatting(state);
|
330
|
+
nodes.push(...formatting.nodes);
|
331
|
+
edges.push(...formatting.edges);
|
332
|
+
}
|
333
|
+
if (features.lists ?? true) {
|
334
|
+
const lists = createLists(state);
|
335
|
+
nodes.push(...lists.nodes);
|
336
|
+
edges.push(...lists.edges);
|
337
|
+
}
|
338
|
+
if (features.blocks ?? true) {
|
339
|
+
const blocks = createBlocks(state);
|
340
|
+
nodes.push(...blocks.nodes);
|
341
|
+
edges.push(...blocks.edges);
|
342
|
+
}
|
343
|
+
if (customActions) {
|
344
|
+
const custom = customActions();
|
345
|
+
nodes.push(...custom.nodes);
|
346
|
+
edges.push(...custom.edges);
|
347
|
+
}
|
348
|
+
const editorToolbarGap = createGapSeparator();
|
349
|
+
nodes.push(...editorToolbarGap.nodes);
|
350
|
+
edges.push(...editorToolbarGap.edges);
|
351
|
+
if (features.comment ?? true) {
|
352
|
+
const comment = createComment(state);
|
353
|
+
nodes.push(...comment.nodes);
|
354
|
+
edges.push(...comment.edges);
|
355
|
+
}
|
356
|
+
if (features.search ?? true) {
|
357
|
+
nodes.push(editorToolbarSearch);
|
358
|
+
edges.push({
|
359
|
+
source: "root",
|
360
|
+
target: editorToolbarSearch.id
|
361
|
+
});
|
362
|
+
}
|
363
|
+
if (features.viewMode ?? true) {
|
364
|
+
const viewMode = createViewMode(state);
|
365
|
+
nodes.push(...viewMode.nodes);
|
366
|
+
edges.push(...viewMode.edges);
|
367
|
+
}
|
162
368
|
return {
|
163
|
-
|
164
|
-
|
165
|
-
top: rect.top,
|
166
|
-
bottom: rect.bottom
|
369
|
+
nodes,
|
370
|
+
edges
|
167
371
|
};
|
168
372
|
};
|
169
|
-
var
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
return
|
373
|
+
var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
|
374
|
+
const menuCreator = useCallback(() => createToolbar(props), [
|
375
|
+
props
|
376
|
+
]);
|
377
|
+
const { resolveGroupItems } = useMenuActions(menuCreator);
|
378
|
+
return {
|
379
|
+
resolveGroupItems,
|
380
|
+
onAction
|
381
|
+
};
|
175
382
|
};
|
176
|
-
var
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
}
|
182
|
-
|
183
|
-
}
|
383
|
+
var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
|
384
|
+
const menuProps = useEditorToolbarActionGraph(props);
|
385
|
+
return /* @__PURE__ */ React.createElement("div", {
|
386
|
+
role: "none",
|
387
|
+
className: stackItemContentToolbarClassNames(role)
|
388
|
+
}, /* @__PURE__ */ React.createElement(ElevationProvider, {
|
389
|
+
elevation: role === "section" ? "positioned" : "base"
|
390
|
+
}, /* @__PURE__ */ React.createElement(MenuProvider, {
|
391
|
+
...menuProps,
|
392
|
+
attendableId
|
393
|
+
}, /* @__PURE__ */ React.createElement(ToolbarMenu, {
|
394
|
+
classNames: [
|
395
|
+
textBlockWidth,
|
396
|
+
"!bg-transparent",
|
397
|
+
classNames
|
398
|
+
]
|
399
|
+
}))));
|
184
400
|
};
|
185
401
|
|
186
|
-
// packages/ui/react-ui-editor/src/
|
187
|
-
import
|
188
|
-
import {
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
402
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
403
|
+
import { EditorView } from "@codemirror/view";
|
404
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
405
|
+
|
406
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
407
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
408
|
+
var headings = {
|
409
|
+
1: "text-4xl",
|
410
|
+
2: "text-3xl",
|
411
|
+
3: "text-2xl",
|
412
|
+
4: "text-xl",
|
413
|
+
5: "text-lg",
|
414
|
+
6: ""
|
415
|
+
};
|
416
|
+
var theme = {
|
417
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
418
|
+
codeMark: "font-mono text-primary-500",
|
419
|
+
mark: "opacity-50",
|
420
|
+
heading: (level) => {
|
421
|
+
return mx2(headings[level], "dark:text-primary-400");
|
200
422
|
}
|
201
|
-
return el;
|
202
423
|
};
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
424
|
+
|
425
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
426
|
+
import get from "lodash.get";
|
427
|
+
import { tokens } from "@dxos/react-ui-theme";
|
428
|
+
var getToken = (path, defaultValue) => {
|
429
|
+
const value = get(tokens, path, defaultValue);
|
430
|
+
return value?.toString() ?? "";
|
208
431
|
};
|
432
|
+
var fontBody = getToken("fontFamily.body");
|
433
|
+
var fontMono = getToken("fontFamily.mono");
|
209
434
|
|
210
|
-
// packages/ui/react-ui-editor/src/
|
211
|
-
var
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
}
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
435
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
436
|
+
var defaultTheme = {
|
437
|
+
"&": {},
|
438
|
+
"&.cm-focused": {
|
439
|
+
outline: "none"
|
440
|
+
},
|
441
|
+
/**
|
442
|
+
* Scroller
|
443
|
+
*/
|
444
|
+
".cm-scroller": {
|
445
|
+
overflowY: "auto"
|
446
|
+
},
|
447
|
+
/**
|
448
|
+
* Content
|
449
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
450
|
+
*/
|
451
|
+
".cm-content": {
|
452
|
+
padding: "unset",
|
453
|
+
fontFamily: fontBody,
|
454
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
455
|
+
fontSize: "16px",
|
456
|
+
lineHeight: 1.5,
|
457
|
+
color: "unset"
|
458
|
+
},
|
459
|
+
/**
|
460
|
+
* Gutters
|
461
|
+
* NOTE: Gutters should have the same top margin as the content.
|
462
|
+
* NOTE: They can't be transparent since the content needs to scroll below.
|
463
|
+
*/
|
464
|
+
".cm-gutters": {
|
465
|
+
background: "var(--surface-bg)",
|
466
|
+
borderRight: "none"
|
467
|
+
},
|
468
|
+
".cm-gutter": {},
|
469
|
+
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
470
|
+
minWidth: "40px",
|
471
|
+
alignContent: "center"
|
472
|
+
},
|
473
|
+
/**
|
474
|
+
* Height is set to match the corresponding line.
|
475
|
+
*/
|
476
|
+
".cm-gutterElement": {
|
477
|
+
alignItems: "center",
|
478
|
+
fontSize: "16px"
|
479
|
+
},
|
480
|
+
/**
|
481
|
+
* Line.
|
482
|
+
*/
|
483
|
+
".cm-line": {
|
484
|
+
paddingInline: 0
|
485
|
+
},
|
486
|
+
".cm-activeLine": {
|
487
|
+
background: "var(--dx-cmActiveLine)"
|
488
|
+
},
|
489
|
+
/**
|
490
|
+
* Cursor (layer).
|
491
|
+
*/
|
492
|
+
".cm-cursor, .cm-dropCursor": {
|
493
|
+
borderLeft: "2px solid var(--dx-cmCursor)"
|
494
|
+
},
|
495
|
+
".cm-placeholder": {
|
496
|
+
color: "var(--dx-subdued)"
|
497
|
+
},
|
498
|
+
/**
|
499
|
+
* Selection (layer).
|
500
|
+
*/
|
501
|
+
".cm-selectionBackground": {
|
502
|
+
background: "var(--dx-cmSelection)"
|
503
|
+
},
|
504
|
+
/**
|
505
|
+
* Search.
|
506
|
+
* NOTE: Matches comment.
|
507
|
+
*/
|
508
|
+
".cm-searchMatch": {
|
509
|
+
margin: "0 -3px",
|
510
|
+
padding: "3px",
|
511
|
+
borderRadius: "3px",
|
512
|
+
background: "var(--dx-cmHighlightSurface)",
|
513
|
+
color: "var(--dx-cmHighlight)"
|
514
|
+
},
|
515
|
+
".cm-searchMatch-selected": {
|
516
|
+
textDecoration: "underline"
|
517
|
+
},
|
518
|
+
/**
|
519
|
+
* Link.
|
520
|
+
*/
|
521
|
+
".cm-link": {
|
522
|
+
textDecorationLine: "underline",
|
523
|
+
textDecorationThickness: "1px",
|
524
|
+
textUnderlineOffset: "2px",
|
525
|
+
borderRadius: ".125rem"
|
526
|
+
},
|
527
|
+
".cm-link > span": {
|
528
|
+
color: "var(--dx-accentText)"
|
529
|
+
},
|
530
|
+
/**
|
531
|
+
* Tooltip.
|
532
|
+
*/
|
533
|
+
".cm-tooltip": {
|
534
|
+
background: "var(--dx-baseSurface)"
|
535
|
+
},
|
536
|
+
".cm-tooltip-below": {},
|
537
|
+
/**
|
538
|
+
* Autocomplete.
|
539
|
+
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
540
|
+
*/
|
541
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
542
|
+
marginTop: "4px",
|
543
|
+
marginLeft: "-3px"
|
544
|
+
},
|
545
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
546
|
+
maxHeight: "20em"
|
547
|
+
},
|
548
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
549
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
550
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
551
|
+
paddingLeft: "4px !important",
|
552
|
+
borderBottom: "none !important",
|
553
|
+
color: "var(--dx-accentText)"
|
554
|
+
},
|
555
|
+
".cm-tooltip.cm-completionInfo": {
|
556
|
+
width: "360px !important",
|
557
|
+
margin: "-10px 1px 0 1px",
|
558
|
+
padding: "8px !important",
|
559
|
+
borderColor: "var(--dx-separator)"
|
560
|
+
},
|
561
|
+
".cm-completionIcon": {
|
562
|
+
display: "none"
|
563
|
+
},
|
564
|
+
".cm-completionLabel": {
|
565
|
+
fontFamily: fontBody
|
566
|
+
},
|
567
|
+
".cm-completionMatchedText": {
|
568
|
+
textDecoration: "none !important",
|
569
|
+
opacity: 0.5
|
570
|
+
},
|
571
|
+
/**
|
572
|
+
* Panels
|
573
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
574
|
+
*
|
575
|
+
* Find/replace panel.
|
576
|
+
* <div class="cm-announced">...</div>
|
577
|
+
* <div class="cm-scroller">...</div>
|
578
|
+
* <div class="cm-panels cm-panels-bottom">
|
579
|
+
* <div class="cm-search cm-panel">
|
580
|
+
* <input class="cm-textfield" />
|
581
|
+
* <button class="cm-button">...</button>
|
582
|
+
* <label><input type="checkbox" />...</label>
|
583
|
+
* </div>
|
584
|
+
* </div
|
585
|
+
*/
|
586
|
+
// TODO(burdon): Implement custom panel (with icon buttons).
|
587
|
+
".cm-panels": {},
|
588
|
+
".cm-panel": {
|
589
|
+
fontFamily: fontBody,
|
590
|
+
backgroundColor: "var(--surface-bg)"
|
591
|
+
},
|
592
|
+
".cm-panel input, .cm-panel button, .cm-panel label": {
|
593
|
+
color: "var(--dx-subdued)",
|
594
|
+
fontFamily: fontBody,
|
595
|
+
fontSize: "14px",
|
596
|
+
all: "unset",
|
597
|
+
margin: "3px !important",
|
598
|
+
padding: "2px 6px !important",
|
599
|
+
outline: "1px solid transparent"
|
600
|
+
},
|
601
|
+
".cm-panel input, .cm-panel button": {
|
602
|
+
backgroundColor: "var(--dx-input)"
|
603
|
+
},
|
604
|
+
".cm-panel input:focus, .cm-panel button:focus": {
|
605
|
+
outline: "1px solid var(--dx-accentFocusIndicator)"
|
606
|
+
},
|
607
|
+
".cm-panel label": {
|
608
|
+
display: "inline-flex",
|
609
|
+
alignItems: "center",
|
610
|
+
cursor: "pointer"
|
611
|
+
},
|
612
|
+
".cm-panel input.cm-textfield": {},
|
613
|
+
".cm-panel input[type=checkbox]": {
|
614
|
+
width: "8px",
|
615
|
+
height: "8px",
|
616
|
+
marginRight: "6px !important",
|
617
|
+
padding: "2px !important",
|
618
|
+
color: "var(--dx-accentFocusIndicator)"
|
619
|
+
},
|
620
|
+
".cm-panel button": {
|
621
|
+
"&:hover": {
|
622
|
+
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
623
|
+
},
|
624
|
+
"&:active": {
|
625
|
+
backgroundColor: "var(--dx-accentSurfaceHover)"
|
243
626
|
}
|
244
|
-
}
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
], (state) => {
|
250
|
-
const annotations2 = state.field(annotationsState);
|
251
|
-
const decorations = annotations2.map((annotation) => {
|
252
|
-
const range = Cursor.getRangeFromCursor(state, annotation.cursor);
|
253
|
-
return range && annotationMark.range(range.from, range.to);
|
254
|
-
}).filter(isNotFalsy);
|
255
|
-
return Decoration.set(decorations);
|
256
|
-
}),
|
257
|
-
styles
|
258
|
-
];
|
627
|
+
},
|
628
|
+
".cm-panel.cm-search": {
|
629
|
+
padding: "4px",
|
630
|
+
borderTop: "1px solid var(--dx-separator)"
|
631
|
+
}
|
259
632
|
};
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
633
|
+
|
634
|
+
// packages/ui/react-ui-editor/src/defaults.ts
|
635
|
+
var margin = "!mt-[1rem]";
|
636
|
+
var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
|
637
|
+
var editorFullWidth = mx3(margin);
|
638
|
+
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
639
|
+
var editorGutter = EditorView.theme({
|
640
|
+
// Match margin from content.
|
641
|
+
".cm-gutters": {
|
642
|
+
marginTop: "16px",
|
643
|
+
paddingRight: "1rem"
|
644
|
+
}
|
645
|
+
});
|
646
|
+
var editorMonospace = EditorView.theme({
|
647
|
+
".cm-content": {
|
648
|
+
fontFamily: fontMono
|
265
649
|
}
|
266
650
|
});
|
267
651
|
|
268
|
-
// packages/ui/react-ui-editor/src/extensions/
|
269
|
-
import {
|
270
|
-
import {
|
271
|
-
import {
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
652
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
653
|
+
import { StateField } from "@codemirror/state";
|
654
|
+
import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
|
655
|
+
import { isNotFalsy } from "@dxos/util";
|
656
|
+
|
657
|
+
// packages/ui/react-ui-editor/src/util/facet.ts
|
658
|
+
import { Facet } from "@codemirror/state";
|
659
|
+
var singleValueFacet = (defaultValue) => Facet.define({
|
660
|
+
// Called immediately.
|
661
|
+
combine: (providers) => {
|
662
|
+
return providers[0] ?? defaultValue;
|
663
|
+
}
|
664
|
+
});
|
665
|
+
|
666
|
+
// packages/ui/react-ui-editor/src/util/cursor.ts
|
667
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
668
|
+
var defaultCursorConverter = {
|
669
|
+
toCursor: (position) => position.toString(),
|
670
|
+
fromCursor: (cursor) => parseInt(cursor)
|
671
|
+
};
|
672
|
+
var Cursor = class _Cursor {
|
673
|
+
static {
|
674
|
+
this.converter = singleValueFacet(defaultCursorConverter);
|
675
|
+
}
|
676
|
+
static {
|
677
|
+
this.getCursorFromRange = (state, range) => {
|
678
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
679
|
+
const from = cursorConverter2.toCursor(range.from);
|
680
|
+
const to = cursorConverter2.toCursor(range.to, -1);
|
681
|
+
return [
|
682
|
+
from,
|
683
|
+
to
|
684
|
+
].join(":");
|
685
|
+
};
|
686
|
+
}
|
687
|
+
static {
|
688
|
+
this.getRangeFromCursor = (state, cursor) => {
|
689
|
+
const cursorConverter2 = state.facet(_Cursor.converter);
|
690
|
+
const parts = cursor.split(":");
|
691
|
+
const from = cursorConverter2.fromCursor(parts[0]);
|
692
|
+
const to = cursorConverter2.fromCursor(parts[1]);
|
693
|
+
return from !== void 0 && to !== void 0 ? {
|
694
|
+
from,
|
695
|
+
to
|
696
|
+
} : void 0;
|
697
|
+
};
|
698
|
+
}
|
699
|
+
};
|
700
|
+
|
701
|
+
// packages/ui/react-ui-editor/src/util/debug.ts
|
702
|
+
import { log } from "@dxos/log";
|
703
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
|
704
|
+
var wrapWithCatch = (fn) => {
|
705
|
+
return (...args) => {
|
706
|
+
try {
|
707
|
+
return fn(...args);
|
708
|
+
} catch (err) {
|
709
|
+
log.catch(err, void 0, {
|
710
|
+
F: __dxlog_file,
|
711
|
+
L: 15,
|
712
|
+
S: void 0,
|
713
|
+
C: (f, a) => f(...a)
|
714
|
+
});
|
715
|
+
}
|
716
|
+
};
|
717
|
+
};
|
718
|
+
var callbackWrapper = (fn) => (...args) => {
|
719
|
+
try {
|
720
|
+
return fn(...args);
|
721
|
+
} catch (err) {
|
722
|
+
log.catch(err, void 0, {
|
723
|
+
F: __dxlog_file,
|
724
|
+
L: 29,
|
725
|
+
S: void 0,
|
726
|
+
C: (f, a) => f(...a)
|
727
|
+
});
|
728
|
+
}
|
729
|
+
};
|
730
|
+
var debugDispatcher = (trs, view) => {
|
731
|
+
logChanges(trs);
|
732
|
+
view.update(trs);
|
733
|
+
};
|
734
|
+
var logChanges = (trs) => {
|
735
|
+
const changes = trs.flatMap((tr) => {
|
736
|
+
if (tr.changes.empty) {
|
737
|
+
return void 0;
|
738
|
+
}
|
739
|
+
const changes2 = [];
|
740
|
+
tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
|
741
|
+
fromA,
|
742
|
+
toA,
|
743
|
+
fromB,
|
744
|
+
toB,
|
745
|
+
inserted: inserted.toString()
|
746
|
+
})));
|
747
|
+
return changes2;
|
748
|
+
}).filter(Boolean);
|
749
|
+
if (changes.length) {
|
750
|
+
log.info("changes", {
|
751
|
+
changes
|
752
|
+
}, {
|
753
|
+
F: __dxlog_file,
|
754
|
+
L: 62,
|
755
|
+
S: void 0,
|
756
|
+
C: (f, a) => f(...a)
|
757
|
+
});
|
758
|
+
}
|
759
|
+
};
|
760
|
+
|
761
|
+
// packages/ui/react-ui-editor/src/util/dom.ts
|
762
|
+
var flattenRect = (rect, left) => {
|
763
|
+
const x = left ? rect.left : rect.right;
|
764
|
+
return {
|
765
|
+
left: x,
|
766
|
+
right: x,
|
767
|
+
top: rect.top,
|
768
|
+
bottom: rect.bottom
|
769
|
+
};
|
770
|
+
};
|
771
|
+
var scratchRange;
|
772
|
+
var textRange = (node, from, to = from) => {
|
773
|
+
const range = scratchRange || (scratchRange = document.createRange());
|
774
|
+
range.setEnd(node, to);
|
775
|
+
range.setStart(node, from);
|
776
|
+
return range;
|
777
|
+
};
|
778
|
+
var clientRectsFor = (dom) => {
|
779
|
+
if (dom.nodeType === 3) {
|
780
|
+
return textRange(dom, 0, dom.nodeValue.length).getClientRects();
|
781
|
+
} else if (dom.nodeType === 1) {
|
782
|
+
return dom.getClientRects();
|
783
|
+
} else {
|
784
|
+
return [];
|
785
|
+
}
|
786
|
+
};
|
787
|
+
|
788
|
+
// packages/ui/react-ui-editor/src/util/react.tsx
|
789
|
+
import React2 from "react";
|
790
|
+
import { createRoot } from "react-dom/client";
|
791
|
+
import { ThemeProvider } from "@dxos/react-ui";
|
792
|
+
import { defaultTx } from "@dxos/react-ui-theme";
|
793
|
+
var createElement = (tag, options, children) => {
|
794
|
+
const el = document.createElement(tag);
|
795
|
+
if (options?.className) {
|
796
|
+
el.className = options.className;
|
797
|
+
}
|
798
|
+
if (children) {
|
799
|
+
el.append(...Array.isArray(children) ? children : [
|
800
|
+
children
|
801
|
+
]);
|
802
|
+
}
|
803
|
+
return el;
|
804
|
+
};
|
805
|
+
var renderRoot = (root, node) => {
|
806
|
+
createRoot(root).render(/* @__PURE__ */ React2.createElement(ThemeProvider, {
|
807
|
+
tx: defaultTx
|
808
|
+
}, node));
|
809
|
+
return root;
|
810
|
+
};
|
811
|
+
|
812
|
+
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
813
|
+
var annotationMark = Decoration.mark({
|
814
|
+
class: "cm-annotation"
|
815
|
+
});
|
816
|
+
var annotations = (options = {}) => {
|
817
|
+
const match = (state) => {
|
818
|
+
const annotations2 = [];
|
819
|
+
const text = state.doc.toString();
|
820
|
+
if (options.match) {
|
821
|
+
const matches = text.matchAll(options.match);
|
822
|
+
for (const match2 of matches) {
|
823
|
+
const from = match2.index;
|
824
|
+
const to = from + match2[0].length;
|
825
|
+
const cursor = Cursor.getCursorFromRange(state, {
|
826
|
+
from,
|
827
|
+
to
|
828
|
+
});
|
829
|
+
annotations2.push({
|
830
|
+
cursor
|
831
|
+
});
|
832
|
+
}
|
833
|
+
}
|
834
|
+
return annotations2;
|
835
|
+
};
|
836
|
+
const annotationsState = StateField.define({
|
837
|
+
create: (state) => {
|
838
|
+
return match(state);
|
839
|
+
},
|
840
|
+
update: (value, tr) => {
|
841
|
+
if (!tr.changes.empty) {
|
842
|
+
return match(tr.state);
|
843
|
+
}
|
844
|
+
return value;
|
845
|
+
}
|
846
|
+
});
|
847
|
+
return [
|
848
|
+
annotationsState,
|
849
|
+
EditorView2.decorations.compute([
|
850
|
+
annotationsState
|
851
|
+
], (state) => {
|
852
|
+
const annotations2 = state.field(annotationsState);
|
853
|
+
const decorations = annotations2.map((annotation) => {
|
854
|
+
const range = Cursor.getRangeFromCursor(state, annotation.cursor);
|
855
|
+
return range && annotationMark.range(range.from, range.to);
|
856
|
+
}).filter(isNotFalsy);
|
857
|
+
return Decoration.set(decorations);
|
858
|
+
}),
|
859
|
+
styles
|
860
|
+
];
|
861
|
+
};
|
862
|
+
var styles = EditorView2.theme({
|
863
|
+
".cm-annotation": {
|
864
|
+
textDecoration: "underline",
|
865
|
+
textDecorationStyle: "wavy",
|
866
|
+
textDecorationColor: "var(--dx-error)"
|
867
|
+
}
|
868
|
+
});
|
869
|
+
|
870
|
+
// packages/ui/react-ui-editor/src/extensions/autocomplete.ts
|
871
|
+
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
872
|
+
import { markdownLanguage } from "@codemirror/lang-markdown";
|
873
|
+
import { keymap } from "@codemirror/view";
|
874
|
+
var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
875
|
+
const extensions = [
|
876
|
+
// https://codemirror.net/docs/ref/#view.keymap
|
877
|
+
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
878
|
+
// TODO(burdon): Set custom keymap.
|
879
|
+
keymap.of(completionKeymap),
|
880
|
+
// https://codemirror.net/examples/autocompletion
|
881
|
+
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
882
|
+
autocompletion({
|
883
|
+
activateOnTyping,
|
884
|
+
override,
|
885
|
+
closeOnBlur: !debug,
|
886
|
+
tooltipClass: () => "shadow rounded"
|
887
|
+
})
|
888
|
+
];
|
889
|
+
if (onSearch) {
|
890
|
+
extensions.push(
|
891
|
+
// TODO(burdon): Optional decoration via addToOptions
|
892
|
+
markdownLanguage.data.of({
|
893
|
+
autocomplete: (context) => {
|
894
|
+
const match = context.matchBefore(/\w*/);
|
895
|
+
if (!match || match.from === match.to && !context.explicit) {
|
294
896
|
return null;
|
295
897
|
}
|
296
898
|
return {
|
@@ -306,7 +908,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
|
|
306
908
|
|
307
909
|
// packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
|
308
910
|
import { StateField as StateField2 } from "@codemirror/state";
|
309
|
-
import { EditorView as
|
911
|
+
import { EditorView as EditorView3, ViewPlugin } from "@codemirror/view";
|
310
912
|
import { next as A3 } from "@dxos/automerge/automerge";
|
311
913
|
|
312
914
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
@@ -590,7 +1192,7 @@ var automerge = (accessor) => {
|
|
590
1192
|
}
|
591
1193
|
}),
|
592
1194
|
// Reconcile local updates.
|
593
|
-
|
1195
|
+
EditorView3.updateListener.of(({ view, changes }) => {
|
594
1196
|
if (!changes.empty) {
|
595
1197
|
syncer.reconcile(view, true);
|
596
1198
|
}
|
@@ -600,7 +1202,7 @@ var automerge = (accessor) => {
|
|
600
1202
|
|
601
1203
|
// packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
|
602
1204
|
import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
|
603
|
-
import { Decoration as Decoration2, EditorView as
|
1205
|
+
import { Decoration as Decoration2, EditorView as EditorView4, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
604
1206
|
import { Event } from "@dxos/async";
|
605
1207
|
import { Context } from "@dxos/context";
|
606
1208
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
|
@@ -774,7 +1376,7 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
774
1376
|
return true;
|
775
1377
|
}
|
776
1378
|
};
|
777
|
-
var styles2 =
|
1379
|
+
var styles2 = EditorView4.theme({
|
778
1380
|
".cm-collab-selection": {},
|
779
1381
|
".cm-collab-selectionLine": {
|
780
1382
|
padding: 0,
|
@@ -940,7 +1542,7 @@ var SpaceAwarenessProvider = class {
|
|
940
1542
|
};
|
941
1543
|
|
942
1544
|
// packages/ui/react-ui-editor/src/extensions/blast.ts
|
943
|
-
import { EditorView as
|
1545
|
+
import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
|
944
1546
|
import defaultsDeep from "lodash.defaultsdeep";
|
945
1547
|
import { invariant as invariant2 } from "@dxos/invariant";
|
946
1548
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
|
@@ -988,7 +1590,7 @@ var blast = (options = defaultOptions) => {
|
|
988
1590
|
};
|
989
1591
|
return [
|
990
1592
|
// Cursor moved.
|
991
|
-
|
1593
|
+
EditorView5.updateListener.of((update2) => {
|
992
1594
|
if (blaster?.node !== update2.view.scrollDOM) {
|
993
1595
|
if (blaster) {
|
994
1596
|
blaster.destroy();
|
@@ -1250,11 +1852,11 @@ var random = (min, max) => {
|
|
1250
1852
|
};
|
1251
1853
|
|
1252
1854
|
// packages/ui/react-ui-editor/src/extensions/command/command.ts
|
1253
|
-
import { EditorView as
|
1855
|
+
import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
|
1254
1856
|
|
1255
1857
|
// packages/ui/react-ui-editor/src/extensions/command/hint.ts
|
1256
1858
|
import { RangeSetBuilder } from "@codemirror/state";
|
1257
|
-
import { Decoration as Decoration3, EditorView as
|
1859
|
+
import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
|
1258
1860
|
|
1259
1861
|
// packages/ui/react-ui-editor/src/extensions/command/state.ts
|
1260
1862
|
import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
|
@@ -1420,7 +2022,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
|
|
1420
2022
|
}
|
1421
2023
|
}, {
|
1422
2024
|
provide: (plugin) => [
|
1423
|
-
|
2025
|
+
EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
|
1424
2026
|
]
|
1425
2027
|
});
|
1426
2028
|
|
@@ -1431,7 +2033,7 @@ var command = (options) => {
|
|
1431
2033
|
commandState,
|
1432
2034
|
keymap3.of(commandKeyBindings),
|
1433
2035
|
hintViewPlugin(options),
|
1434
|
-
|
2036
|
+
EditorView7.focusChangeEffect.of((_, focusing) => {
|
1435
2037
|
return focusing ? closeEffect.of(null) : null;
|
1436
2038
|
})
|
1437
2039
|
];
|
@@ -1440,16 +2042,16 @@ var command = (options) => {
|
|
1440
2042
|
// packages/ui/react-ui-editor/src/extensions/comments.ts
|
1441
2043
|
import { invertedEffects } from "@codemirror/commands";
|
1442
2044
|
import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
1443
|
-
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as
|
2045
|
+
import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
1444
2046
|
import sortBy from "lodash.sortby";
|
1445
|
-
import { useEffect, useMemo
|
2047
|
+
import { useEffect, useMemo as useMemo2 } from "react";
|
1446
2048
|
import { debounce as debounce2 } from "@dxos/async";
|
1447
2049
|
import { log as log4 } from "@dxos/log";
|
1448
2050
|
import { nonNullable } from "@dxos/util";
|
1449
2051
|
|
1450
2052
|
// packages/ui/react-ui-editor/src/extensions/selection.ts
|
1451
2053
|
import { Transaction } from "@codemirror/state";
|
1452
|
-
import { EditorView as
|
2054
|
+
import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
|
1453
2055
|
import { debounce } from "@dxos/async";
|
1454
2056
|
import { invariant as invariant3 } from "@dxos/invariant";
|
1455
2057
|
import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
@@ -1460,7 +2062,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
1460
2062
|
return {
|
1461
2063
|
selection,
|
1462
2064
|
scrollIntoView: !scrollTo,
|
1463
|
-
effects: scrollTo ?
|
2065
|
+
effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
|
1464
2066
|
yMargin: 96
|
1465
2067
|
}) : void 0,
|
1466
2068
|
annotations: Transaction.userEvent.of(stateRestoreAnnotation)
|
@@ -1502,7 +2104,7 @@ var selectionState = ({ getState, setState } = {}) => {
|
|
1502
2104
|
// setStateDebounced(id, {});
|
1503
2105
|
// },
|
1504
2106
|
// }),
|
1505
|
-
|
2107
|
+
EditorView8.updateListener.of(({ view, transactions }) => {
|
1506
2108
|
const id = view.state.facet(documentId);
|
1507
2109
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
1508
2110
|
return;
|
@@ -1583,7 +2185,7 @@ var commentsState = StateField4.define({
|
|
1583
2185
|
return value;
|
1584
2186
|
}
|
1585
2187
|
});
|
1586
|
-
var styles3 =
|
2188
|
+
var styles3 = EditorView9.theme({
|
1587
2189
|
".cm-comment, .cm-comment-current": {
|
1588
2190
|
margin: "0 -3px",
|
1589
2191
|
padding: "3px",
|
@@ -1603,7 +2205,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
|
|
1603
2205
|
"data-comment-id": id
|
1604
2206
|
}
|
1605
2207
|
});
|
1606
|
-
var commentsDecorations =
|
2208
|
+
var commentsDecorations = EditorView9.decorations.compute([
|
1607
2209
|
commentsState
|
1608
2210
|
], (state) => {
|
1609
2211
|
const { selection: { current }, comments: comments2 } = state.field(commentsState);
|
@@ -1612,7 +2214,7 @@ var commentsDecorations = EditorView8.decorations.compute([
|
|
1612
2214
|
if (!range) {
|
1613
2215
|
log4.warn("Invalid range:", range, {
|
1614
2216
|
F: __dxlog_file7,
|
1615
|
-
L:
|
2217
|
+
L: 144,
|
1616
2218
|
S: void 0,
|
1617
2219
|
C: (f, a) => f(...a)
|
1618
2220
|
});
|
@@ -1626,7 +2228,7 @@ var commentsDecorations = EditorView8.decorations.compute([
|
|
1626
2228
|
return Decoration4.set(decorations);
|
1627
2229
|
});
|
1628
2230
|
var commentClickedEffect = StateEffect3.define();
|
1629
|
-
var handleCommentClick =
|
2231
|
+
var handleCommentClick = EditorView9.domEventHandlers({
|
1630
2232
|
click: (event, view) => {
|
1631
2233
|
let target = event.target;
|
1632
2234
|
const editorRoot = view.dom;
|
@@ -1665,7 +2267,7 @@ var trackPastedComments = (onUpdate) => {
|
|
1665
2267
|
}
|
1666
2268
|
};
|
1667
2269
|
return [
|
1668
|
-
|
2270
|
+
EditorView9.domEventHandlers({
|
1669
2271
|
cut: handleTrack,
|
1670
2272
|
copy: handleTrack
|
1671
2273
|
}),
|
@@ -1687,7 +2289,7 @@ var trackPastedComments = (onUpdate) => {
|
|
1687
2289
|
return effects;
|
1688
2290
|
}),
|
1689
2291
|
// Handle paste or the undo of comment deletion.
|
1690
|
-
|
2292
|
+
EditorView9.updateListener.of((update2) => {
|
1691
2293
|
const restore = [];
|
1692
2294
|
for (let i = 0; i < update2.transactions.length; i++) {
|
1693
2295
|
const tr = update2.transactions[i];
|
@@ -1746,7 +2348,7 @@ var mapTrackedComment = (comment, changes) => ({
|
|
1746
2348
|
var restoreCommentEffect = StateEffect3.define({
|
1747
2349
|
map: mapTrackedComment
|
1748
2350
|
});
|
1749
|
-
var
|
2351
|
+
var createComment2 = (view) => {
|
1750
2352
|
const options = view.state.facet(optionsFacet);
|
1751
2353
|
const { from, to } = view.state.selection.main;
|
1752
2354
|
if (from === to) {
|
@@ -1791,7 +2393,7 @@ var comments = (options = {}) => {
|
|
1791
2393
|
options.onCreate && keymap5.of([
|
1792
2394
|
{
|
1793
2395
|
key: shortcut,
|
1794
|
-
run: callbackWrapper(
|
2396
|
+
run: callbackWrapper(createComment2)
|
1795
2397
|
}
|
1796
2398
|
]),
|
1797
2399
|
//
|
@@ -1827,7 +2429,7 @@ var comments = (options = {}) => {
|
|
1827
2429
|
//
|
1828
2430
|
// Track deleted ranges and update ranges for decorations.
|
1829
2431
|
//
|
1830
|
-
|
2432
|
+
EditorView9.updateListener.of(({ view, state, changes }) => {
|
1831
2433
|
let mod = false;
|
1832
2434
|
const { comments: comments2, ...value } = state.field(commentsState);
|
1833
2435
|
changes.iterChanges((from, to, from2, to2) => {
|
@@ -1859,7 +2461,7 @@ var comments = (options = {}) => {
|
|
1859
2461
|
//
|
1860
2462
|
// Track selection/proximity.
|
1861
2463
|
//
|
1862
|
-
|
2464
|
+
EditorView9.updateListener.of(({ view, state }) => {
|
1863
2465
|
let min = Infinity;
|
1864
2466
|
const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
|
1865
2467
|
const { head } = state.selection.main;
|
@@ -1913,7 +2515,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
1913
2515
|
anchor: range.from
|
1914
2516
|
} : void 0,
|
1915
2517
|
effects: [
|
1916
|
-
needsScroll ?
|
2518
|
+
needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
|
1917
2519
|
y: "center"
|
1918
2520
|
} : void 0) : [],
|
1919
2521
|
needsSelectionUpdate ? setSelection.of({
|
@@ -1924,415 +2526,179 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
1924
2526
|
}
|
1925
2527
|
}
|
1926
2528
|
};
|
1927
|
-
var selectionOverlapsComment = (state) => {
|
1928
|
-
const commentState = state.field(commentsState, false);
|
1929
|
-
if (commentState === void 0) {
|
1930
|
-
return false;
|
1931
|
-
}
|
1932
|
-
const { selection } = state;
|
1933
|
-
for (const range of selection.ranges) {
|
1934
|
-
if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
|
1935
|
-
return true;
|
1936
|
-
}
|
1937
|
-
}
|
1938
|
-
return false;
|
1939
|
-
};
|
1940
|
-
var hasActiveSelection = (state) => {
|
1941
|
-
return state.selection.ranges.some((range) => !range.empty);
|
1942
|
-
};
|
1943
|
-
var ExternalCommentSync = class {
|
1944
|
-
constructor(view, id, subscribe, getComments) {
|
1945
|
-
this.destroy = () => {
|
1946
|
-
this.unsubscribe();
|
1947
|
-
};
|
1948
|
-
const updateComments = () => {
|
1949
|
-
const comments2 = getComments();
|
1950
|
-
if (id === view.state.facet(documentId)) {
|
1951
|
-
queueMicrotask(() => view.dispatch({
|
1952
|
-
effects: setComments.of({
|
1953
|
-
id,
|
1954
|
-
comments: comments2
|
1955
|
-
})
|
1956
|
-
}));
|
1957
|
-
}
|
1958
|
-
};
|
1959
|
-
this.unsubscribe = subscribe(updateComments);
|
1960
|
-
}
|
1961
|
-
};
|
1962
|
-
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
|
1963
|
-
constructor(view) {
|
1964
|
-
return new ExternalCommentSync(view, id, subscribe, getComments);
|
1965
|
-
}
|
1966
|
-
});
|
1967
|
-
var useCommentState = () => {
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
if (id === view.state.facet(documentId)) {
|
1989
|
-
view.dispatch({
|
1990
|
-
effects: setComments.of({
|
1991
|
-
id,
|
1992
|
-
comments: comments2 ?? []
|
1993
|
-
})
|
1994
|
-
});
|
1995
|
-
}
|
1996
|
-
}
|
1997
|
-
});
|
1998
|
-
};
|
1999
|
-
var useCommentClickListener = (onCommentClick) => {
|
2000
|
-
return useMemo(() => EditorView8.updateListener.of((update2) => {
|
2001
|
-
update2.transactions.forEach((transaction) => {
|
2002
|
-
transaction.effects.forEach((effect) => {
|
2003
|
-
if (effect.is(commentClickedEffect)) {
|
2004
|
-
onCommentClick(effect.value);
|
2005
|
-
}
|
2006
|
-
});
|
2007
|
-
});
|
2008
|
-
}), [
|
2009
|
-
onCommentClick
|
2010
|
-
]);
|
2011
|
-
};
|
2012
|
-
|
2013
|
-
// packages/ui/react-ui-editor/src/extensions/debug.ts
|
2014
|
-
import { syntaxTree } from "@codemirror/language";
|
2015
|
-
import { StateField as StateField5 } from "@codemirror/state";
|
2016
|
-
var debugNodeLogger = (log8 = console.log) => {
|
2017
|
-
const logTokens = (state) => syntaxTree(state).iterate({
|
2018
|
-
enter: (node) => log8(node.type)
|
2019
|
-
});
|
2020
|
-
return StateField5.define({
|
2021
|
-
create: (state) => logTokens(state),
|
2022
|
-
update: (_, tr) => logTokens(tr.state)
|
2023
|
-
});
|
2024
|
-
};
|
2025
|
-
|
2026
|
-
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2027
|
-
import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
|
2028
|
-
var styles4 = EditorView9.theme({
|
2029
|
-
".cm-dropCursor": {
|
2030
|
-
borderLeft: "2px solid var(--dx-accentText)",
|
2031
|
-
color: "var(--dx-accentText)",
|
2032
|
-
padding: "0 4px"
|
2033
|
-
},
|
2034
|
-
".cm-dropCursor:after": {
|
2035
|
-
content: '"\u2190"'
|
2036
|
-
}
|
2037
|
-
});
|
2038
|
-
var dropFile = (options = {}) => {
|
2039
|
-
return [
|
2040
|
-
styles4,
|
2041
|
-
dropCursor(),
|
2042
|
-
EditorView9.domEventHandlers({
|
2043
|
-
drop: (event, view) => {
|
2044
|
-
event.preventDefault();
|
2045
|
-
const files = event.dataTransfer?.files;
|
2046
|
-
const pos = view.posAtCoords(event);
|
2047
|
-
if (files?.length && pos !== null) {
|
2048
|
-
view.dispatch({
|
2049
|
-
selection: {
|
2050
|
-
anchor: pos
|
2051
|
-
}
|
2052
|
-
});
|
2053
|
-
options.onDrop?.(view, {
|
2054
|
-
files
|
2055
|
-
});
|
2056
|
-
}
|
2057
|
-
}
|
2058
|
-
})
|
2059
|
-
];
|
2060
|
-
};
|
2061
|
-
|
2062
|
-
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2063
|
-
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
2064
|
-
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
2065
|
-
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
2066
|
-
import { searchKeymap } from "@codemirror/search";
|
2067
|
-
import { EditorState } from "@codemirror/state";
|
2068
|
-
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2069
|
-
import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2070
|
-
import defaultsDeep2 from "lodash.defaultsdeep";
|
2071
|
-
import merge from "lodash.merge";
|
2072
|
-
import { generateName } from "@dxos/display-name";
|
2073
|
-
import { log as log5 } from "@dxos/log";
|
2074
|
-
import { hueTokens } from "@dxos/react-ui-theme";
|
2075
|
-
import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
2076
|
-
|
2077
|
-
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2078
|
-
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2079
|
-
import { EditorView as EditorView10 } from "@codemirror/view";
|
2080
|
-
var focusEffect = StateEffect4.define();
|
2081
|
-
var focusField = StateField6.define({
|
2082
|
-
create: () => false,
|
2083
|
-
update: (value, tr) => {
|
2084
|
-
for (const effect of tr.effects) {
|
2085
|
-
if (effect.is(focusEffect)) {
|
2086
|
-
return effect.value;
|
2087
|
-
}
|
2088
|
-
}
|
2089
|
-
return value;
|
2090
|
-
}
|
2091
|
-
});
|
2092
|
-
var focus = [
|
2093
|
-
focusField,
|
2094
|
-
EditorView10.domEventHandlers({
|
2095
|
-
focus: (event, view) => {
|
2096
|
-
setTimeout(() => view.dispatch({
|
2097
|
-
effects: focusEffect.of(true)
|
2098
|
-
}));
|
2099
|
-
},
|
2100
|
-
blur: (event, view) => {
|
2101
|
-
setTimeout(() => view.dispatch({
|
2102
|
-
effects: focusEffect.of(false)
|
2103
|
-
}));
|
2104
|
-
}
|
2105
|
-
})
|
2106
|
-
];
|
2107
|
-
|
2108
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
2109
|
-
import { mx } from "@dxos/react-ui-theme";
|
2110
|
-
var headings = {
|
2111
|
-
1: "text-4xl",
|
2112
|
-
2: "text-3xl",
|
2113
|
-
3: "text-2xl",
|
2114
|
-
4: "text-xl",
|
2115
|
-
5: "text-lg",
|
2116
|
-
6: "text-md"
|
2117
|
-
};
|
2118
|
-
var theme = {
|
2119
|
-
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
2120
|
-
codeMark: "font-mono text-primary-500",
|
2121
|
-
mark: "opacity-50",
|
2122
|
-
heading: (level) => {
|
2123
|
-
return mx(headings[level], "dark:text-primary-400");
|
2124
|
-
}
|
2125
|
-
};
|
2126
|
-
|
2127
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
2128
|
-
import get from "lodash.get";
|
2129
|
-
import { tokens } from "@dxos/react-ui-theme";
|
2130
|
-
var getToken = (path, defaultValue) => {
|
2131
|
-
const value = get(tokens, path, defaultValue);
|
2132
|
-
return value?.toString() ?? "";
|
2133
|
-
};
|
2134
|
-
var fontBody = getToken("fontFamily.body");
|
2135
|
-
var fontMono = getToken("fontFamily.mono");
|
2136
|
-
|
2137
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
2138
|
-
var defaultTheme = {
|
2139
|
-
"&": {},
|
2140
|
-
"&.cm-focused": {
|
2141
|
-
outline: "none"
|
2142
|
-
},
|
2143
|
-
/**
|
2144
|
-
* Scroller
|
2145
|
-
*/
|
2146
|
-
".cm-scroller": {
|
2147
|
-
overflowY: "auto"
|
2148
|
-
},
|
2149
|
-
/**
|
2150
|
-
* Content
|
2151
|
-
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
2152
|
-
*/
|
2153
|
-
".cm-content": {
|
2154
|
-
padding: "unset",
|
2155
|
-
fontFamily: fontBody,
|
2156
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
2157
|
-
fontSize: "16px",
|
2158
|
-
lineHeight: 1.5,
|
2159
|
-
color: "unset"
|
2160
|
-
},
|
2161
|
-
/**
|
2162
|
-
* Gutters
|
2163
|
-
* NOTE: Gutters should have the same top margin as the content.
|
2164
|
-
* NOTE: They can't be transparent since the content needs to scroll below.
|
2165
|
-
*/
|
2166
|
-
".cm-gutters": {
|
2167
|
-
background: "var(--surface-bg)",
|
2168
|
-
borderRight: "none"
|
2169
|
-
},
|
2170
|
-
".cm-gutter": {},
|
2171
|
-
".cm-gutter.cm-lineNumbers .cm-gutterElement": {
|
2172
|
-
minWidth: "40px",
|
2173
|
-
alignContent: "center"
|
2174
|
-
},
|
2175
|
-
/**
|
2176
|
-
* Height is set to match the corresponding line.
|
2177
|
-
*/
|
2178
|
-
".cm-gutterElement": {
|
2179
|
-
alignItems: "center",
|
2180
|
-
fontSize: "16px"
|
2181
|
-
},
|
2182
|
-
/**
|
2183
|
-
* Line.
|
2184
|
-
*/
|
2185
|
-
".cm-line": {
|
2186
|
-
paddingInline: 0
|
2187
|
-
},
|
2188
|
-
".cm-activeLine": {
|
2189
|
-
background: "var(--dx-cmActiveLine)"
|
2190
|
-
},
|
2191
|
-
/**
|
2192
|
-
* Cursor (layer).
|
2193
|
-
*/
|
2194
|
-
".cm-cursor, .cm-dropCursor": {
|
2195
|
-
borderLeft: "2px solid var(--dx-cmCursor)"
|
2196
|
-
},
|
2197
|
-
".cm-placeholder": {
|
2198
|
-
color: "var(--dx-subdued)"
|
2199
|
-
},
|
2200
|
-
/**
|
2201
|
-
* Selection (layer).
|
2202
|
-
*/
|
2203
|
-
".cm-selectionBackground": {
|
2204
|
-
background: "var(--dx-cmSelection)"
|
2205
|
-
},
|
2206
|
-
/**
|
2207
|
-
* Search.
|
2208
|
-
* NOTE: Matches comment.
|
2209
|
-
*/
|
2210
|
-
".cm-searchMatch": {
|
2211
|
-
margin: "0 -3px",
|
2212
|
-
padding: "3px",
|
2213
|
-
borderRadius: "3px",
|
2214
|
-
background: "var(--dx-cmHighlightSurface)",
|
2215
|
-
color: "var(--dx-cmHighlight)"
|
2216
|
-
},
|
2217
|
-
".cm-searchMatch-selected": {
|
2218
|
-
textDecoration: "underline"
|
2219
|
-
},
|
2220
|
-
/**
|
2221
|
-
* Link.
|
2222
|
-
*/
|
2223
|
-
".cm-link": {
|
2224
|
-
textDecorationLine: "underline",
|
2225
|
-
textDecorationThickness: "1px",
|
2226
|
-
textUnderlineOffset: "2px",
|
2227
|
-
borderRadius: ".125rem"
|
2228
|
-
},
|
2229
|
-
".cm-link > span": {
|
2230
|
-
color: "var(--dx-accentText)"
|
2231
|
-
},
|
2232
|
-
/**
|
2233
|
-
* Tooltip.
|
2234
|
-
*/
|
2235
|
-
".cm-tooltip": {
|
2236
|
-
background: "var(--dx-base)"
|
2237
|
-
},
|
2238
|
-
".cm-tooltip-below": {},
|
2239
|
-
/**
|
2240
|
-
* Autocomplete.
|
2241
|
-
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
2242
|
-
*/
|
2243
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
2244
|
-
marginTop: "4px",
|
2245
|
-
marginLeft: "-3px"
|
2246
|
-
},
|
2247
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
2248
|
-
maxHeight: "20em"
|
2249
|
-
},
|
2250
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
2251
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
2252
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
2253
|
-
paddingLeft: "4px !important",
|
2254
|
-
borderBottom: "none !important",
|
2255
|
-
color: "var(--dx-accentText)"
|
2256
|
-
},
|
2257
|
-
".cm-tooltip.cm-completionInfo": {
|
2258
|
-
width: "360px !important",
|
2259
|
-
margin: "-10px 1px 0 1px",
|
2260
|
-
padding: "8px !important",
|
2261
|
-
borderColor: "var(--dx-separator)"
|
2262
|
-
},
|
2263
|
-
".cm-completionIcon": {
|
2264
|
-
display: "none"
|
2265
|
-
},
|
2266
|
-
".cm-completionLabel": {
|
2267
|
-
fontFamily: fontBody
|
2268
|
-
},
|
2269
|
-
".cm-completionMatchedText": {
|
2270
|
-
textDecoration: "none !important",
|
2271
|
-
opacity: 0.5
|
2272
|
-
},
|
2273
|
-
/**
|
2274
|
-
* Panels
|
2275
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
2276
|
-
*
|
2277
|
-
* Find/replace panel.
|
2278
|
-
* <div class="cm-announced">...</div>
|
2279
|
-
* <div class="cm-scroller">...</div>
|
2280
|
-
* <div class="cm-panels cm-panels-bottom">
|
2281
|
-
* <div class="cm-search cm-panel">
|
2282
|
-
* <input class="cm-textfield" />
|
2283
|
-
* <button class="cm-button">...</button>
|
2284
|
-
* <label><input type="checkbox" />...</label>
|
2285
|
-
* </div>
|
2286
|
-
* </div
|
2287
|
-
*/
|
2288
|
-
// TODO(burdon): Implement custom panel (with icon buttons).
|
2289
|
-
".cm-panels": {},
|
2290
|
-
".cm-panel": {
|
2291
|
-
fontFamily: fontBody,
|
2292
|
-
backgroundColor: "var(--surface-bg)"
|
2293
|
-
},
|
2294
|
-
".cm-panel input, .cm-panel button, .cm-panel label": {
|
2295
|
-
color: "var(--dx-subdued)",
|
2296
|
-
fontFamily: fontBody,
|
2297
|
-
fontSize: "14px",
|
2298
|
-
all: "unset",
|
2299
|
-
margin: "3px !important",
|
2300
|
-
padding: "2px 6px !important",
|
2301
|
-
outline: "1px solid transparent"
|
2302
|
-
},
|
2303
|
-
".cm-panel input, .cm-panel button": {
|
2304
|
-
backgroundColor: "var(--dx-input)"
|
2305
|
-
},
|
2306
|
-
".cm-panel input:focus, .cm-panel button:focus": {
|
2307
|
-
outline: "1px solid var(--dx-accentFocusIndicator)"
|
2308
|
-
},
|
2309
|
-
".cm-panel label": {
|
2310
|
-
display: "inline-flex",
|
2311
|
-
alignItems: "center",
|
2312
|
-
cursor: "pointer"
|
2313
|
-
},
|
2314
|
-
".cm-panel input.cm-textfield": {},
|
2315
|
-
".cm-panel input[type=checkbox]": {
|
2316
|
-
width: "8px",
|
2317
|
-
height: "8px",
|
2318
|
-
marginRight: "6px !important",
|
2319
|
-
padding: "2px !important",
|
2320
|
-
color: "var(--dx-accentFocusIndicator)"
|
2321
|
-
},
|
2322
|
-
".cm-panel button": {
|
2323
|
-
"&:hover": {
|
2324
|
-
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
2325
|
-
},
|
2326
|
-
"&:active": {
|
2327
|
-
backgroundColor: "var(--dx-accentSurfaceHover)"
|
2529
|
+
var selectionOverlapsComment = (state) => {
|
2530
|
+
const commentState = state.field(commentsState, false);
|
2531
|
+
if (commentState === void 0) {
|
2532
|
+
return false;
|
2533
|
+
}
|
2534
|
+
const { selection } = state;
|
2535
|
+
for (const range of selection.ranges) {
|
2536
|
+
if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
|
2537
|
+
return true;
|
2538
|
+
}
|
2539
|
+
}
|
2540
|
+
return false;
|
2541
|
+
};
|
2542
|
+
var hasActiveSelection = (state) => {
|
2543
|
+
return state.selection.ranges.some((range) => !range.empty);
|
2544
|
+
};
|
2545
|
+
var ExternalCommentSync = class {
|
2546
|
+
constructor(view, id, subscribe, getComments) {
|
2547
|
+
this.destroy = () => {
|
2548
|
+
this.unsubscribe();
|
2549
|
+
};
|
2550
|
+
const updateComments = () => {
|
2551
|
+
const comments2 = getComments();
|
2552
|
+
if (id === view.state.facet(documentId)) {
|
2553
|
+
queueMicrotask(() => view.dispatch({
|
2554
|
+
effects: setComments.of({
|
2555
|
+
id,
|
2556
|
+
comments: comments2
|
2557
|
+
})
|
2558
|
+
}));
|
2559
|
+
}
|
2560
|
+
};
|
2561
|
+
this.unsubscribe = subscribe(updateComments);
|
2562
|
+
}
|
2563
|
+
};
|
2564
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
|
2565
|
+
constructor(view) {
|
2566
|
+
return new ExternalCommentSync(view, id, subscribe, getComments);
|
2567
|
+
}
|
2568
|
+
});
|
2569
|
+
var useCommentState = (state) => {
|
2570
|
+
return useMemo2(() => EditorView9.updateListener.of((update2) => {
|
2571
|
+
if (update2.docChanged || update2.selectionSet) {
|
2572
|
+
state.comment = selectionOverlapsComment(update2.state);
|
2573
|
+
state.selection = hasActiveSelection(update2.state);
|
2574
|
+
}
|
2575
|
+
}), [
|
2576
|
+
state
|
2577
|
+
]);
|
2578
|
+
};
|
2579
|
+
var useComments = (view, id, comments2) => {
|
2580
|
+
useEffect(() => {
|
2581
|
+
if (view) {
|
2582
|
+
if (id === view.state.facet(documentId)) {
|
2583
|
+
view.dispatch({
|
2584
|
+
effects: setComments.of({
|
2585
|
+
id,
|
2586
|
+
comments: comments2 ?? []
|
2587
|
+
})
|
2588
|
+
});
|
2589
|
+
}
|
2328
2590
|
}
|
2591
|
+
});
|
2592
|
+
};
|
2593
|
+
var useCommentClickListener = (onCommentClick) => {
|
2594
|
+
return useMemo2(() => EditorView9.updateListener.of((update2) => {
|
2595
|
+
update2.transactions.forEach((transaction) => {
|
2596
|
+
transaction.effects.forEach((effect) => {
|
2597
|
+
if (effect.is(commentClickedEffect)) {
|
2598
|
+
onCommentClick(effect.value);
|
2599
|
+
}
|
2600
|
+
});
|
2601
|
+
});
|
2602
|
+
}), [
|
2603
|
+
onCommentClick
|
2604
|
+
]);
|
2605
|
+
};
|
2606
|
+
|
2607
|
+
// packages/ui/react-ui-editor/src/extensions/debug.ts
|
2608
|
+
import { syntaxTree } from "@codemirror/language";
|
2609
|
+
import { StateField as StateField5 } from "@codemirror/state";
|
2610
|
+
var debugNodeLogger = (log8 = console.log) => {
|
2611
|
+
const logTokens = (state) => syntaxTree(state).iterate({
|
2612
|
+
enter: (node) => log8(node.type)
|
2613
|
+
});
|
2614
|
+
return StateField5.define({
|
2615
|
+
create: (state) => logTokens(state),
|
2616
|
+
update: (_, tr) => logTokens(tr.state)
|
2617
|
+
});
|
2618
|
+
};
|
2619
|
+
|
2620
|
+
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
2621
|
+
import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
|
2622
|
+
var styles4 = EditorView10.theme({
|
2623
|
+
".cm-dropCursor": {
|
2624
|
+
borderLeft: "2px solid var(--dx-accentText)",
|
2625
|
+
color: "var(--dx-accentText)",
|
2626
|
+
padding: "0 4px"
|
2329
2627
|
},
|
2330
|
-
".cm-
|
2331
|
-
|
2332
|
-
borderTop: "1px solid var(--dx-separator)"
|
2628
|
+
".cm-dropCursor:after": {
|
2629
|
+
content: '"\u2190"'
|
2333
2630
|
}
|
2631
|
+
});
|
2632
|
+
var dropFile = (options = {}) => {
|
2633
|
+
return [
|
2634
|
+
styles4,
|
2635
|
+
dropCursor(),
|
2636
|
+
EditorView10.domEventHandlers({
|
2637
|
+
drop: (event, view) => {
|
2638
|
+
event.preventDefault();
|
2639
|
+
const files = event.dataTransfer?.files;
|
2640
|
+
const pos = view.posAtCoords(event);
|
2641
|
+
if (files?.length && pos !== null) {
|
2642
|
+
view.dispatch({
|
2643
|
+
selection: {
|
2644
|
+
anchor: pos
|
2645
|
+
}
|
2646
|
+
});
|
2647
|
+
options.onDrop?.(view, {
|
2648
|
+
files
|
2649
|
+
});
|
2650
|
+
}
|
2651
|
+
}
|
2652
|
+
})
|
2653
|
+
];
|
2334
2654
|
};
|
2335
2655
|
|
2656
|
+
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2657
|
+
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
2658
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
2659
|
+
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
2660
|
+
import { searchKeymap } from "@codemirror/search";
|
2661
|
+
import { EditorState } from "@codemirror/state";
|
2662
|
+
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
2663
|
+
import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
2664
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
2665
|
+
import merge from "lodash.merge";
|
2666
|
+
import { generateName } from "@dxos/display-name";
|
2667
|
+
import { log as log5 } from "@dxos/log";
|
2668
|
+
import { hueTokens } from "@dxos/react-ui-theme";
|
2669
|
+
import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
2670
|
+
|
2671
|
+
// packages/ui/react-ui-editor/src/extensions/focus.ts
|
2672
|
+
import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
|
2673
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
2674
|
+
var focusEffect = StateEffect4.define();
|
2675
|
+
var focusField = StateField6.define({
|
2676
|
+
create: () => false,
|
2677
|
+
update: (value, tr) => {
|
2678
|
+
for (const effect of tr.effects) {
|
2679
|
+
if (effect.is(focusEffect)) {
|
2680
|
+
return effect.value;
|
2681
|
+
}
|
2682
|
+
}
|
2683
|
+
return value;
|
2684
|
+
}
|
2685
|
+
});
|
2686
|
+
var focus = [
|
2687
|
+
focusField,
|
2688
|
+
EditorView11.domEventHandlers({
|
2689
|
+
focus: (event, view) => {
|
2690
|
+
setTimeout(() => view.dispatch({
|
2691
|
+
effects: focusEffect.of(true)
|
2692
|
+
}));
|
2693
|
+
},
|
2694
|
+
blur: (event, view) => {
|
2695
|
+
setTimeout(() => view.dispatch({
|
2696
|
+
effects: focusEffect.of(false)
|
2697
|
+
}));
|
2698
|
+
}
|
2699
|
+
})
|
2700
|
+
];
|
2701
|
+
|
2336
2702
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
2337
2703
|
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
2338
2704
|
var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
|
@@ -2358,7 +2724,7 @@ var createBasicExtensions = (_props) => {
|
|
2358
2724
|
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
2359
2725
|
return [
|
2360
2726
|
// NOTE: Doesn't catch errors in keymap functions.
|
2361
|
-
|
2727
|
+
EditorView12.exceptionSink.of((err) => {
|
2362
2728
|
log5.catch(err, void 0, {
|
2363
2729
|
F: __dxlog_file8,
|
2364
2730
|
L: 96,
|
@@ -2377,11 +2743,11 @@ var createBasicExtensions = (_props) => {
|
|
2377
2743
|
props.highlightActiveLine && highlightActiveLine(),
|
2378
2744
|
props.history && history(),
|
2379
2745
|
props.lineNumbers && lineNumbers(),
|
2380
|
-
props.lineWrapping &&
|
2746
|
+
props.lineWrapping && EditorView12.lineWrapping,
|
2381
2747
|
props.placeholder && placeholder(props.placeholder),
|
2382
2748
|
props.readonly && [
|
2383
2749
|
EditorState.readOnly.of(true),
|
2384
|
-
|
2750
|
+
EditorView12.editable.of(false)
|
2385
2751
|
],
|
2386
2752
|
props.scrollPastEnd && scrollPastEnd(),
|
2387
2753
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
@@ -2410,14 +2776,14 @@ var defaultThemeSlots = {
|
|
2410
2776
|
var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
|
2411
2777
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
2412
2778
|
return [
|
2413
|
-
|
2414
|
-
|
2779
|
+
EditorView12.darkTheme.of(themeMode === "dark"),
|
2780
|
+
EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
|
2415
2781
|
// https://github.com/codemirror/theme-one-dark
|
2416
2782
|
_syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
|
2417
|
-
slots.editor?.className &&
|
2783
|
+
slots.editor?.className && EditorView12.editorAttributes.of({
|
2418
2784
|
class: slots.editor.className
|
2419
2785
|
}),
|
2420
|
-
slots.content?.className &&
|
2786
|
+
slots.content?.className && EditorView12.contentAttributes.of({
|
2421
2787
|
class: slots.content.className
|
2422
2788
|
})
|
2423
2789
|
].filter(isNotFalsy3);
|
@@ -2446,8 +2812,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2446
2812
|
|
2447
2813
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
2448
2814
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
2449
|
-
import { EditorView as
|
2450
|
-
import
|
2815
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
2816
|
+
import React3 from "react";
|
2451
2817
|
import { Icon } from "@dxos/react-ui";
|
2452
2818
|
var folding = (_props = {}) => [
|
2453
2819
|
codeFolding({
|
@@ -2460,7 +2826,7 @@ var folding = (_props = {}) => [
|
|
2460
2826
|
const el = createElement("div", {
|
2461
2827
|
className: "flex h-full items-center"
|
2462
2828
|
});
|
2463
|
-
return renderRoot(el, /* @__PURE__ */
|
2829
|
+
return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
|
2464
2830
|
icon: "ph--caret-right--regular",
|
2465
2831
|
size: 3,
|
2466
2832
|
classNames: [
|
@@ -2470,7 +2836,7 @@ var folding = (_props = {}) => [
|
|
2470
2836
|
}));
|
2471
2837
|
}
|
2472
2838
|
}),
|
2473
|
-
|
2839
|
+
EditorView13.theme({
|
2474
2840
|
".cm-foldGutter": {
|
2475
2841
|
opacity: 0.3,
|
2476
2842
|
transition: "opacity 0.3s",
|
@@ -2483,14 +2849,14 @@ var folding = (_props = {}) => [
|
|
2483
2849
|
];
|
2484
2850
|
|
2485
2851
|
// packages/ui/react-ui-editor/src/extensions/listener.ts
|
2486
|
-
import { EditorView as
|
2852
|
+
import { EditorView as EditorView14 } from "@codemirror/view";
|
2487
2853
|
var listener = ({ onFocus, onChange }) => {
|
2488
2854
|
const extensions = [];
|
2489
|
-
onFocus && extensions.push(
|
2855
|
+
onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
|
2490
2856
|
onFocus(focusing);
|
2491
2857
|
return null;
|
2492
2858
|
}));
|
2493
|
-
onChange && extensions.push(
|
2859
|
+
onChange && extensions.push(EditorView14.updateListener.of((update2) => {
|
2494
2860
|
onChange(update2.state.doc.toString(), update2.state.facet(documentId));
|
2495
2861
|
}));
|
2496
2862
|
return extensions;
|
@@ -2500,8 +2866,8 @@ var listener = ({ onFocus, onChange }) => {
|
|
2500
2866
|
import { snippet } from "@codemirror/autocomplete";
|
2501
2867
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
2502
2868
|
import { EditorSelection } from "@codemirror/state";
|
2503
|
-
import { EditorView as
|
2504
|
-
import { useMemo as
|
2869
|
+
import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
|
2870
|
+
import { useMemo as useMemo3 } from "react";
|
2505
2871
|
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;
|
2506
2872
|
var Inline;
|
2507
2873
|
(function(Inline2) {
|
@@ -3588,65 +3954,56 @@ var getFormatting = (state) => {
|
|
3588
3954
|
listStyle: listStyle || null
|
3589
3955
|
};
|
3590
3956
|
};
|
3591
|
-
var useFormattingState = () => {
|
3592
|
-
|
3593
|
-
const observer = useMemo2(() => EditorView14.updateListener.of((update2) => {
|
3957
|
+
var useFormattingState = (state) => {
|
3958
|
+
return useMemo3(() => EditorView15.updateListener.of((update2) => {
|
3594
3959
|
if (update2.docChanged || update2.selectionSet) {
|
3595
|
-
|
3596
|
-
|
3597
|
-
if (!prevState || !formattingEquals(prevState, newState)) {
|
3598
|
-
return newState;
|
3599
|
-
}
|
3600
|
-
return prevState;
|
3960
|
+
Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
|
3961
|
+
state[key] = active;
|
3601
3962
|
});
|
3602
3963
|
}
|
3603
3964
|
}), []);
|
3604
|
-
return [
|
3605
|
-
state,
|
3606
|
-
observer
|
3607
|
-
];
|
3608
3965
|
};
|
3609
3966
|
|
3610
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
3611
|
-
var
|
3967
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/editorAction.ts
|
3968
|
+
var processEditorPayload = (view, { type, data }) => {
|
3612
3969
|
let inlineType, listType;
|
3613
|
-
switch (
|
3970
|
+
switch (type) {
|
3614
3971
|
case "heading":
|
3615
|
-
setHeading(parseInt(
|
3972
|
+
setHeading(parseInt(data))(view);
|
3616
3973
|
break;
|
3617
3974
|
case "strong":
|
3618
3975
|
case "emphasis":
|
3619
3976
|
case "strikethrough":
|
3620
3977
|
case "code":
|
3621
|
-
inlineType =
|
3622
|
-
(typeof
|
3978
|
+
inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
|
3979
|
+
(typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
|
3623
3980
|
break;
|
3624
3981
|
case "list-ordered":
|
3625
3982
|
case "list-bullet":
|
3626
3983
|
case "list-task":
|
3627
|
-
listType =
|
3628
|
-
(
|
3984
|
+
listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
|
3985
|
+
(data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
|
3629
3986
|
break;
|
3630
3987
|
case "blockquote":
|
3631
|
-
(
|
3988
|
+
(data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
|
3632
3989
|
break;
|
3633
3990
|
case "codeblock":
|
3634
|
-
(
|
3991
|
+
(data === false ? removeCodeblock : addCodeblock)(view);
|
3635
3992
|
break;
|
3636
3993
|
case "table":
|
3637
3994
|
insertTable(view);
|
3638
3995
|
break;
|
3639
3996
|
case "link":
|
3640
|
-
(
|
3997
|
+
(data === false ? removeLink : addLink())(view);
|
3641
3998
|
break;
|
3642
3999
|
case "image":
|
3643
4000
|
addLink({
|
3644
|
-
url:
|
4001
|
+
url: data,
|
3645
4002
|
image: true
|
3646
4003
|
})(view);
|
3647
4004
|
break;
|
3648
4005
|
case "comment":
|
3649
|
-
|
4006
|
+
createComment2(view);
|
3650
4007
|
break;
|
3651
4008
|
}
|
3652
4009
|
requestAnimationFrame(() => {
|
@@ -3910,9 +4267,9 @@ var convertTreeToJson = (state) => {
|
|
3910
4267
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
3911
4268
|
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
3912
4269
|
import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
|
3913
|
-
import { EditorView as
|
4270
|
+
import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
3914
4271
|
import { invariant as invariant4 } from "@dxos/invariant";
|
3915
|
-
import { mx as
|
4272
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
3916
4273
|
|
3917
4274
|
// packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
|
3918
4275
|
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
@@ -4061,7 +4418,7 @@ var getValidUrl = (str) => {
|
|
4061
4418
|
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
4062
4419
|
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
4063
4420
|
import { StateField as StateField8 } from "@codemirror/state";
|
4064
|
-
import { Decoration as Decoration5, EditorView as
|
4421
|
+
import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
|
4065
4422
|
var image = (_options = {}) => {
|
4066
4423
|
return [
|
4067
4424
|
StateField8.define({
|
@@ -4089,7 +4446,7 @@ var image = (_options = {}) => {
|
|
4089
4446
|
add: buildDecorations(from, to, tr.state)
|
4090
4447
|
});
|
4091
4448
|
},
|
4092
|
-
provide: (field) =>
|
4449
|
+
provide: (field) => EditorView16.decorations.from(field)
|
4093
4450
|
})
|
4094
4451
|
];
|
4095
4452
|
};
|
@@ -4149,10 +4506,10 @@ var ImageWidget = class extends WidgetType3 {
|
|
4149
4506
|
};
|
4150
4507
|
|
4151
4508
|
// packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
|
4152
|
-
import { EditorView as
|
4509
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
4153
4510
|
var bulletListIndentationWidth = 24;
|
4154
4511
|
var orderedListIndentationWidth = 36;
|
4155
|
-
var formattingStyles =
|
4512
|
+
var formattingStyles = EditorView17.theme({
|
4156
4513
|
/**
|
4157
4514
|
* Horizontal rule.
|
4158
4515
|
*/
|
@@ -4246,18 +4603,39 @@ var formattingStyles = EditorView16.theme({
|
|
4246
4603
|
height: "auto",
|
4247
4604
|
borderTop: "0.5rem solid transparent",
|
4248
4605
|
borderBottom: "0.5rem solid transparent"
|
4606
|
+
},
|
4607
|
+
".cm-image-with-loader": {
|
4608
|
+
display: "block",
|
4609
|
+
opacity: "0",
|
4610
|
+
transitionDuration: "350ms",
|
4611
|
+
transitionProperty: "opacity"
|
4612
|
+
},
|
4613
|
+
".cm-image-with-loader.cm-loaded-image": {
|
4614
|
+
opacity: "1"
|
4615
|
+
},
|
4616
|
+
".cm-image-wrapper": {
|
4617
|
+
"grid-template-columns": "1fr",
|
4618
|
+
display: "grid",
|
4619
|
+
margin: "0.5rem 0",
|
4620
|
+
overflow: "hidden",
|
4621
|
+
transitionDuration: "350ms",
|
4622
|
+
transitionProperty: "height",
|
4623
|
+
"& > *": {
|
4624
|
+
"grid-row-start": 1,
|
4625
|
+
"grid-column-start": 1
|
4626
|
+
}
|
4249
4627
|
}
|
4250
4628
|
});
|
4251
4629
|
|
4252
4630
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
4253
4631
|
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
4254
4632
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
|
4255
|
-
import { Decoration as Decoration6, EditorView as
|
4633
|
+
import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
|
4256
4634
|
var table = (options = {}) => {
|
4257
4635
|
return StateField9.define({
|
4258
4636
|
create: (state) => update(state, options),
|
4259
4637
|
update: (_, tr) => update(tr.state, options),
|
4260
|
-
provide: (field) =>
|
4638
|
+
provide: (field) => EditorView18.decorations.from(field)
|
4261
4639
|
});
|
4262
4640
|
};
|
4263
4641
|
var update = (state, _options) => {
|
@@ -4389,7 +4767,7 @@ var CheckboxWidget = class extends WidgetType5 {
|
|
4389
4767
|
}
|
4390
4768
|
toDOM(view) {
|
4391
4769
|
const input = document.createElement("input");
|
4392
|
-
input.className = "cm-task-checkbox
|
4770
|
+
input.className = "cm-task-checkbox dx-checkbox";
|
4393
4771
|
input.type = "checkbox";
|
4394
4772
|
input.tabIndex = -1;
|
4395
4773
|
input.checked = this._checked;
|
@@ -4441,16 +4819,16 @@ var TextWidget = class extends WidgetType5 {
|
|
4441
4819
|
};
|
4442
4820
|
var hide = Decoration7.replace({});
|
4443
4821
|
var blockQuote = Decoration7.line({
|
4444
|
-
class:
|
4822
|
+
class: mx4("cm-blockquote")
|
4445
4823
|
});
|
4446
4824
|
var fencedCodeLine = Decoration7.line({
|
4447
|
-
class:
|
4825
|
+
class: mx4("cm-code cm-codeblock-line")
|
4448
4826
|
});
|
4449
4827
|
var fencedCodeLineFirst = Decoration7.line({
|
4450
|
-
class:
|
4828
|
+
class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
|
4451
4829
|
});
|
4452
4830
|
var fencedCodeLineLast = Decoration7.line({
|
4453
|
-
class:
|
4831
|
+
class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
|
4454
4832
|
});
|
4455
4833
|
var commentBlockLine = fencedCodeLine;
|
4456
4834
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
@@ -4791,9 +5169,9 @@ var decorateMarkdown = (options = {}) => {
|
|
4791
5169
|
}
|
4792
5170
|
}, {
|
4793
5171
|
provide: (plugin) => [
|
4794
|
-
|
4795
|
-
|
4796
|
-
|
5172
|
+
EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5173
|
+
EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
5174
|
+
EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
4797
5175
|
]
|
4798
5176
|
}),
|
4799
5177
|
image(),
|
@@ -4980,428 +5358,29 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
4980
5358
|
];
|
4981
5359
|
};
|
4982
5360
|
|
4983
|
-
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
4984
|
-
var iconStyles = getSize(5);
|
4985
|
-
var buttonStyles = "min-bs-0 p-1";
|
4986
|
-
var tooltipProps = {
|
4987
|
-
side: "top",
|
4988
|
-
classNames: "z-10"
|
4989
|
-
};
|
4990
|
-
var ToolbarSeparator = () => /* @__PURE__ */ React3.createElement("div", {
|
4991
|
-
role: "separator",
|
4992
|
-
className: "grow"
|
4993
|
-
});
|
4994
|
-
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
4995
|
-
var ToolbarRoot = ({ children, onAction, classNames, state }) => {
|
4996
|
-
return /* @__PURE__ */ React3.createElement(ToolbarContextProvider, {
|
4997
|
-
onAction,
|
4998
|
-
state
|
4999
|
-
}, /* @__PURE__ */ React3.createElement(ElevationProvider, {
|
5000
|
-
elevation: "positioned"
|
5001
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
5002
|
-
classNames: [
|
5003
|
-
"p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
|
5004
|
-
classNames
|
5005
|
-
],
|
5006
|
-
style: {
|
5007
|
-
contain: "layout"
|
5008
|
-
}
|
5009
|
-
}, children)));
|
5010
|
-
};
|
5011
|
-
var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
|
5012
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5013
|
-
asChild: true
|
5014
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, {
|
5015
|
-
variant: "ghost",
|
5016
|
-
...props,
|
5017
|
-
classNames: buttonStyles
|
5018
|
-
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
5019
|
-
className: iconStyles
|
5020
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
5021
|
-
className: "sr-only"
|
5022
|
-
}, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5023
|
-
};
|
5024
|
-
var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
|
5025
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5026
|
-
asChild: true
|
5027
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
5028
|
-
variant: "ghost",
|
5029
|
-
...props,
|
5030
|
-
classNames: buttonStyles
|
5031
|
-
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
5032
|
-
className: iconStyles
|
5033
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
5034
|
-
className: "sr-only"
|
5035
|
-
}, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5036
|
-
};
|
5037
|
-
var HeadingIcons = {
|
5038
|
-
"0": Paragraph,
|
5039
|
-
"1": TextHOne,
|
5040
|
-
"2": TextHTwo,
|
5041
|
-
"3": TextHThree,
|
5042
|
-
"4": TextHFour,
|
5043
|
-
"5": TextHFive,
|
5044
|
-
"6": TextHSix
|
5045
|
-
};
|
5046
|
-
var MarkdownHeading = () => {
|
5047
|
-
const { t } = useTranslation(translationKey);
|
5048
|
-
const { onAction, state } = useToolbarContext("MarkdownFormatting");
|
5049
|
-
const blockType = state ? state.blockType : "paragraph";
|
5050
|
-
const header = blockType && /heading(\d)/.exec(blockType);
|
5051
|
-
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
5052
|
-
const HeadingIcon = HeadingIcons[value ?? "0"];
|
5053
|
-
const suppressNextTooltip = useRef(false);
|
5054
|
-
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
5055
|
-
const [selectOpen, setSelectOpen] = useState3(false);
|
5056
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
|
5057
|
-
open: tooltipOpen,
|
5058
|
-
onOpenChange: (nextOpen) => {
|
5059
|
-
if (nextOpen && suppressNextTooltip.current) {
|
5060
|
-
suppressNextTooltip.current = false;
|
5061
|
-
return setTooltipOpen(false);
|
5062
|
-
} else {
|
5063
|
-
return setTooltipOpen(nextOpen);
|
5064
|
-
}
|
5065
|
-
}
|
5066
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
5067
|
-
open: selectOpen,
|
5068
|
-
onOpenChange: (nextOpen) => {
|
5069
|
-
if (!nextOpen) {
|
5070
|
-
suppressNextTooltip.current = true;
|
5071
|
-
}
|
5072
|
-
return setSelectOpen(nextOpen);
|
5073
|
-
}
|
5074
|
-
}, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5075
|
-
asChild: true
|
5076
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
5077
|
-
asChild: true
|
5078
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
5079
|
-
asChild: true
|
5080
|
-
}, /* @__PURE__ */ React3.createElement(Button, {
|
5081
|
-
variant: "ghost",
|
5082
|
-
classNames: buttonStyles,
|
5083
|
-
disabled: value === null
|
5084
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
5085
|
-
className: "sr-only"
|
5086
|
-
}, t("heading label")), /* @__PURE__ */ React3.createElement(HeadingIcon, {
|
5087
|
-
className: iconStyles
|
5088
|
-
}), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
|
5089
|
-
classNames: "is-min md:is-min",
|
5090
|
-
onCloseAutoFocus: (e) => e.preventDefault()
|
5091
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
|
5092
|
-
const Icon2 = HeadingIcons[level];
|
5093
|
-
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
5094
|
-
key: level,
|
5095
|
-
checked: value === level,
|
5096
|
-
onClick: () => onAction?.({
|
5097
|
-
type: "heading",
|
5098
|
-
data: level
|
5099
|
-
})
|
5100
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
5101
|
-
className: "sr-only"
|
5102
|
-
}, t("heading level label", {
|
5103
|
-
count: parseInt(level)
|
5104
|
-
})), /* @__PURE__ */ React3.createElement(Icon2, {
|
5105
|
-
className: iconStyles
|
5106
|
-
}), /* @__PURE__ */ React3.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React3.createElement(Check, null)));
|
5107
|
-
})), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5108
|
-
};
|
5109
|
-
var markdownStyles = [
|
5110
|
-
{
|
5111
|
-
type: "strong",
|
5112
|
-
Icon: TextB,
|
5113
|
-
getState: (state) => !!state?.strong
|
5114
|
-
},
|
5115
|
-
{
|
5116
|
-
type: "emphasis",
|
5117
|
-
Icon: TextItalic,
|
5118
|
-
getState: (state) => !!state?.emphasis
|
5119
|
-
},
|
5120
|
-
{
|
5121
|
-
type: "strikethrough",
|
5122
|
-
Icon: TextStrikethrough,
|
5123
|
-
getState: (state) => !!state?.strikethrough
|
5124
|
-
},
|
5125
|
-
{
|
5126
|
-
type: "code",
|
5127
|
-
Icon: Code,
|
5128
|
-
getState: (state) => !!state?.code
|
5129
|
-
},
|
5130
|
-
{
|
5131
|
-
type: "link",
|
5132
|
-
Icon: Link,
|
5133
|
-
getState: (state) => !!state?.link
|
5134
|
-
}
|
5135
|
-
];
|
5136
|
-
var MarkdownStyles = () => {
|
5137
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
5138
|
-
const { t } = useTranslation(translationKey);
|
5139
|
-
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
5140
|
-
type: "multiple",
|
5141
|
-
value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
|
5142
|
-
}, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
5143
|
-
key: type,
|
5144
|
-
value: type,
|
5145
|
-
Icon: Icon2,
|
5146
|
-
disabled: state?.blockType === "codeblock",
|
5147
|
-
onClick: state ? () => onAction?.({
|
5148
|
-
type,
|
5149
|
-
data: !getState(state)
|
5150
|
-
}) : void 0
|
5151
|
-
}, t(`${type} label`))));
|
5152
|
-
};
|
5153
|
-
var markdownLists = [
|
5154
|
-
{
|
5155
|
-
type: "list-bullet",
|
5156
|
-
Icon: ListBullets,
|
5157
|
-
getState: (state) => state.listStyle === "bullet"
|
5158
|
-
},
|
5159
|
-
{
|
5160
|
-
type: "list-ordered",
|
5161
|
-
Icon: ListNumbers,
|
5162
|
-
getState: (state) => state.listStyle === "ordered"
|
5163
|
-
},
|
5164
|
-
{
|
5165
|
-
type: "list-task",
|
5166
|
-
Icon: ListChecks,
|
5167
|
-
getState: (state) => state.listStyle === "task"
|
5168
|
-
}
|
5169
|
-
];
|
5170
|
-
var MarkdownLists = () => {
|
5171
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
5172
|
-
const { t } = useTranslation(translationKey);
|
5173
|
-
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
5174
|
-
type: "single",
|
5175
|
-
value: state?.listStyle ? `list-${state.listStyle}` : ""
|
5176
|
-
}, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
5177
|
-
key: type,
|
5178
|
-
value: type,
|
5179
|
-
Icon: Icon2,
|
5180
|
-
onClick: state ? () => onAction?.({
|
5181
|
-
type,
|
5182
|
-
data: !getState(state)
|
5183
|
-
}) : void 0
|
5184
|
-
}, t(`${type} label`))));
|
5185
|
-
};
|
5186
|
-
var markdownBlocks = [
|
5187
|
-
{
|
5188
|
-
type: "blockquote",
|
5189
|
-
Icon: Quotes,
|
5190
|
-
getState: (state) => !!state?.blockQuote
|
5191
|
-
},
|
5192
|
-
{
|
5193
|
-
type: "codeblock",
|
5194
|
-
Icon: CodeBlock,
|
5195
|
-
getState: (state) => state.blockType === "codeblock"
|
5196
|
-
},
|
5197
|
-
{
|
5198
|
-
type: "table",
|
5199
|
-
Icon: Table2,
|
5200
|
-
getState: (state) => state.blockType === "tablecell",
|
5201
|
-
disabled: (state) => !state.blankLine
|
5202
|
-
}
|
5203
|
-
];
|
5204
|
-
var MarkdownBlocks = () => {
|
5205
|
-
const { onAction, state } = useToolbarContext("MarkdownStyles");
|
5206
|
-
const { t } = useTranslation(translationKey);
|
5207
|
-
const value = markdownBlocks.find(({ getState }) => state && getState(state));
|
5208
|
-
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
5209
|
-
type: "single",
|
5210
|
-
value: value?.type ?? ""
|
5211
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
5212
|
-
key: type,
|
5213
|
-
value: type,
|
5214
|
-
Icon: Icon2,
|
5215
|
-
disabled: !state || disabled?.(state),
|
5216
|
-
onClick: state ? () => onAction?.({
|
5217
|
-
type,
|
5218
|
-
data: !getState(state)
|
5219
|
-
}) : void 0
|
5220
|
-
}, t(`${type} label`))));
|
5221
|
-
};
|
5222
|
-
var MarkdownStandard = () => /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(MarkdownHeading, null), /* @__PURE__ */ React3.createElement(MarkdownStyles, null), /* @__PURE__ */ React3.createElement(MarkdownLists, null), /* @__PURE__ */ React3.createElement(MarkdownBlocks, null));
|
5223
|
-
var MarkdownCustom = ({ onUpload } = {}) => {
|
5224
|
-
const { onAction } = useToolbarContext("MarkdownStyles");
|
5225
|
-
const { t } = useTranslation(translationKey);
|
5226
|
-
const { acceptedFiles, getInputProps, open } = useDropzone({
|
5227
|
-
multiple: false,
|
5228
|
-
noDrag: true,
|
5229
|
-
accept: {
|
5230
|
-
"image/*": [
|
5231
|
-
".jpg",
|
5232
|
-
".jpeg",
|
5233
|
-
".png",
|
5234
|
-
".gif"
|
5235
|
-
]
|
5236
|
-
}
|
5237
|
-
});
|
5238
|
-
useEffect2(() => {
|
5239
|
-
if (onUpload && acceptedFiles.length) {
|
5240
|
-
requestAnimationFrame(async () => {
|
5241
|
-
const f = acceptedFiles[0];
|
5242
|
-
const file = new File([
|
5243
|
-
f
|
5244
|
-
], f.name, {
|
5245
|
-
type: f.type,
|
5246
|
-
lastModified: f.lastModified
|
5247
|
-
});
|
5248
|
-
const info = await onUpload(file);
|
5249
|
-
if (info) {
|
5250
|
-
onAction?.({
|
5251
|
-
type: "image",
|
5252
|
-
data: info.url
|
5253
|
-
});
|
5254
|
-
}
|
5255
|
-
});
|
5256
|
-
}
|
5257
|
-
}, [
|
5258
|
-
acceptedFiles
|
5259
|
-
]);
|
5260
|
-
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("input", getInputProps()), /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
5261
|
-
value: "image",
|
5262
|
-
Icon: Image,
|
5263
|
-
onClick: () => open()
|
5264
|
-
}, t("image label")));
|
5265
|
-
};
|
5266
|
-
var ViewModeIcons = {
|
5267
|
-
preview: PencilSimple,
|
5268
|
-
readonly: PencilSimpleSlash,
|
5269
|
-
source: MarkdownLogo
|
5270
|
-
};
|
5271
|
-
var MarkdownView = ({ mode }) => {
|
5272
|
-
const { t } = useTranslation(translationKey);
|
5273
|
-
const { onAction } = useToolbarContext("ViewMode");
|
5274
|
-
const ModeIcon = ViewModeIcons[mode ?? "preview"];
|
5275
|
-
const suppressNextTooltip = useRef(false);
|
5276
|
-
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
5277
|
-
const [selectOpen, setSelectOpen] = useState3(false);
|
5278
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
|
5279
|
-
open: tooltipOpen,
|
5280
|
-
onOpenChange: (nextOpen) => {
|
5281
|
-
if (nextOpen && suppressNextTooltip.current) {
|
5282
|
-
suppressNextTooltip.current = false;
|
5283
|
-
return setTooltipOpen(false);
|
5284
|
-
} else {
|
5285
|
-
return setTooltipOpen(nextOpen);
|
5286
|
-
}
|
5287
|
-
}
|
5288
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
5289
|
-
open: selectOpen,
|
5290
|
-
onOpenChange: (nextOpen) => {
|
5291
|
-
if (!nextOpen) {
|
5292
|
-
suppressNextTooltip.current = true;
|
5293
|
-
}
|
5294
|
-
return setSelectOpen(nextOpen);
|
5295
|
-
}
|
5296
|
-
}, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
5297
|
-
asChild: true
|
5298
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
5299
|
-
asChild: true
|
5300
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
5301
|
-
asChild: true
|
5302
|
-
}, /* @__PURE__ */ React3.createElement(Button, {
|
5303
|
-
variant: "ghost",
|
5304
|
-
classNames: buttonStyles
|
5305
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
5306
|
-
className: "sr-only"
|
5307
|
-
}, t("mode label")), /* @__PURE__ */ React3.createElement(ModeIcon, {
|
5308
|
-
className: iconStyles
|
5309
|
-
}), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
|
5310
|
-
classNames: "is-min md:is-min",
|
5311
|
-
onCloseAutoFocus: (e) => e.preventDefault()
|
5312
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
|
5313
|
-
const Icon2 = ViewModeIcons[value];
|
5314
|
-
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
5315
|
-
key: value,
|
5316
|
-
checked: value === mode,
|
5317
|
-
onClick: () => onAction?.({
|
5318
|
-
type: "view-mode",
|
5319
|
-
data: value
|
5320
|
-
})
|
5321
|
-
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
5322
|
-
className: iconStyles
|
5323
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
5324
|
-
className: "whitespace-nowrap grow"
|
5325
|
-
}, t(`${value} mode label`)), /* @__PURE__ */ React3.createElement(Check, {
|
5326
|
-
className: value === mode ? "visible" : "invisible"
|
5327
|
-
}));
|
5328
|
-
})), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
5329
|
-
};
|
5330
|
-
var MarkdownActions = () => {
|
5331
|
-
const { onAction, state } = useToolbarContext("MarkdownActions");
|
5332
|
-
const { t } = useTranslation(translationKey);
|
5333
|
-
let commentToolTipKey = "comment label";
|
5334
|
-
if (state?.comment) {
|
5335
|
-
commentToolTipKey = "selection overlaps existing comment label";
|
5336
|
-
} else if (state?.selection === false) {
|
5337
|
-
commentToolTipKey = "select text to comment label";
|
5338
|
-
}
|
5339
|
-
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
5340
|
-
value: "search",
|
5341
|
-
Icon: MagnifyingGlass,
|
5342
|
-
onClick: () => onAction?.({
|
5343
|
-
type: "search"
|
5344
|
-
})
|
5345
|
-
}, t("search label")), /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
5346
|
-
value: "comment",
|
5347
|
-
Icon: ChatText,
|
5348
|
-
"data-testid": "editor.toolbar.comment",
|
5349
|
-
onClick: () => onAction?.({
|
5350
|
-
type: "comment"
|
5351
|
-
}),
|
5352
|
-
disabled: !state || state.comment || !state.selection
|
5353
|
-
}, t(commentToolTipKey)));
|
5354
|
-
};
|
5355
|
-
var Toolbar = {
|
5356
|
-
Root: ToolbarRoot,
|
5357
|
-
Button: ToolbarToggleButton,
|
5358
|
-
Separator: ToolbarSeparator,
|
5359
|
-
View: MarkdownView,
|
5360
|
-
Markdown: MarkdownStandard,
|
5361
|
-
Custom: MarkdownCustom,
|
5362
|
-
Actions: MarkdownActions
|
5363
|
-
};
|
5364
|
-
|
5365
|
-
// packages/ui/react-ui-editor/src/defaults.ts
|
5366
|
-
import { EditorView as EditorView19 } from "@codemirror/view";
|
5367
|
-
import { mx as mx3 } from "@dxos/react-ui-theme";
|
5368
|
-
var margin = "!mt-[1rem]";
|
5369
|
-
var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
|
5370
|
-
var editorFullWidth = mx3(margin);
|
5371
|
-
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
5372
|
-
var editorGutter = EditorView19.theme({
|
5373
|
-
// Match margin from content.
|
5374
|
-
".cm-gutters": {
|
5375
|
-
marginTop: "16px",
|
5376
|
-
paddingRight: "1rem"
|
5377
|
-
}
|
5378
|
-
});
|
5379
|
-
var editorMonospace = EditorView19.theme({
|
5380
|
-
".cm-content": {
|
5381
|
-
fontFamily: fontMono
|
5382
|
-
}
|
5383
|
-
});
|
5384
|
-
|
5385
5361
|
// packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
|
5362
|
+
import { useCallback as useCallback2 } from "react";
|
5386
5363
|
var useActionHandler = (view) => {
|
5387
|
-
return (action) => view &&
|
5364
|
+
return useCallback2((action) => view && processEditorPayload(view, action.properties), [
|
5365
|
+
view
|
5366
|
+
]);
|
5388
5367
|
};
|
5389
5368
|
|
5390
5369
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
5391
5370
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
5392
5371
|
import { EditorView as EditorView20 } from "@codemirror/view";
|
5393
5372
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
5394
|
-
import { useCallback, useEffect as
|
5373
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
|
5395
5374
|
import { log as log7 } from "@dxos/log";
|
5396
5375
|
import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
5397
5376
|
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
5398
5377
|
var instanceCount = 0;
|
5399
5378
|
var useTextEditor = (props = {}, deps = []) => {
|
5400
|
-
const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } =
|
5401
|
-
const [instanceId] =
|
5402
|
-
const [view, setView] =
|
5403
|
-
const parentRef =
|
5404
|
-
|
5379
|
+
const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
|
5380
|
+
const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
|
5381
|
+
const [view, setView] = useState();
|
5382
|
+
const parentRef = useRef(null);
|
5383
|
+
useEffect2(() => {
|
5405
5384
|
let view2;
|
5406
5385
|
if (parentRef.current) {
|
5407
5386
|
log7("create", {
|
@@ -5475,7 +5454,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5475
5454
|
view2?.destroy();
|
5476
5455
|
};
|
5477
5456
|
}, deps);
|
5478
|
-
|
5457
|
+
useEffect2(() => {
|
5479
5458
|
if (view) {
|
5480
5459
|
if (scrollTo || selection) {
|
5481
5460
|
if (selection && selection.anchor > view.state.doc.length) {
|
@@ -5502,7 +5481,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5502
5481
|
scrollTo,
|
5503
5482
|
selection
|
5504
5483
|
]);
|
5505
|
-
|
5484
|
+
useEffect2(() => {
|
5506
5485
|
if (view && autoFocus) {
|
5507
5486
|
view.focus();
|
5508
5487
|
}
|
@@ -5516,7 +5495,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
5516
5495
|
Escape: view?.state.facet(editorInputMode).noTabster
|
5517
5496
|
}
|
5518
5497
|
});
|
5519
|
-
const handleKeyUp =
|
5498
|
+
const handleKeyUp = useCallback3((event) => {
|
5520
5499
|
const { key, target, currentTarget } = event;
|
5521
5500
|
if (target === currentTarget) {
|
5522
5501
|
switch (key) {
|
@@ -5545,6 +5524,7 @@ export {
|
|
5545
5524
|
EditorInputMode,
|
5546
5525
|
EditorInputModes,
|
5547
5526
|
EditorState3 as EditorState,
|
5527
|
+
EditorToolbar,
|
5548
5528
|
EditorView21 as EditorView,
|
5549
5529
|
EditorViewMode,
|
5550
5530
|
EditorViewModes,
|
@@ -5554,7 +5534,6 @@ export {
|
|
5554
5534
|
RemoteSelectionsDecorator,
|
5555
5535
|
SpaceAwarenessProvider,
|
5556
5536
|
TextKind,
|
5557
|
-
Toolbar,
|
5558
5537
|
addBlockquote,
|
5559
5538
|
addCodeblock,
|
5560
5539
|
addLink,
|
@@ -5573,8 +5552,10 @@ export {
|
|
5573
5552
|
commentsState,
|
5574
5553
|
convertTreeToJson,
|
5575
5554
|
createBasicExtensions,
|
5576
|
-
createComment,
|
5555
|
+
createComment2 as createComment,
|
5577
5556
|
createDataExtensions,
|
5557
|
+
createEditorAction,
|
5558
|
+
createEditorActionGroup,
|
5578
5559
|
createEditorStateStore,
|
5579
5560
|
createEditorStateTransaction,
|
5580
5561
|
createElement,
|
@@ -5613,7 +5594,7 @@ export {
|
|
5613
5594
|
mention,
|
5614
5595
|
overlap,
|
5615
5596
|
preventNewline,
|
5616
|
-
|
5597
|
+
processEditorPayload,
|
5617
5598
|
removeBlockquote,
|
5618
5599
|
removeCodeblock,
|
5619
5600
|
removeLink,
|
@@ -5629,6 +5610,8 @@ export {
|
|
5629
5610
|
setSelection,
|
5630
5611
|
setStyle,
|
5631
5612
|
singleValueFacet,
|
5613
|
+
stackItemContentEditorClassNames,
|
5614
|
+
stackItemContentToolbarClassNames,
|
5632
5615
|
table,
|
5633
5616
|
tags2 as tags,
|
5634
5617
|
textRange,
|
@@ -5646,9 +5629,9 @@ export {
|
|
5646
5629
|
useCommentClickListener,
|
5647
5630
|
useCommentState,
|
5648
5631
|
useComments,
|
5632
|
+
useEditorToolbarState,
|
5649
5633
|
useFormattingState,
|
5650
5634
|
useTextEditor,
|
5651
|
-
useToolbarContext,
|
5652
5635
|
wrapWithCatch
|
5653
5636
|
};
|
5654
5637
|
//# sourceMappingURL=index.mjs.map
|