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