@dxos/react-ui-editor 0.6.9 → 0.6.10-main.3cfcc89
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 +759 -732
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/InputMode.stories.d.ts +2 -1
- package/dist/types/src/InputMode.stories.d.ts.map +1 -1
- package/dist/types/src/TextEditor.stories.d.ts +20 -13
- package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts +5 -1
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts +3 -2
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +2 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +2 -2
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts +10 -0
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/debug.d.ts +11 -0
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts +4 -0
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/styles/tokens.d.ts +2 -5
- package/dist/types/src/styles/tokens.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/package.json +26 -27
- package/src/InputMode.stories.tsx +1 -1
- package/src/TextEditor.stories.tsx +125 -77
- package/src/components/Toolbar/Toolbar.tsx +91 -92
- package/src/defaults.ts +16 -11
- package/src/extensions/annotations.ts +2 -2
- package/src/extensions/autocomplete.ts +4 -1
- package/src/extensions/automerge/automerge.stories.tsx +1 -1
- package/src/extensions/awareness/awareness.ts +1 -1
- package/src/extensions/comments.ts +11 -45
- package/src/extensions/dnd.ts +3 -5
- package/src/extensions/factories.ts +8 -8
- package/src/extensions/folding.tsx +3 -4
- package/src/extensions/markdown/action.ts +1 -0
- package/src/extensions/markdown/bundle.ts +3 -1
- package/src/extensions/markdown/{link-paste.test.ts → changes.test.ts} +2 -2
- package/src/extensions/markdown/changes.ts +148 -0
- package/src/extensions/markdown/debug.ts +44 -0
- package/src/extensions/markdown/decorate.ts +35 -108
- package/src/extensions/markdown/formatting.ts +1 -2
- package/src/extensions/markdown/highlight.ts +2 -2
- package/src/extensions/markdown/index.ts +1 -0
- package/src/extensions/markdown/parser.test.ts +29 -0
- package/src/extensions/markdown/styles.ts +103 -0
- package/src/index.ts +0 -2
- package/src/styles/theme.ts +85 -147
- package/src/styles/tokens.ts +6 -6
- package/src/translations.ts +1 -0
- package/dist/types/src/extensions/markdown/link-paste.d.ts +0 -9
- package/dist/types/src/extensions/markdown/link-paste.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/link-paste.test.d.ts +0 -2
- package/dist/types/src/extensions/markdown/link-paste.test.d.ts.map +0 -1
- package/src/extensions/markdown/link-paste.ts +0 -107
|
@@ -26,6 +26,7 @@ var translations_default = [
|
|
|
26
26
|
"view mode label": "Editor view",
|
|
27
27
|
"preview mode label": "Live preview",
|
|
28
28
|
"readonly mode label": "Read only",
|
|
29
|
+
"search label": "Search",
|
|
29
30
|
"source mode label": "Source"
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -37,282 +38,8 @@ import { keymap as keymap11 } from "@codemirror/view";
|
|
|
37
38
|
import { tags as tags2 } from "@lezer/highlight";
|
|
38
39
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
39
40
|
|
|
40
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
41
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
42
|
-
var headings = {
|
|
43
|
-
1: "text-4xl",
|
|
44
|
-
2: "text-3xl",
|
|
45
|
-
3: "text-2xl",
|
|
46
|
-
4: "text-xl",
|
|
47
|
-
5: "text-lg",
|
|
48
|
-
6: "text-md"
|
|
49
|
-
};
|
|
50
|
-
var theme = {
|
|
51
|
-
mark: "opacity-50",
|
|
52
|
-
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
|
53
|
-
codeMark: "font-mono text-primary-500",
|
|
54
|
-
// TODO(burdon): Replace with widget.
|
|
55
|
-
blockquote: "pl-1 mr-1 border-is-4 border-orange-500 dark:border-orange-500 dark:text-neutral-500",
|
|
56
|
-
heading: (level) => {
|
|
57
|
-
return mx(headings[level], "dark:text-primary-400");
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
62
|
-
import get from "lodash.get";
|
|
63
|
-
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
64
|
-
var tokens = tailwindConfig({}).theme;
|
|
65
|
-
var getToken = (path, defaultValue) => {
|
|
66
|
-
const value = get(tokens, path, defaultValue);
|
|
67
|
-
return value?.toString() ?? "";
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// packages/ui/react-ui-editor/src/styles/theme.ts
|
|
71
|
-
var defaultTheme = {
|
|
72
|
-
"&": {},
|
|
73
|
-
"&.cm-focused": {
|
|
74
|
-
outline: "none"
|
|
75
|
-
},
|
|
76
|
-
/**
|
|
77
|
-
* Scroller
|
|
78
|
-
*/
|
|
79
|
-
".cm-scroller": {
|
|
80
|
-
overflowY: "auto"
|
|
81
|
-
},
|
|
82
|
-
/**
|
|
83
|
-
* Content
|
|
84
|
-
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
|
85
|
-
*/
|
|
86
|
-
".cm-content": {
|
|
87
|
-
padding: "unset",
|
|
88
|
-
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
89
|
-
fontSize: "16px",
|
|
90
|
-
fontFamily: getToken("fontFamily.body"),
|
|
91
|
-
lineHeight: 1.5
|
|
92
|
-
},
|
|
93
|
-
"&light .cm-content": {
|
|
94
|
-
color: getToken("extend.semanticColors.base.fg.light", "black")
|
|
95
|
-
},
|
|
96
|
-
"&dark .cm-content": {
|
|
97
|
-
color: getToken("extend.semanticColors.base.fg.dark", "white")
|
|
98
|
-
},
|
|
99
|
-
/**
|
|
100
|
-
* Gutters
|
|
101
|
-
* NOTE: Gutters should have the same top margin as the content.
|
|
102
|
-
*/
|
|
103
|
-
".cm-gutters": {
|
|
104
|
-
background: "transparent"
|
|
105
|
-
},
|
|
106
|
-
".cm-gutter": {},
|
|
107
|
-
".cm-gutterElement": {
|
|
108
|
-
lineHeight: 1.5
|
|
109
|
-
},
|
|
110
|
-
//
|
|
111
|
-
// Cursor
|
|
112
|
-
//
|
|
113
|
-
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
114
|
-
borderLeft: "2px solid black"
|
|
115
|
-
},
|
|
116
|
-
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
117
|
-
borderLeft: "2px solid white"
|
|
118
|
-
},
|
|
119
|
-
"&light .cm-placeholder": {
|
|
120
|
-
color: getToken("extend.semanticColors.description.light", "rgba(0,0,0,.2)")
|
|
121
|
-
},
|
|
122
|
-
"&dark .cm-placeholder": {
|
|
123
|
-
color: getToken("extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
|
|
124
|
-
},
|
|
125
|
-
//
|
|
126
|
-
// line
|
|
127
|
-
//
|
|
128
|
-
".cm-line": {
|
|
129
|
-
paddingInline: 0
|
|
130
|
-
},
|
|
131
|
-
".cm-activeLine": {
|
|
132
|
-
background: "transparent"
|
|
133
|
-
},
|
|
134
|
-
//
|
|
135
|
-
// gutter
|
|
136
|
-
//
|
|
137
|
-
".cm-lineNumbers": {
|
|
138
|
-
minWidth: "36px"
|
|
139
|
-
},
|
|
140
|
-
//
|
|
141
|
-
// Selection
|
|
142
|
-
//
|
|
143
|
-
"&light .cm-selectionBackground": {
|
|
144
|
-
background: getToken("extend.colors.primary.100")
|
|
145
|
-
},
|
|
146
|
-
"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
147
|
-
background: getToken("extend.colors.primary.200")
|
|
148
|
-
},
|
|
149
|
-
"&dark .cm-selectionBackground": {
|
|
150
|
-
background: getToken("extend.colors.primary.700")
|
|
151
|
-
},
|
|
152
|
-
"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
|
|
153
|
-
background: getToken("extend.colors.primary.600")
|
|
154
|
-
},
|
|
155
|
-
//
|
|
156
|
-
// Search
|
|
157
|
-
//
|
|
158
|
-
"&light .cm-searchMatch": {
|
|
159
|
-
backgroundColor: getToken("extend.colors.yellow.100")
|
|
160
|
-
},
|
|
161
|
-
"&dark .cm-searchMatch": {
|
|
162
|
-
backgroundColor: getToken("extend.colors.yellow.700")
|
|
163
|
-
},
|
|
164
|
-
//
|
|
165
|
-
// link
|
|
166
|
-
//
|
|
167
|
-
".cm-link": {
|
|
168
|
-
textDecorationLine: "underline",
|
|
169
|
-
textDecorationThickness: "1px",
|
|
170
|
-
textUnderlineOffset: "2px",
|
|
171
|
-
borderRadius: ".125rem",
|
|
172
|
-
fontFamily: getToken("fontFamily.body")
|
|
173
|
-
},
|
|
174
|
-
"&light .cm-link > span": {
|
|
175
|
-
color: getToken("extend.colors.primary.600")
|
|
176
|
-
},
|
|
177
|
-
"&dark .cm-link > span": {
|
|
178
|
-
color: getToken("extend.colors.primary.400")
|
|
179
|
-
},
|
|
180
|
-
//
|
|
181
|
-
// tooltip
|
|
182
|
-
//
|
|
183
|
-
".cm-tooltip": {},
|
|
184
|
-
"&light .cm-tooltip": {
|
|
185
|
-
background: `${getToken("extend.colors.neutral.100")} !important`
|
|
186
|
-
},
|
|
187
|
-
"&dark .cm-tooltip": {
|
|
188
|
-
background: `${getToken("extend.colors.neutral.900")} !important`
|
|
189
|
-
},
|
|
190
|
-
".cm-tooltip-below": {},
|
|
191
|
-
//
|
|
192
|
-
// autocomplete
|
|
193
|
-
// https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
194
|
-
//
|
|
195
|
-
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
196
|
-
marginTop: "4px",
|
|
197
|
-
marginLeft: "-3px"
|
|
198
|
-
},
|
|
199
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
200
|
-
maxHeight: "20em !important"
|
|
201
|
-
},
|
|
202
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
|
203
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
|
204
|
-
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
205
|
-
paddingLeft: "4px !important",
|
|
206
|
-
borderBottom: "none !important",
|
|
207
|
-
color: getToken("extend.colors.primary.500")
|
|
208
|
-
},
|
|
209
|
-
".cm-tooltip.cm-completionInfo": {
|
|
210
|
-
border: getToken("extend.colors.neutral.500"),
|
|
211
|
-
width: "360px !important",
|
|
212
|
-
margin: "-10px 1px 0 1px",
|
|
213
|
-
padding: "8px !important"
|
|
214
|
-
},
|
|
215
|
-
".cm-completionIcon": {
|
|
216
|
-
display: "none"
|
|
217
|
-
},
|
|
218
|
-
".cm-completionLabel": {
|
|
219
|
-
fontFamily: getToken("fontFamily.body")
|
|
220
|
-
},
|
|
221
|
-
".cm-completionMatchedText": {
|
|
222
|
-
textDecoration: "none !important",
|
|
223
|
-
opacity: 0.5
|
|
224
|
-
},
|
|
225
|
-
// TODO(burdon): Override vars --cm-background.
|
|
226
|
-
// https://www.npmjs.com/package/codemirror-theme-vars
|
|
227
|
-
/**
|
|
228
|
-
* Panels
|
|
229
|
-
* TODO(burdon): Needs styling attention (esp. dark mode).
|
|
230
|
-
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
231
|
-
*
|
|
232
|
-
* Find/replace panel.
|
|
233
|
-
* <div class="cm-announced">...</div>
|
|
234
|
-
* <div class="cm-scroller">...</div>
|
|
235
|
-
* <div class="cm-panels cm-panels-bottom">
|
|
236
|
-
* <div class="cm-search cm-panel">
|
|
237
|
-
* <input class="cm-textfield" />
|
|
238
|
-
* <button class="cm-button">...</button>
|
|
239
|
-
* <label><input type="checkbox" />...</label>
|
|
240
|
-
* </div>
|
|
241
|
-
* </div
|
|
242
|
-
*/
|
|
243
|
-
".cm-panels": {},
|
|
244
|
-
".cm-panel": {
|
|
245
|
-
fontFamily: getToken("fontFamily.body")
|
|
246
|
-
},
|
|
247
|
-
".cm-panel input[type=checkbox]": {
|
|
248
|
-
marginRight: "0.4rem !important"
|
|
249
|
-
},
|
|
250
|
-
"&light .cm-panel": {
|
|
251
|
-
background: getToken("extend.colors.neutral.50")
|
|
252
|
-
},
|
|
253
|
-
"&dark .cm-panel": {
|
|
254
|
-
background: getToken("extend.colors.neutral.850")
|
|
255
|
-
},
|
|
256
|
-
".cm-button": {
|
|
257
|
-
margin: "4px",
|
|
258
|
-
fontFamily: getToken("fontFamily.body"),
|
|
259
|
-
backgroundImage: "none",
|
|
260
|
-
border: "none",
|
|
261
|
-
"&:active": {
|
|
262
|
-
backgroundImage: "none"
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
"&light .cm-button": {
|
|
266
|
-
background: getToken("extend.colors.neutral.100"),
|
|
267
|
-
"&:hover": {
|
|
268
|
-
background: getToken("extend.colors.neutral.200")
|
|
269
|
-
},
|
|
270
|
-
"&:active": {
|
|
271
|
-
background: getToken("extend.colors.neutral.300")
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
"&dark .cm-button": {
|
|
275
|
-
background: getToken("extend.colors.neutral.800"),
|
|
276
|
-
"&:hover": {
|
|
277
|
-
background: getToken("extend.colors.neutral.700")
|
|
278
|
-
},
|
|
279
|
-
"&:active": {
|
|
280
|
-
background: getToken("extend.colors.neutral.600")
|
|
281
|
-
}
|
|
282
|
-
},
|
|
283
|
-
// TODO(burdon): Factor out element specific logic.
|
|
284
|
-
//
|
|
285
|
-
// table
|
|
286
|
-
//
|
|
287
|
-
".cm-table *": {
|
|
288
|
-
fontFamily: `${getToken("fontFamily.mono")} !important`,
|
|
289
|
-
textDecoration: "none !important"
|
|
290
|
-
},
|
|
291
|
-
".cm-table-head": {
|
|
292
|
-
padding: "2px 16px 2px 0px",
|
|
293
|
-
textAlign: "left",
|
|
294
|
-
borderBottom: `1px solid ${getToken("extend.colors.primary.500")}`,
|
|
295
|
-
color: getToken("extend.colors.neutral.500")
|
|
296
|
-
},
|
|
297
|
-
".cm-table-cell": {
|
|
298
|
-
padding: "2px 16px 2px 0px"
|
|
299
|
-
},
|
|
300
|
-
//
|
|
301
|
-
// image
|
|
302
|
-
//
|
|
303
|
-
".cm-image": {
|
|
304
|
-
display: "block",
|
|
305
|
-
height: "0"
|
|
306
|
-
},
|
|
307
|
-
".cm-image.cm-loaded-image": {
|
|
308
|
-
height: "auto",
|
|
309
|
-
borderTop: "0.5rem solid transparent",
|
|
310
|
-
borderBottom: "0.5rem solid transparent"
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
|
|
314
41
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
315
|
-
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
|
|
42
|
+
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, MagnifyingGlass, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
|
|
316
43
|
import { createContext } from "@radix-ui/react-context";
|
|
317
44
|
import React3, { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
318
45
|
import { useDropzone } from "react-dropzone";
|
|
@@ -413,11 +140,11 @@ var annotations = (options = {}) => {
|
|
|
413
140
|
styles
|
|
414
141
|
];
|
|
415
142
|
};
|
|
416
|
-
var styles = EditorView.
|
|
143
|
+
var styles = EditorView.theme({
|
|
417
144
|
".cm-annotation": {
|
|
418
145
|
textDecoration: "underline",
|
|
419
146
|
textDecorationStyle: "wavy",
|
|
420
|
-
textDecorationColor: "
|
|
147
|
+
textDecorationColor: "var(--dx-error)"
|
|
421
148
|
}
|
|
422
149
|
});
|
|
423
150
|
|
|
@@ -425,7 +152,7 @@ var styles = EditorView.baseTheme({
|
|
|
425
152
|
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
426
153
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
427
154
|
import { keymap } from "@codemirror/view";
|
|
428
|
-
var autocomplete = ({ activateOnTyping, onSearch } = {}) => {
|
|
155
|
+
var autocomplete = ({ activateOnTyping, override, onSearch } = {}) => {
|
|
429
156
|
const extentions = [
|
|
430
157
|
// https://codemirror.net/docs/ref/#view.keymap
|
|
431
158
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
|
@@ -435,6 +162,7 @@ var autocomplete = ({ activateOnTyping, onSearch } = {}) => {
|
|
|
435
162
|
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
|
436
163
|
autocompletion({
|
|
437
164
|
activateOnTyping,
|
|
165
|
+
override,
|
|
438
166
|
// closeOnBlur: false,
|
|
439
167
|
// defaultKeymap: false,
|
|
440
168
|
// TODO(burdon): Styles/fragments.
|
|
@@ -933,7 +661,7 @@ var RemoteCaretWidget = class extends WidgetType {
|
|
|
933
661
|
return true;
|
|
934
662
|
}
|
|
935
663
|
};
|
|
936
|
-
var styles2 = EditorView3.
|
|
664
|
+
var styles2 = EditorView3.theme({
|
|
937
665
|
".cm-collab-selection": {},
|
|
938
666
|
".cm-collab-selectionLine": {
|
|
939
667
|
padding: 0,
|
|
@@ -1756,50 +1484,17 @@ var commentsState = StateField4.define({
|
|
|
1756
1484
|
return value;
|
|
1757
1485
|
}
|
|
1758
1486
|
});
|
|
1759
|
-
var styles3 = EditorView7.
|
|
1487
|
+
var styles3 = EditorView7.theme({
|
|
1760
1488
|
".cm-comment, .cm-comment-current": {
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
// Light theme.
|
|
1768
|
-
"&light .cm-comment": {
|
|
1769
|
-
backgroundColor: getToken("extend.colors.yellow.50"),
|
|
1770
|
-
mixBlendMode: "darken",
|
|
1771
|
-
borderColor: getToken("extend.colors.yellow.100")
|
|
1772
|
-
},
|
|
1773
|
-
"&light .cm-comment:hover": {
|
|
1774
|
-
backgroundColor: getToken("extend.colors.yellow.100")
|
|
1775
|
-
},
|
|
1776
|
-
"&light .cm-comment-current": {
|
|
1777
|
-
backgroundColor: getToken("extend.colors.primary.100"),
|
|
1778
|
-
borderColor: getToken("extend.colors.primary.200")
|
|
1779
|
-
},
|
|
1780
|
-
"&light .cm-comment-current:hover": {
|
|
1781
|
-
backgroundColor: getToken("extend.colors.primary.150"),
|
|
1782
|
-
borderColor: getToken("extend.colors.primary.250")
|
|
1783
|
-
},
|
|
1784
|
-
// Dark theme.
|
|
1785
|
-
"&dark .cm-comment": {
|
|
1786
|
-
color: getToken("extend.colors.yellow.50"),
|
|
1787
|
-
backgroundColor: getToken("extend.colors.yellow.800"),
|
|
1788
|
-
borderColor: getToken("extend.colors.yellow.700"),
|
|
1789
|
-
mixBlendMode: "plus-lighter"
|
|
1790
|
-
},
|
|
1791
|
-
"&dark .cm-comment:hover": {
|
|
1792
|
-
backgroundColor: getToken("extend.colors.yellow.700"),
|
|
1793
|
-
borderColor: getToken("extend.colors.yellow.650")
|
|
1794
|
-
},
|
|
1795
|
-
"&dark .cm-comment-current": {
|
|
1796
|
-
color: getToken("extend.colors.primary.50"),
|
|
1797
|
-
backgroundColor: getToken("extend.colors.primary.800"),
|
|
1798
|
-
borderColor: getToken("extend.colors.primary.700")
|
|
1489
|
+
margin: "0 -3px",
|
|
1490
|
+
padding: "3px",
|
|
1491
|
+
borderRadius: "3px",
|
|
1492
|
+
backgroundColor: "var(--dx-cmCommentSurface)",
|
|
1493
|
+
color: "var(--dx-cmComment)",
|
|
1494
|
+
cursor: "pointer"
|
|
1799
1495
|
},
|
|
1800
|
-
"
|
|
1801
|
-
|
|
1802
|
-
borderColor: getToken("extend.colors.primary.650")
|
|
1496
|
+
".cm-comment:hover, .cm-comment-current": {
|
|
1497
|
+
textDecoration: "underline"
|
|
1803
1498
|
}
|
|
1804
1499
|
});
|
|
1805
1500
|
var createCommentMark = (id, isCurrent) => Decoration4.mark({
|
|
@@ -1818,7 +1513,7 @@ var commentsDecorations = EditorView7.decorations.compute([
|
|
|
1818
1513
|
if (!range) {
|
|
1819
1514
|
log5.warn("Invalid range:", range, {
|
|
1820
1515
|
F: __dxlog_file7,
|
|
1821
|
-
L:
|
|
1516
|
+
L: 147,
|
|
1822
1517
|
S: void 0,
|
|
1823
1518
|
C: (f, a) => f(...a)
|
|
1824
1519
|
});
|
|
@@ -2259,10 +1954,10 @@ var documentId2 = Facet5.define({
|
|
|
2259
1954
|
|
|
2260
1955
|
// packages/ui/react-ui-editor/src/extensions/dnd.ts
|
|
2261
1956
|
import { dropCursor, EditorView as EditorView8 } from "@codemirror/view";
|
|
2262
|
-
var styles4 = EditorView8.
|
|
1957
|
+
var styles4 = EditorView8.theme({
|
|
2263
1958
|
".cm-dropCursor": {
|
|
2264
|
-
borderLeft:
|
|
2265
|
-
color:
|
|
1959
|
+
borderLeft: "2px solid var(--dx-accentText)",
|
|
1960
|
+
color: "var(--dx-accentText)",
|
|
2266
1961
|
padding: "0 4px"
|
|
2267
1962
|
},
|
|
2268
1963
|
".cm-dropCursor:after": {
|
|
@@ -2295,89 +1990,318 @@ var dropFile = (options = {}) => {
|
|
|
2295
1990
|
|
|
2296
1991
|
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
2297
1992
|
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
2298
|
-
import { defaultKeymap, history, historyKeymap, standardKeymap } from "@codemirror/commands";
|
|
1993
|
+
import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
2299
1994
|
import { bracketMatching } from "@codemirror/language";
|
|
2300
1995
|
import { searchKeymap } from "@codemirror/search";
|
|
2301
1996
|
import { EditorState } from "@codemirror/state";
|
|
2302
1997
|
import { EditorView as EditorView9, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
|
|
2303
1998
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1999
|
+
import merge from "lodash.merge";
|
|
2304
2000
|
import { generateName } from "@dxos/display-name";
|
|
2305
2001
|
import { log as log6 } from "@dxos/log";
|
|
2306
2002
|
import { hueTokens } from "@dxos/react-ui-theme";
|
|
2307
2003
|
import { hexToHue, isNotFalsy as isNotFalsy2 } from "@dxos/util";
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
lineWrapping: true,
|
|
2319
|
-
search: true
|
|
2004
|
+
|
|
2005
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
2006
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
2007
|
+
var headings = {
|
|
2008
|
+
1: "text-4xl",
|
|
2009
|
+
2: "text-3xl",
|
|
2010
|
+
3: "text-2xl",
|
|
2011
|
+
4: "text-xl",
|
|
2012
|
+
5: "text-lg",
|
|
2013
|
+
6: "text-md"
|
|
2320
2014
|
};
|
|
2321
|
-
var
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2015
|
+
var theme = {
|
|
2016
|
+
mark: "opacity-50",
|
|
2017
|
+
code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
|
|
2018
|
+
codeMark: "font-mono text-primary-500",
|
|
2019
|
+
// TODO(burdon): Replace with widget.
|
|
2020
|
+
blockquote: "pl-1 mr-1 border-is-4 border-orange-500 dark:border-orange-500 dark:text-neutral-500",
|
|
2021
|
+
heading: (level) => {
|
|
2022
|
+
return mx(headings[level], "dark:text-primary-400");
|
|
2023
|
+
}
|
|
2326
2024
|
};
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2025
|
+
|
|
2026
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
2027
|
+
import get from "lodash.get";
|
|
2028
|
+
import { tokens } from "@dxos/react-ui-theme";
|
|
2029
|
+
var getToken = (path, defaultValue) => {
|
|
2030
|
+
const value = get(tokens, path, defaultValue);
|
|
2031
|
+
return value?.toString() ?? "";
|
|
2032
|
+
};
|
|
2033
|
+
var fontBody = getToken("fontFamily.body");
|
|
2034
|
+
var fontMono = getToken("fontFamily.mono");
|
|
2035
|
+
|
|
2036
|
+
// packages/ui/react-ui-editor/src/styles/theme.ts
|
|
2037
|
+
var defaultTheme = {
|
|
2038
|
+
"&": {},
|
|
2039
|
+
"&.cm-focused": {
|
|
2040
|
+
outline: "none"
|
|
2041
|
+
},
|
|
2042
|
+
/**
|
|
2043
|
+
* Scroller
|
|
2044
|
+
*/
|
|
2045
|
+
".cm-scroller": {
|
|
2046
|
+
overflowY: "auto"
|
|
2047
|
+
},
|
|
2048
|
+
/**
|
|
2049
|
+
* Content
|
|
2050
|
+
* NOTE: Apply margins to content so that scrollbar is at the edge of the container.
|
|
2051
|
+
*/
|
|
2052
|
+
".cm-content": {
|
|
2053
|
+
padding: "unset",
|
|
2054
|
+
fontFamily: fontBody,
|
|
2055
|
+
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
2056
|
+
fontSize: "16px",
|
|
2057
|
+
lineHeight: 1.5,
|
|
2058
|
+
color: "unset"
|
|
2059
|
+
},
|
|
2060
|
+
/**
|
|
2061
|
+
* Gutters
|
|
2062
|
+
* NOTE: Gutters should have the same top margin as the content.
|
|
2063
|
+
*/
|
|
2064
|
+
".cm-gutters": {
|
|
2065
|
+
background: "unset"
|
|
2066
|
+
},
|
|
2067
|
+
".cm-gutter": {},
|
|
2068
|
+
".cm-gutterElement": {
|
|
2069
|
+
fontSize: "16px",
|
|
2070
|
+
lineHeight: 1.5
|
|
2071
|
+
},
|
|
2072
|
+
".cm-lineNumbers": {
|
|
2073
|
+
minWidth: "36px"
|
|
2074
|
+
},
|
|
2075
|
+
/**
|
|
2076
|
+
* Line.
|
|
2077
|
+
*/
|
|
2078
|
+
".cm-line": {
|
|
2079
|
+
paddingInline: 0
|
|
2080
|
+
},
|
|
2081
|
+
".cm-activeLine": {
|
|
2082
|
+
background: "var(--dx-hoverSurface)"
|
|
2083
|
+
},
|
|
2084
|
+
/**
|
|
2085
|
+
* Cursor (layer).
|
|
2086
|
+
*/
|
|
2087
|
+
".cm-cursor, .cm-dropCursor": {
|
|
2088
|
+
borderLeft: "2px solid var(--dx-cmCursor)"
|
|
2089
|
+
},
|
|
2090
|
+
".cm-placeholder": {
|
|
2091
|
+
color: "var(--dx-subdued)"
|
|
2092
|
+
},
|
|
2093
|
+
/**
|
|
2094
|
+
* Selection (layer).
|
|
2095
|
+
*/
|
|
2096
|
+
".cm-selectionBackground": {
|
|
2097
|
+
background: "var(--dx-cmSelection)"
|
|
2098
|
+
},
|
|
2099
|
+
/**
|
|
2100
|
+
* Search.
|
|
2101
|
+
* NOTE: Matches comment.
|
|
2102
|
+
*/
|
|
2103
|
+
".cm-searchMatch": {
|
|
2104
|
+
margin: "0 -3px",
|
|
2105
|
+
padding: "3px",
|
|
2106
|
+
borderRadius: "3px",
|
|
2107
|
+
background: "var(--dx-cmHighlightSurface)",
|
|
2108
|
+
color: "var(--dx-cmHighlight)"
|
|
2109
|
+
},
|
|
2110
|
+
".cm-searchMatch-selected": {
|
|
2111
|
+
textDecoration: "underline"
|
|
2112
|
+
},
|
|
2113
|
+
/**
|
|
2114
|
+
* Link.
|
|
2115
|
+
*/
|
|
2116
|
+
".cm-link": {
|
|
2117
|
+
textDecorationLine: "underline",
|
|
2118
|
+
textDecorationThickness: "1px",
|
|
2119
|
+
textUnderlineOffset: "2px",
|
|
2120
|
+
borderRadius: ".125rem"
|
|
2121
|
+
},
|
|
2122
|
+
".cm-link > span": {
|
|
2123
|
+
color: "var(--dx-accentText)"
|
|
2124
|
+
},
|
|
2125
|
+
/**
|
|
2126
|
+
* Tooltip.
|
|
2127
|
+
*/
|
|
2128
|
+
".cm-tooltip": {
|
|
2129
|
+
background: "var(--dx-base)"
|
|
2130
|
+
},
|
|
2131
|
+
".cm-tooltip-below": {},
|
|
2132
|
+
/**
|
|
2133
|
+
* Autocomplete.
|
|
2134
|
+
* https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
2135
|
+
*/
|
|
2136
|
+
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
2137
|
+
marginTop: "4px",
|
|
2138
|
+
marginLeft: "-3px"
|
|
2139
|
+
},
|
|
2140
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
|
2141
|
+
maxHeight: "20em !important"
|
|
2142
|
+
},
|
|
2143
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
|
|
2144
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
|
2145
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2146
|
+
paddingLeft: "4px !important",
|
|
2147
|
+
borderBottom: "none !important",
|
|
2148
|
+
color: "var(--dx-accentText)"
|
|
2149
|
+
},
|
|
2150
|
+
".cm-tooltip.cm-completionInfo": {
|
|
2151
|
+
width: "360px !important",
|
|
2152
|
+
margin: "-10px 1px 0 1px",
|
|
2153
|
+
padding: "8px !important",
|
|
2154
|
+
borderColor: "var(--dx-separator)"
|
|
2155
|
+
},
|
|
2156
|
+
".cm-completionIcon": {
|
|
2157
|
+
display: "none"
|
|
2158
|
+
},
|
|
2159
|
+
".cm-completionLabel": {
|
|
2160
|
+
fontFamily: fontBody
|
|
2161
|
+
},
|
|
2162
|
+
".cm-completionMatchedText": {
|
|
2163
|
+
textDecoration: "none !important",
|
|
2164
|
+
opacity: 0.5
|
|
2165
|
+
},
|
|
2166
|
+
/**
|
|
2167
|
+
* Panels
|
|
2168
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
2169
|
+
*
|
|
2170
|
+
* Find/replace panel.
|
|
2171
|
+
* <div class="cm-announced">...</div>
|
|
2172
|
+
* <div class="cm-scroller">...</div>
|
|
2173
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
2174
|
+
* <div class="cm-search cm-panel">
|
|
2175
|
+
* <input class="cm-textfield" />
|
|
2176
|
+
* <button class="cm-button">...</button>
|
|
2177
|
+
* <label><input type="checkbox" />...</label>
|
|
2178
|
+
* </div>
|
|
2179
|
+
* </div
|
|
2180
|
+
*/
|
|
2181
|
+
// TODO(burdon): Apply react-ui-theme or replace panel.
|
|
2182
|
+
".cm-panels": {},
|
|
2183
|
+
".cm-panel": {
|
|
2184
|
+
fontFamily: fontBody,
|
|
2185
|
+
backgroundColor: "var(--dx-base)"
|
|
2186
|
+
},
|
|
2187
|
+
".cm-panel input, .cm-panel button, .cm-panel label": {
|
|
2188
|
+
fontFamily: fontBody,
|
|
2189
|
+
fontSize: "14px",
|
|
2190
|
+
all: "unset",
|
|
2191
|
+
margin: "3px !important",
|
|
2192
|
+
padding: "2px 6px !important",
|
|
2193
|
+
outline: "1px solid transparent"
|
|
2194
|
+
},
|
|
2195
|
+
".cm-panel input, .cm-panel button": {
|
|
2196
|
+
backgroundColor: "var(--dx-input)"
|
|
2197
|
+
},
|
|
2198
|
+
".cm-panel input:focus, .cm-panel button:focus": {
|
|
2199
|
+
outline: "1px solid var(--dx-accentFocusIndicator)"
|
|
2200
|
+
},
|
|
2201
|
+
".cm-panel label": {
|
|
2202
|
+
display: "inline-flex",
|
|
2203
|
+
alignItems: "center",
|
|
2204
|
+
cursor: "pointer"
|
|
2205
|
+
},
|
|
2206
|
+
".cm-panel input.cm-textfield": {},
|
|
2207
|
+
".cm-panel input[type=checkbox]": {
|
|
2208
|
+
width: "8px",
|
|
2209
|
+
height: "8px",
|
|
2210
|
+
marginRight: "6px !important",
|
|
2211
|
+
padding: "2px !important",
|
|
2212
|
+
color: "var(--dx-accentFocusIndicator)"
|
|
2213
|
+
},
|
|
2214
|
+
".cm-panel button": {
|
|
2215
|
+
"&:hover": {
|
|
2216
|
+
backgroundColor: "var(--dx-accentSurfaceHover) !important"
|
|
2217
|
+
},
|
|
2218
|
+
"&:active": {
|
|
2219
|
+
backgroundColor: "var(--dx-accentSurfaceHover)"
|
|
2220
|
+
}
|
|
2221
|
+
},
|
|
2222
|
+
".cm-panel.cm-search": {
|
|
2223
|
+
padding: "4px",
|
|
2224
|
+
borderTop: "1px solid var(--dx-separator)"
|
|
2225
|
+
}
|
|
2226
|
+
};
|
|
2227
|
+
|
|
2228
|
+
// packages/ui/react-ui-editor/src/extensions/factories.ts
|
|
2229
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
|
|
2230
|
+
var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
|
|
2231
|
+
var defaultBasicOptions = {
|
|
2232
|
+
allowMultipleSelections: true,
|
|
2233
|
+
bracketMatching: true,
|
|
2234
|
+
closeBrackets: true,
|
|
2235
|
+
drawSelection: true,
|
|
2236
|
+
editable: true,
|
|
2237
|
+
history: true,
|
|
2238
|
+
keymap: "standard",
|
|
2239
|
+
lineWrapping: true,
|
|
2240
|
+
search: true
|
|
2241
|
+
};
|
|
2242
|
+
var keymaps = {
|
|
2243
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
2244
|
+
standard: standardKeymap,
|
|
2245
|
+
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
2246
|
+
default: defaultKeymap
|
|
2247
|
+
};
|
|
2248
|
+
var createBasicExtensions = (_props) => {
|
|
2249
|
+
const props = defaultsDeep2({}, _props, defaultBasicOptions);
|
|
2250
|
+
return [
|
|
2251
|
+
// NOTE: Doesn't catch errors in keymap functions.
|
|
2252
|
+
EditorView9.exceptionSink.of((err) => {
|
|
2253
|
+
log6.catch(err, void 0, {
|
|
2254
|
+
F: __dxlog_file9,
|
|
2255
|
+
L: 92,
|
|
2256
|
+
S: void 0,
|
|
2257
|
+
C: (f, a) => f(...a)
|
|
2258
|
+
});
|
|
2259
|
+
}),
|
|
2260
|
+
props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
|
|
2261
|
+
props.bracketMatching && bracketMatching(),
|
|
2262
|
+
props.closeBrackets && closeBrackets(),
|
|
2263
|
+
props.dropCursor && dropCursor2(),
|
|
2264
|
+
props.drawSelection && drawSelection({
|
|
2265
|
+
cursorBlinkRate: 1200
|
|
2266
|
+
}),
|
|
2267
|
+
props.highlightActiveLine && highlightActiveLine(),
|
|
2268
|
+
props.history && history(),
|
|
2269
|
+
props.lineNumbers && lineNumbers(),
|
|
2270
|
+
props.lineWrapping && EditorView9.lineWrapping,
|
|
2271
|
+
props.placeholder && placeholder(props.placeholder),
|
|
2272
|
+
props.readonly && [
|
|
2273
|
+
EditorState.readOnly.of(true),
|
|
2274
|
+
EditorView9.editable.of(false)
|
|
2275
|
+
],
|
|
2276
|
+
props.scrollPastEnd && scrollPastEnd(),
|
|
2277
|
+
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
2278
|
+
// https://codemirror.net/docs/ref/#view.KeyBinding
|
|
2279
|
+
keymap5.of([
|
|
2280
|
+
...(props.keymap && keymaps[props.keymap]) ?? [],
|
|
2281
|
+
// NOTE: Tabs are also configured by markdown extension.
|
|
2282
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
2283
|
+
...props.indentWithTab ? [
|
|
2284
|
+
indentWithTab
|
|
2285
|
+
] : [],
|
|
2286
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
2287
|
+
...props.closeBrackets ? closeBracketsKeymap : [],
|
|
2288
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
2289
|
+
...props.history ? historyKeymap : [],
|
|
2290
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
2291
|
+
...props.search ? searchKeymap : []
|
|
2292
|
+
].filter(isNotFalsy2))
|
|
2293
|
+
].filter(isNotFalsy2);
|
|
2369
2294
|
};
|
|
2370
2295
|
var defaultThemeSlots = {
|
|
2371
2296
|
editor: {
|
|
2372
2297
|
className: "w-full bs-full"
|
|
2373
2298
|
}
|
|
2374
2299
|
};
|
|
2375
|
-
var createThemeExtensions = ({
|
|
2300
|
+
var createThemeExtensions = ({ themeMode, styles: styles5, slots: _slots } = {}) => {
|
|
2376
2301
|
const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
|
|
2377
2302
|
return [
|
|
2378
|
-
EditorView9.baseTheme(defaultTheme),
|
|
2379
2303
|
EditorView9.darkTheme.of(themeMode === "dark"),
|
|
2380
|
-
|
|
2304
|
+
EditorView9.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
|
|
2381
2305
|
slots.editor?.className && EditorView9.editorAttributes.of({
|
|
2382
2306
|
class: slots.editor.className
|
|
2383
2307
|
}),
|
|
@@ -2411,18 +2335,22 @@ var createDataExtensions = ({ id, text, space, identity }) => {
|
|
|
2411
2335
|
// packages/ui/react-ui-editor/src/extensions/folding.tsx
|
|
2412
2336
|
import { codeFolding, foldGutter } from "@codemirror/language";
|
|
2413
2337
|
import React2 from "react";
|
|
2414
|
-
import {
|
|
2338
|
+
import { Icon } from "@dxos/react-ui";
|
|
2339
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
2415
2340
|
var folding = (_props = {}) => [
|
|
2416
2341
|
codeFolding({
|
|
2417
2342
|
placeholderDOM: () => document.createElement("div")
|
|
2418
2343
|
}),
|
|
2419
2344
|
foldGutter({
|
|
2420
2345
|
markerDOM: (open) => {
|
|
2421
|
-
return renderRoot(document.createElement("div"), /* @__PURE__ */ React2.createElement(
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2346
|
+
return renderRoot(document.createElement("div"), /* @__PURE__ */ React2.createElement(Icon, {
|
|
2347
|
+
icon: "ph--caret-right--regular",
|
|
2348
|
+
classNames: [
|
|
2349
|
+
getSize(3),
|
|
2350
|
+
"m-2 cursor-pointer",
|
|
2351
|
+
open && "rotate-90"
|
|
2352
|
+
]
|
|
2353
|
+
}));
|
|
2426
2354
|
}
|
|
2427
2355
|
})
|
|
2428
2356
|
];
|
|
@@ -2443,7 +2371,6 @@ var listener = ({ onFocus, onChange }) => {
|
|
|
2443
2371
|
|
|
2444
2372
|
// packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
|
|
2445
2373
|
import { snippet } from "@codemirror/autocomplete";
|
|
2446
|
-
import { indentWithTab } from "@codemirror/commands";
|
|
2447
2374
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
2448
2375
|
import { EditorSelection } from "@codemirror/state";
|
|
2449
2376
|
import { EditorView as EditorView11, keymap as keymap6 } from "@codemirror/view";
|
|
@@ -3792,7 +3719,7 @@ var markdownHighlightStyle = (_options = {}) => {
|
|
|
3792
3719
|
], {
|
|
3793
3720
|
scope: markdownLanguage2,
|
|
3794
3721
|
all: {
|
|
3795
|
-
fontFamily:
|
|
3722
|
+
fontFamily: fontBody
|
|
3796
3723
|
}
|
|
3797
3724
|
});
|
|
3798
3725
|
};
|
|
@@ -3812,6 +3739,8 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
|
3812
3739
|
base: markdownLanguage3,
|
|
3813
3740
|
// Languages for syntax highlighting fenced code blocks.
|
|
3814
3741
|
codeLanguages: languages,
|
|
3742
|
+
// Don't complete HTML tags.
|
|
3743
|
+
completeHTMLTags: false,
|
|
3815
3744
|
// Parser extensions.
|
|
3816
3745
|
extensions: [
|
|
3817
3746
|
// GFM provided by default.
|
|
@@ -3823,7 +3752,6 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
|
3823
3752
|
// Custom styles.
|
|
3824
3753
|
syntaxHighlighting(markdownHighlightStyle()),
|
|
3825
3754
|
keymap7.of([
|
|
3826
|
-
// TODO(burdon): Indent by 4 if in task list.
|
|
3827
3755
|
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
3828
3756
|
indentWithTab2,
|
|
3829
3757
|
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
@@ -3834,44 +3762,209 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
|
|
|
3834
3762
|
];
|
|
3835
3763
|
};
|
|
3836
3764
|
|
|
3765
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/debug.ts
|
|
3766
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
3767
|
+
import { StateField as StateField6 } from "@codemirror/state";
|
|
3768
|
+
var debugTree = (cb) => StateField6.define({
|
|
3769
|
+
create: (state2) => cb(convertTreeToJson(state2)),
|
|
3770
|
+
update: (value, tr) => cb(convertTreeToJson(tr.state))
|
|
3771
|
+
});
|
|
3772
|
+
var convertTreeToJson = (state2) => {
|
|
3773
|
+
const treeToJson = (cursor) => {
|
|
3774
|
+
const node = {
|
|
3775
|
+
type: cursor.type.name,
|
|
3776
|
+
from: cursor.from,
|
|
3777
|
+
to: cursor.to,
|
|
3778
|
+
text: state2.doc.slice(cursor.from, cursor.to).toString(),
|
|
3779
|
+
children: []
|
|
3780
|
+
};
|
|
3781
|
+
if (cursor.firstChild()) {
|
|
3782
|
+
do {
|
|
3783
|
+
node.children.push(treeToJson(cursor));
|
|
3784
|
+
} while (cursor.nextSibling());
|
|
3785
|
+
cursor.parent();
|
|
3786
|
+
}
|
|
3787
|
+
return node;
|
|
3788
|
+
};
|
|
3789
|
+
return treeToJson(syntaxTree3(state2).cursor());
|
|
3790
|
+
};
|
|
3791
|
+
|
|
3837
3792
|
// packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
|
|
3838
|
-
import { syntaxTree as
|
|
3793
|
+
import { syntaxTree as syntaxTree7 } from "@codemirror/language";
|
|
3839
3794
|
import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect4 } from "@codemirror/state";
|
|
3840
|
-
import { EditorView as
|
|
3795
|
+
import { EditorView as EditorView15, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
|
|
3841
3796
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
3842
|
-
import { mx as
|
|
3797
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
3843
3798
|
|
|
3844
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
3845
|
-
import { syntaxTree as
|
|
3846
|
-
import {
|
|
3847
|
-
import {
|
|
3848
|
-
var
|
|
3849
|
-
return
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3799
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
|
|
3800
|
+
import { syntaxTree as syntaxTree4 } from "@codemirror/language";
|
|
3801
|
+
import { Transaction } from "@codemirror/state";
|
|
3802
|
+
import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
|
|
3803
|
+
var adjustChanges = () => {
|
|
3804
|
+
return ViewPlugin5.fromClass(class {
|
|
3805
|
+
update(update2) {
|
|
3806
|
+
const tree = syntaxTree4(update2.state);
|
|
3807
|
+
const adjustments = [];
|
|
3808
|
+
for (const tr of update2.transactions) {
|
|
3809
|
+
const event = tr.annotation(Transaction.userEvent);
|
|
3810
|
+
switch (event) {
|
|
3811
|
+
case "input": {
|
|
3812
|
+
const changes = tr.changes;
|
|
3813
|
+
if (changes.empty) {
|
|
3814
|
+
break;
|
|
3815
|
+
}
|
|
3816
|
+
changes.iterChanges((fromA) => {
|
|
3817
|
+
const node = tree.resolveInner(fromA, 1);
|
|
3818
|
+
if (node?.name === "BulletList") {
|
|
3819
|
+
const { text } = update2.state.doc.lineAt(fromA);
|
|
3820
|
+
if (text.endsWith("]")) {
|
|
3821
|
+
adjustments.push({
|
|
3822
|
+
from: fromA,
|
|
3823
|
+
to: fromA,
|
|
3824
|
+
insert: " "
|
|
3825
|
+
});
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3828
|
+
});
|
|
3829
|
+
break;
|
|
3830
|
+
}
|
|
3831
|
+
case "input.paste": {
|
|
3832
|
+
const changes = tr.changes;
|
|
3833
|
+
if (changes.empty) {
|
|
3834
|
+
break;
|
|
3835
|
+
}
|
|
3836
|
+
changes.iterChanges((fromA, toA, fromB, toB, text) => {
|
|
3837
|
+
const url = getValidUrl(update2.view.state.sliceDoc(fromB, toB));
|
|
3838
|
+
if (url) {
|
|
3839
|
+
const node = tree.resolveInner(fromA, -1);
|
|
3840
|
+
const invalidPositions = /* @__PURE__ */ new Set([
|
|
3841
|
+
"Link",
|
|
3842
|
+
"LinkMark",
|
|
3843
|
+
"Code",
|
|
3844
|
+
"CodeText",
|
|
3845
|
+
"FencedCode",
|
|
3846
|
+
"URL"
|
|
3847
|
+
]);
|
|
3848
|
+
if (!invalidPositions.has(node?.name)) {
|
|
3849
|
+
const replacedText = tr.startState.sliceDoc(fromA, toA);
|
|
3850
|
+
adjustments.push({
|
|
3851
|
+
from: fromA,
|
|
3852
|
+
to: toB,
|
|
3853
|
+
insert: createLink(url, replacedText)
|
|
3854
|
+
});
|
|
3855
|
+
}
|
|
3856
|
+
} else {
|
|
3857
|
+
const node = tree.resolveInner(fromA, 1);
|
|
3858
|
+
switch (node?.name) {
|
|
3859
|
+
case "Task": {
|
|
3860
|
+
const str = text.toString();
|
|
3861
|
+
const match = str.match(/\s*- \[[ xX]\]\s*(.+)/);
|
|
3862
|
+
if (match) {
|
|
3863
|
+
const [, replacement] = match;
|
|
3864
|
+
adjustments.push({
|
|
3865
|
+
from: fromA,
|
|
3866
|
+
to: toB,
|
|
3867
|
+
insert: replacement
|
|
3868
|
+
});
|
|
3869
|
+
}
|
|
3870
|
+
break;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
});
|
|
3875
|
+
break;
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3856
3878
|
}
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3879
|
+
if (adjustments.length) {
|
|
3880
|
+
setTimeout(() => {
|
|
3881
|
+
update2.view.dispatch(update2.view.state.update({
|
|
3882
|
+
changes: adjustments
|
|
3883
|
+
}));
|
|
3884
|
+
});
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3887
|
+
});
|
|
3888
|
+
};
|
|
3889
|
+
var createLink = (url, label) => {
|
|
3890
|
+
const { host, pathname } = url;
|
|
3891
|
+
const [, extension] = pathname.split(".");
|
|
3892
|
+
const imageExtensions = [
|
|
3893
|
+
"jpg",
|
|
3894
|
+
"jpeg",
|
|
3895
|
+
"png",
|
|
3896
|
+
"gif",
|
|
3897
|
+
"svg",
|
|
3898
|
+
"webp"
|
|
3899
|
+
];
|
|
3900
|
+
if (imageExtensions.includes(extension)) {
|
|
3901
|
+
return ``;
|
|
3902
|
+
}
|
|
3903
|
+
if (!label) {
|
|
3904
|
+
label = createLinkLabel(url);
|
|
3905
|
+
}
|
|
3906
|
+
return `[${label}](${url})`;
|
|
3907
|
+
};
|
|
3908
|
+
var createLinkLabel = (url) => {
|
|
3909
|
+
let { protocol, host, pathname } = url;
|
|
3910
|
+
if (protocol === "http:" || protocol === "https:") {
|
|
3911
|
+
protocol = "";
|
|
3912
|
+
}
|
|
3913
|
+
host = host.replace(/^www\./, "");
|
|
3914
|
+
return [
|
|
3915
|
+
protocol,
|
|
3916
|
+
host
|
|
3917
|
+
].filter(Boolean).join("//") + (pathname !== "/" ? pathname : "");
|
|
3918
|
+
};
|
|
3919
|
+
var getValidUrl = (str) => {
|
|
3920
|
+
const validProtocols = [
|
|
3921
|
+
"http:",
|
|
3922
|
+
"https:",
|
|
3923
|
+
"mailto:",
|
|
3924
|
+
"tel:"
|
|
3925
|
+
];
|
|
3926
|
+
try {
|
|
3927
|
+
const url = new URL(str);
|
|
3928
|
+
if (!validProtocols.includes(url.protocol)) {
|
|
3929
|
+
return void 0;
|
|
3930
|
+
}
|
|
3931
|
+
return url;
|
|
3932
|
+
} catch (_err) {
|
|
3933
|
+
return void 0;
|
|
3934
|
+
}
|
|
3935
|
+
};
|
|
3936
|
+
|
|
3937
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/image.ts
|
|
3938
|
+
import { syntaxTree as syntaxTree5 } from "@codemirror/language";
|
|
3939
|
+
import { StateField as StateField7 } from "@codemirror/state";
|
|
3940
|
+
import { Decoration as Decoration5, EditorView as EditorView12, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
3941
|
+
var image = (_options = {}) => {
|
|
3942
|
+
return StateField7.define({
|
|
3943
|
+
create: (state2) => {
|
|
3944
|
+
return Decoration5.set(buildDecorations(0, state2.doc.length, state2));
|
|
3945
|
+
},
|
|
3946
|
+
update: (value, tr) => {
|
|
3947
|
+
if (!tr.docChanged && !tr.selection) {
|
|
3948
|
+
return value;
|
|
3949
|
+
}
|
|
3950
|
+
const cursor = tr.state.selection.main.head;
|
|
3951
|
+
const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
|
|
3952
|
+
let from = Math.min(cursor, oldCursor);
|
|
3953
|
+
let to = Math.max(cursor, oldCursor);
|
|
3954
|
+
tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
|
3955
|
+
from = Math.min(from, fromB);
|
|
3956
|
+
to = Math.max(to, toB);
|
|
3957
|
+
});
|
|
3958
|
+
from = tr.state.doc.lineAt(from).from;
|
|
3959
|
+
to = tr.state.doc.lineAt(to).to;
|
|
3960
|
+
return value.map(tr.changes).update({
|
|
3961
|
+
filterFrom: from,
|
|
3962
|
+
filterTo: to,
|
|
3963
|
+
filter: () => false,
|
|
3964
|
+
add: buildDecorations(from, to, tr.state)
|
|
3965
|
+
});
|
|
3966
|
+
},
|
|
3967
|
+
provide: (field) => EditorView12.decorations.from(field)
|
|
3875
3968
|
});
|
|
3876
3969
|
};
|
|
3877
3970
|
var preloaded = /* @__PURE__ */ new Set();
|
|
@@ -3885,7 +3978,7 @@ var preloadImage = (url) => {
|
|
|
3885
3978
|
var buildDecorations = (from, to, state2) => {
|
|
3886
3979
|
const decorations = [];
|
|
3887
3980
|
const cursor = state2.selection.main.head;
|
|
3888
|
-
|
|
3981
|
+
syntaxTree5(state2).iterate({
|
|
3889
3982
|
enter: (node) => {
|
|
3890
3983
|
if (node.name === "Image") {
|
|
3891
3984
|
const urlNode = node.node.getChild("URL");
|
|
@@ -3924,112 +4017,107 @@ var ImageWidget = class extends WidgetType3 {
|
|
|
3924
4017
|
var imageUpload = (options = {}) => {
|
|
3925
4018
|
};
|
|
3926
4019
|
|
|
3927
|
-
// packages/ui/react-ui-editor/src/extensions/markdown/
|
|
3928
|
-
import {
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
var
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
4020
|
+
// packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
|
|
4021
|
+
import { EditorView as EditorView13 } from "@codemirror/view";
|
|
4022
|
+
var bulletListIndentationWidth = 24;
|
|
4023
|
+
var orderedListIndentationWidth = 36;
|
|
4024
|
+
var formattingStyles = EditorView13.theme({
|
|
4025
|
+
/**
|
|
4026
|
+
* Horizontal rule.
|
|
4027
|
+
*/
|
|
4028
|
+
"& .cm-hr": {
|
|
4029
|
+
display: "inline-block",
|
|
4030
|
+
width: "100%",
|
|
4031
|
+
height: "0",
|
|
4032
|
+
verticalAlign: "middle",
|
|
4033
|
+
borderTop: "1px solid var(--dx-cmSeparator)",
|
|
4034
|
+
opacity: 0.5
|
|
4035
|
+
},
|
|
4036
|
+
/**
|
|
4037
|
+
* Lists.
|
|
4038
|
+
*/
|
|
4039
|
+
"& .cm-list-item": {},
|
|
4040
|
+
"& .cm-list-mark": {
|
|
4041
|
+
display: "inline-block",
|
|
4042
|
+
textAlign: "right",
|
|
4043
|
+
paddingRight: "0.5em",
|
|
4044
|
+
fontVariant: "tabular-nums"
|
|
4045
|
+
},
|
|
4046
|
+
"& .cm-list-mark-bullet": {
|
|
4047
|
+
width: `${bulletListIndentationWidth}px`
|
|
4048
|
+
},
|
|
4049
|
+
"& .cm-list-mark-ordered": {
|
|
4050
|
+
width: `${orderedListIndentationWidth}px`
|
|
4051
|
+
},
|
|
4052
|
+
/**
|
|
4053
|
+
* Code and codeblocks.
|
|
4054
|
+
*/
|
|
4055
|
+
"& .cm-code": {
|
|
4056
|
+
fontFamily: fontMono
|
|
4057
|
+
},
|
|
4058
|
+
"& .cm-codeblock-line": {
|
|
4059
|
+
background: "var(--dx-cmCodeblock)",
|
|
4060
|
+
paddingInline: "1rem !important"
|
|
4061
|
+
},
|
|
4062
|
+
"& .cm-codeblock-first": {
|
|
4063
|
+
borderTopLeftRadius: ".25rem",
|
|
4064
|
+
borderTopRightRadius: ".25rem"
|
|
4065
|
+
},
|
|
4066
|
+
"& .cm-codeblock-last": {
|
|
4067
|
+
borderBottomLeftRadius: ".25rem",
|
|
4068
|
+
borderBottomRightRadius: ".25rem"
|
|
4069
|
+
},
|
|
4070
|
+
/**
|
|
4071
|
+
* Task list.
|
|
4072
|
+
*/
|
|
4073
|
+
"& .cm-task": {
|
|
4074
|
+
display: "inline-block",
|
|
4075
|
+
width: `${bulletListIndentationWidth}px`
|
|
4076
|
+
},
|
|
4077
|
+
"& .cm-task-checkbox": {
|
|
4078
|
+
display: "grid",
|
|
4079
|
+
margin: "0",
|
|
4080
|
+
transform: "translateY(2px)"
|
|
4081
|
+
},
|
|
4082
|
+
/**
|
|
4083
|
+
* Table.
|
|
4084
|
+
*/
|
|
4085
|
+
".cm-table *": {
|
|
4086
|
+
fontFamily: fontMono,
|
|
4087
|
+
textDecoration: "none !important"
|
|
4088
|
+
},
|
|
4089
|
+
".cm-table-head": {
|
|
4090
|
+
padding: "2px 16px 2px 0px",
|
|
4091
|
+
textAlign: "left",
|
|
4092
|
+
borderBottom: "1px solid var(--dx-cmSeparator)",
|
|
4093
|
+
color: "var(--dx-subdued)"
|
|
4094
|
+
},
|
|
4095
|
+
".cm-table-cell": {
|
|
4096
|
+
padding: "2px 16px 2px 0px"
|
|
4097
|
+
},
|
|
4098
|
+
/**
|
|
4099
|
+
* Image.
|
|
4100
|
+
*/
|
|
4101
|
+
".cm-image": {
|
|
4102
|
+
display: "block",
|
|
4103
|
+
height: "0"
|
|
4104
|
+
},
|
|
4105
|
+
".cm-image.cm-loaded-image": {
|
|
4106
|
+
height: "auto",
|
|
4107
|
+
borderTop: "0.5rem solid transparent",
|
|
4108
|
+
borderBottom: "0.5rem solid transparent"
|
|
3957
4109
|
}
|
|
3958
4110
|
});
|
|
3959
|
-
var createLink = (url, label) => {
|
|
3960
|
-
const { host, pathname } = url;
|
|
3961
|
-
const [, extension] = pathname.split(".");
|
|
3962
|
-
const imageExtensions = [
|
|
3963
|
-
"jpg",
|
|
3964
|
-
"jpeg",
|
|
3965
|
-
"png",
|
|
3966
|
-
"gif",
|
|
3967
|
-
"svg",
|
|
3968
|
-
"webp"
|
|
3969
|
-
];
|
|
3970
|
-
if (imageExtensions.includes(extension)) {
|
|
3971
|
-
return ``;
|
|
3972
|
-
}
|
|
3973
|
-
if (!label) {
|
|
3974
|
-
label = createLinkLabel(url);
|
|
3975
|
-
}
|
|
3976
|
-
return `[${label}](${url})`;
|
|
3977
|
-
};
|
|
3978
|
-
var createLinkLabel = (url) => {
|
|
3979
|
-
let { protocol, host, pathname } = url;
|
|
3980
|
-
if (protocol === "http:" || protocol === "https:") {
|
|
3981
|
-
protocol = "";
|
|
3982
|
-
}
|
|
3983
|
-
host = host.replace(/^www\./, "");
|
|
3984
|
-
return [
|
|
3985
|
-
protocol,
|
|
3986
|
-
host
|
|
3987
|
-
].filter(Boolean).join("//") + (pathname !== "/" ? pathname : "");
|
|
3988
|
-
};
|
|
3989
|
-
var getValidUrl = (str) => {
|
|
3990
|
-
const validProtocols = [
|
|
3991
|
-
"http:",
|
|
3992
|
-
"https:",
|
|
3993
|
-
"mailto:",
|
|
3994
|
-
"tel:"
|
|
3995
|
-
];
|
|
3996
|
-
try {
|
|
3997
|
-
const url = new URL(str);
|
|
3998
|
-
if (!validProtocols.includes(url.protocol)) {
|
|
3999
|
-
return void 0;
|
|
4000
|
-
}
|
|
4001
|
-
return url;
|
|
4002
|
-
} catch (_err) {
|
|
4003
|
-
return void 0;
|
|
4004
|
-
}
|
|
4005
|
-
};
|
|
4006
|
-
var isValidPosition = (state2, pos) => {
|
|
4007
|
-
const invalidPositions = /* @__PURE__ */ new Set([
|
|
4008
|
-
"Link",
|
|
4009
|
-
"LinkMark",
|
|
4010
|
-
"Code",
|
|
4011
|
-
"FencedCode"
|
|
4012
|
-
]);
|
|
4013
|
-
const tree = syntaxTree4(state2);
|
|
4014
|
-
let node = tree.resolveInner(pos, -1);
|
|
4015
|
-
while (node) {
|
|
4016
|
-
if (invalidPositions.has(node.name)) {
|
|
4017
|
-
return false;
|
|
4018
|
-
}
|
|
4019
|
-
node = node.parent;
|
|
4020
|
-
}
|
|
4021
|
-
return true;
|
|
4022
|
-
};
|
|
4023
4111
|
|
|
4024
4112
|
// packages/ui/react-ui-editor/src/extensions/markdown/table.ts
|
|
4025
|
-
import { syntaxTree as
|
|
4026
|
-
import { RangeSetBuilder as RangeSetBuilder2, StateField as
|
|
4027
|
-
import { Decoration as Decoration6, EditorView as
|
|
4113
|
+
import { syntaxTree as syntaxTree6 } from "@codemirror/language";
|
|
4114
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField8 } from "@codemirror/state";
|
|
4115
|
+
import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
4028
4116
|
var table = (options = {}) => {
|
|
4029
|
-
return
|
|
4117
|
+
return StateField8.define({
|
|
4030
4118
|
create: (state2) => update(state2, options),
|
|
4031
4119
|
update: (_, tr) => update(tr.state, options),
|
|
4032
|
-
provide: (field) =>
|
|
4120
|
+
provide: (field) => EditorView14.decorations.from(field)
|
|
4033
4121
|
});
|
|
4034
4122
|
};
|
|
4035
4123
|
var update = (state2, _options) => {
|
|
@@ -4041,7 +4129,7 @@ var update = (state2, _options) => {
|
|
|
4041
4129
|
const table2 = getTable();
|
|
4042
4130
|
return table2.rows?.[table2.rows.length - 1];
|
|
4043
4131
|
};
|
|
4044
|
-
|
|
4132
|
+
syntaxTree6(state2).iterate({
|
|
4045
4133
|
enter: (node) => {
|
|
4046
4134
|
switch (node.name) {
|
|
4047
4135
|
case "Table": {
|
|
@@ -4202,13 +4290,13 @@ var TextWidget = class extends WidgetType5 {
|
|
|
4202
4290
|
};
|
|
4203
4291
|
var hide = Decoration7.replace({});
|
|
4204
4292
|
var fencedCodeLine = Decoration7.line({
|
|
4205
|
-
class:
|
|
4293
|
+
class: mx2("cm-code cm-codeblock-line")
|
|
4206
4294
|
});
|
|
4207
4295
|
var fencedCodeLineFirst = Decoration7.line({
|
|
4208
|
-
class:
|
|
4296
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
|
|
4209
4297
|
});
|
|
4210
4298
|
var fencedCodeLineLast = Decoration7.line({
|
|
4211
|
-
class:
|
|
4299
|
+
class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
|
|
4212
4300
|
});
|
|
4213
4301
|
var commentBlockLine = fencedCodeLine;
|
|
4214
4302
|
var commentBlockLineFirst = fencedCodeLineFirst;
|
|
@@ -4234,8 +4322,6 @@ var autoHideTags = /* @__PURE__ */ new Set([
|
|
|
4234
4322
|
"SubscriptMark",
|
|
4235
4323
|
"SuperscriptMark"
|
|
4236
4324
|
]);
|
|
4237
|
-
var bulletListIndentationWidth = 24;
|
|
4238
|
-
var orderedListIndentationWidth = 32;
|
|
4239
4325
|
var buildDecorations2 = (view, options, focus) => {
|
|
4240
4326
|
const deco = new RangeSetBuilder3();
|
|
4241
4327
|
const atomicDeco = new RangeSetBuilder3();
|
|
@@ -4244,7 +4330,7 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4244
4330
|
const getHeaderLevels = (node, level) => {
|
|
4245
4331
|
invariant4(level > 0, void 0, {
|
|
4246
4332
|
F: __dxlog_file10,
|
|
4247
|
-
L:
|
|
4333
|
+
L: 157,
|
|
4248
4334
|
S: void 0,
|
|
4249
4335
|
A: [
|
|
4250
4336
|
"level > 0",
|
|
@@ -4280,10 +4366,10 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4280
4366
|
const leaveList = () => {
|
|
4281
4367
|
listLevels.pop();
|
|
4282
4368
|
};
|
|
4283
|
-
const
|
|
4369
|
+
const getCurrentListLevel = () => {
|
|
4284
4370
|
invariant4(listLevels.length, void 0, {
|
|
4285
4371
|
F: __dxlog_file10,
|
|
4286
|
-
L:
|
|
4372
|
+
L: 179,
|
|
4287
4373
|
S: void 0,
|
|
4288
4374
|
A: [
|
|
4289
4375
|
"listLevels.length",
|
|
@@ -4333,34 +4419,35 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4333
4419
|
break;
|
|
4334
4420
|
}
|
|
4335
4421
|
case "ListItem": {
|
|
4336
|
-
const list =
|
|
4422
|
+
const list = getCurrentListLevel();
|
|
4337
4423
|
const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
|
|
4338
4424
|
const offset = ((list.level ?? 0) + 1) * width;
|
|
4339
|
-
const
|
|
4340
|
-
|
|
4425
|
+
const line = state2.doc.lineAt(node.from);
|
|
4426
|
+
if (node.from === line.to - 1) {
|
|
4427
|
+
return false;
|
|
4428
|
+
}
|
|
4429
|
+
deco.add(line.from, line.from, Decoration7.line({
|
|
4341
4430
|
class: "cm-list-item",
|
|
4342
4431
|
attributes: {
|
|
4343
|
-
|
|
4344
|
-
// Note: This makes the cursor appear to be left of the margin.
|
|
4345
|
-
style: `padding-left: ${offset}px; text-indent: calc(-${width}px - 0.25em);`
|
|
4432
|
+
style: `padding-left: ${offset}px; text-indent: -${width}px;`
|
|
4346
4433
|
}
|
|
4347
4434
|
}));
|
|
4348
|
-
const
|
|
4349
|
-
const whitespace =
|
|
4435
|
+
const text = state2.doc.sliceString(line.from, node.to);
|
|
4436
|
+
const whitespace = text.match(/^ */)?.[0].length ?? 0;
|
|
4350
4437
|
if (whitespace) {
|
|
4351
|
-
atomicDeco.add(
|
|
4438
|
+
atomicDeco.add(line.from, line.from + whitespace, hide);
|
|
4352
4439
|
}
|
|
4353
4440
|
break;
|
|
4354
4441
|
}
|
|
4355
4442
|
case "ListMark": {
|
|
4356
|
-
const
|
|
4357
|
-
if (
|
|
4358
|
-
atomicDeco.add(node.from, node.to, hide);
|
|
4443
|
+
const next = tree.resolve(node.to + 1, 1);
|
|
4444
|
+
if (next?.name === "TaskMarker") {
|
|
4445
|
+
atomicDeco.add(node.from, node.to + 1, hide);
|
|
4359
4446
|
break;
|
|
4360
4447
|
}
|
|
4361
|
-
const list =
|
|
4362
|
-
const label = list.type === "OrderedList" ? `${++list.number}.` : "
|
|
4363
|
-
atomicDeco.add(node.from, node.to, Decoration7.replace({
|
|
4448
|
+
const list = getCurrentListLevel();
|
|
4449
|
+
const label = list.type === "OrderedList" ? `${++list.number}.` : "\u2022";
|
|
4450
|
+
atomicDeco.add(node.from, node.to + 1, Decoration7.replace({
|
|
4364
4451
|
widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
|
|
4365
4452
|
}));
|
|
4366
4453
|
break;
|
|
@@ -4368,10 +4455,7 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4368
4455
|
case "TaskMarker": {
|
|
4369
4456
|
if (!editingRange(state2, node, focus)) {
|
|
4370
4457
|
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
4371
|
-
atomicDeco.add(node.from
|
|
4372
|
-
class: "cm-task-checkbox"
|
|
4373
|
-
}));
|
|
4374
|
-
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
4458
|
+
atomicDeco.add(node.from, node.to + 1, checked ? checkedTask : uncheckedTask);
|
|
4375
4459
|
}
|
|
4376
4460
|
break;
|
|
4377
4461
|
}
|
|
@@ -4461,7 +4545,7 @@ var buildDecorations2 = (view, options, focus) => {
|
|
|
4461
4545
|
}
|
|
4462
4546
|
}
|
|
4463
4547
|
};
|
|
4464
|
-
const tree =
|
|
4548
|
+
const tree = syntaxTree7(state2);
|
|
4465
4549
|
if (options.numberedHeadings?.from === void 0) {
|
|
4466
4550
|
for (const { from, to } of view.visibleRanges) {
|
|
4467
4551
|
tree.iterate({
|
|
@@ -4490,13 +4574,14 @@ var decorateMarkdown = (options = {}) => {
|
|
|
4490
4574
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
|
|
4491
4575
|
}
|
|
4492
4576
|
update(update2) {
|
|
4493
|
-
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((
|
|
4577
|
+
if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
|
|
4494
4578
|
({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
|
|
4495
4579
|
this.clearUpdate();
|
|
4496
4580
|
} else if (update2.selectionSet) {
|
|
4497
4581
|
this.scheduleUpdate(update2.view);
|
|
4498
4582
|
}
|
|
4499
4583
|
}
|
|
4584
|
+
// Defer update in case moving through the document.
|
|
4500
4585
|
scheduleUpdate(view) {
|
|
4501
4586
|
this.clearUpdate();
|
|
4502
4587
|
this.pendingUpdate = setTimeout(() => {
|
|
@@ -4516,88 +4601,24 @@ var decorateMarkdown = (options = {}) => {
|
|
|
4516
4601
|
}
|
|
4517
4602
|
}, {
|
|
4518
4603
|
provide: (plugin) => [
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4604
|
+
EditorView15.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
|
4605
|
+
EditorView15.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
|
|
4606
|
+
EditorView15.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
|
|
4522
4607
|
]
|
|
4523
4608
|
}),
|
|
4524
|
-
formattingStyles,
|
|
4525
|
-
linkPastePlugin,
|
|
4526
4609
|
image(),
|
|
4527
|
-
table()
|
|
4610
|
+
table(),
|
|
4611
|
+
adjustChanges(),
|
|
4612
|
+
formattingStyles
|
|
4528
4613
|
];
|
|
4529
4614
|
};
|
|
4530
|
-
var formattingStyles = EditorView14.baseTheme({
|
|
4531
|
-
"& .cm-code": {
|
|
4532
|
-
fontFamily: getToken("fontFamily.mono")
|
|
4533
|
-
},
|
|
4534
|
-
"& .cm-codeblock-line": {
|
|
4535
|
-
paddingInline: "1rem !important"
|
|
4536
|
-
},
|
|
4537
|
-
"& .cm-codeblock-end": {
|
|
4538
|
-
display: "inline-block",
|
|
4539
|
-
width: "100%",
|
|
4540
|
-
position: "relative",
|
|
4541
|
-
"&::after": {
|
|
4542
|
-
position: "absolute",
|
|
4543
|
-
inset: 0,
|
|
4544
|
-
content: '""'
|
|
4545
|
-
}
|
|
4546
|
-
},
|
|
4547
|
-
"& .cm-codeblock-first": {
|
|
4548
|
-
borderTopLeftRadius: ".25rem",
|
|
4549
|
-
borderTopRightRadius: ".25rem"
|
|
4550
|
-
},
|
|
4551
|
-
"& .cm-codeblock-last": {
|
|
4552
|
-
borderBottomLeftRadius: ".25rem",
|
|
4553
|
-
borderBottomRightRadius: ".25rem"
|
|
4554
|
-
},
|
|
4555
|
-
"&light .cm-codeblock-line, &light .cm-activeLine.cm-codeblock-line": {
|
|
4556
|
-
background: getToken("extend.semanticColors.input.light"),
|
|
4557
|
-
mixBlendMode: "darken"
|
|
4558
|
-
},
|
|
4559
|
-
"&dark .cm-codeblock-line, &dark .cm-activeLine.cm-codeblock-line": {
|
|
4560
|
-
background: getToken("extend.semanticColors.input.dark"),
|
|
4561
|
-
mixBlendMode: "lighten"
|
|
4562
|
-
},
|
|
4563
|
-
"& .cm-hr": {
|
|
4564
|
-
display: "inline-block",
|
|
4565
|
-
width: "100%",
|
|
4566
|
-
height: "0",
|
|
4567
|
-
verticalAlign: "middle",
|
|
4568
|
-
borderTop: `1px solid ${getToken("extend.colors.primary.500")}`,
|
|
4569
|
-
opacity: 0.5
|
|
4570
|
-
},
|
|
4571
|
-
"& .cm-task": {
|
|
4572
|
-
display: "inline-block",
|
|
4573
|
-
width: `calc(${bulletListIndentationWidth}px - 0.25em)`,
|
|
4574
|
-
color: getToken("extend.colors.blue.500")
|
|
4575
|
-
},
|
|
4576
|
-
"& .cm-task-checkbox": {
|
|
4577
|
-
display: "grid",
|
|
4578
|
-
margin: "0",
|
|
4579
|
-
transform: "translateY(2px)"
|
|
4580
|
-
},
|
|
4581
|
-
"& .cm-list-item": {},
|
|
4582
|
-
"& .cm-list-mark": {
|
|
4583
|
-
display: "inline-block",
|
|
4584
|
-
textAlign: "right",
|
|
4585
|
-
fontVariant: "tabular-nums"
|
|
4586
|
-
},
|
|
4587
|
-
"& .cm-list-mark-bullet": {
|
|
4588
|
-
width: `${bulletListIndentationWidth}px`
|
|
4589
|
-
},
|
|
4590
|
-
"& .cm-list-mark-ordered": {
|
|
4591
|
-
width: `${orderedListIndentationWidth}px`
|
|
4592
|
-
}
|
|
4593
|
-
});
|
|
4594
4615
|
|
|
4595
4616
|
// packages/ui/react-ui-editor/src/extensions/markdown/link.ts
|
|
4596
|
-
import { syntaxTree as
|
|
4617
|
+
import { syntaxTree as syntaxTree8 } from "@codemirror/language";
|
|
4597
4618
|
import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
|
|
4598
4619
|
import { tooltipContent } from "@dxos/react-ui-theme";
|
|
4599
4620
|
var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
|
|
4600
|
-
const syntax =
|
|
4621
|
+
const syntax = syntaxTree8(view.state).resolveInner(pos, side);
|
|
4601
4622
|
let link = null;
|
|
4602
4623
|
for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
|
|
4603
4624
|
link = node.name === "Link" ? node : null;
|
|
@@ -4715,7 +4736,7 @@ var InputModeExtensions = {
|
|
|
4715
4736
|
|
|
4716
4737
|
// packages/ui/react-ui-editor/src/extensions/state.ts
|
|
4717
4738
|
import { Transaction as Transaction2 } from "@codemirror/state";
|
|
4718
|
-
import { EditorView as
|
|
4739
|
+
import { EditorView as EditorView16, keymap as keymap9 } from "@codemirror/view";
|
|
4719
4740
|
import { debounce as debounce2 } from "@dxos/async";
|
|
4720
4741
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
4721
4742
|
import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
|
|
@@ -4753,7 +4774,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
|
|
|
4753
4774
|
return {
|
|
4754
4775
|
selection,
|
|
4755
4776
|
scrollIntoView: !scrollTo,
|
|
4756
|
-
effects: scrollTo ?
|
|
4777
|
+
effects: scrollTo ? EditorView16.scrollIntoView(scrollTo, {
|
|
4757
4778
|
yMargin: 96
|
|
4758
4779
|
}) : void 0,
|
|
4759
4780
|
annotations: Transaction2.userEvent.of(stateRestoreAnnotation)
|
|
@@ -4768,7 +4789,7 @@ var state = ({ getState, setState } = {}) => {
|
|
|
4768
4789
|
// setStateDebounced(id, {});
|
|
4769
4790
|
// },
|
|
4770
4791
|
// }),
|
|
4771
|
-
|
|
4792
|
+
EditorView16.updateListener.of(({ view, transactions }) => {
|
|
4772
4793
|
const id = view.state.facet(documentId2);
|
|
4773
4794
|
if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
|
|
4774
4795
|
return;
|
|
@@ -4893,96 +4914,32 @@ var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
|
4893
4914
|
}
|
|
4894
4915
|
}, children))));
|
|
4895
4916
|
};
|
|
4896
|
-
var ToolbarToggleButton = ({ Icon, children, ...props }) => {
|
|
4917
|
+
var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
|
|
4897
4918
|
return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
4898
4919
|
asChild: true
|
|
4899
4920
|
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
4900
4921
|
variant: "ghost",
|
|
4901
4922
|
...props,
|
|
4902
4923
|
classNames: buttonStyles
|
|
4903
|
-
}, /* @__PURE__ */ React3.createElement(
|
|
4924
|
+
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
|
4904
4925
|
className: iconStyles
|
|
4905
4926
|
}), /* @__PURE__ */ React3.createElement("span", {
|
|
4906
4927
|
className: "sr-only"
|
|
4907
4928
|
}, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
|
4908
4929
|
};
|
|
4909
|
-
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4930
|
+
var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
|
|
4910
4931
|
return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
4911
4932
|
asChild: true
|
|
4912
4933
|
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
4913
4934
|
variant: "ghost",
|
|
4914
4935
|
...props,
|
|
4915
4936
|
classNames: buttonStyles
|
|
4916
|
-
}, /* @__PURE__ */ React3.createElement(
|
|
4937
|
+
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
|
4917
4938
|
className: iconStyles
|
|
4918
4939
|
}), /* @__PURE__ */ React3.createElement("span", {
|
|
4919
4940
|
className: "sr-only"
|
|
4920
4941
|
}, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
|
|
4921
4942
|
};
|
|
4922
|
-
var ViewModeIcons = {
|
|
4923
|
-
preview: PencilSimple,
|
|
4924
|
-
readonly: PencilSimpleSlash,
|
|
4925
|
-
source: MarkdownLogo
|
|
4926
|
-
};
|
|
4927
|
-
var MarkdownView = ({ mode }) => {
|
|
4928
|
-
const { t } = useTranslation(translationKey);
|
|
4929
|
-
const { onAction } = useToolbarContext("ViewMode");
|
|
4930
|
-
const ModeIcon = ViewModeIcons[mode ?? "preview"];
|
|
4931
|
-
const suppressNextTooltip = useRef(false);
|
|
4932
|
-
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
|
4933
|
-
const [selectOpen, setSelectOpen] = useState3(false);
|
|
4934
|
-
return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
|
|
4935
|
-
open: tooltipOpen,
|
|
4936
|
-
onOpenChange: (nextOpen) => {
|
|
4937
|
-
if (nextOpen && suppressNextTooltip.current) {
|
|
4938
|
-
suppressNextTooltip.current = false;
|
|
4939
|
-
return setTooltipOpen(false);
|
|
4940
|
-
} else {
|
|
4941
|
-
return setTooltipOpen(nextOpen);
|
|
4942
|
-
}
|
|
4943
|
-
}
|
|
4944
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
|
4945
|
-
open: selectOpen,
|
|
4946
|
-
onOpenChange: (nextOpen) => {
|
|
4947
|
-
if (!nextOpen) {
|
|
4948
|
-
suppressNextTooltip.current = true;
|
|
4949
|
-
}
|
|
4950
|
-
return setSelectOpen(nextOpen);
|
|
4951
|
-
}
|
|
4952
|
-
}, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
4953
|
-
asChild: true
|
|
4954
|
-
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
4955
|
-
asChild: true
|
|
4956
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
|
4957
|
-
asChild: true
|
|
4958
|
-
}, /* @__PURE__ */ React3.createElement(Button, {
|
|
4959
|
-
variant: "ghost",
|
|
4960
|
-
classNames: buttonStyles
|
|
4961
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
|
4962
|
-
className: "sr-only"
|
|
4963
|
-
}, t("mode label")), /* @__PURE__ */ React3.createElement(ModeIcon, {
|
|
4964
|
-
className: iconStyles
|
|
4965
|
-
}), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
|
|
4966
|
-
classNames: "is-min md:is-min",
|
|
4967
|
-
onCloseAutoFocus: (e) => e.preventDefault()
|
|
4968
|
-
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
|
|
4969
|
-
const Icon = ViewModeIcons[value];
|
|
4970
|
-
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
|
4971
|
-
key: value,
|
|
4972
|
-
checked: value === mode,
|
|
4973
|
-
onClick: () => onAction?.({
|
|
4974
|
-
type: "view-mode",
|
|
4975
|
-
data: value
|
|
4976
|
-
})
|
|
4977
|
-
}, /* @__PURE__ */ React3.createElement(Icon, {
|
|
4978
|
-
className: iconStyles
|
|
4979
|
-
}), /* @__PURE__ */ React3.createElement("span", {
|
|
4980
|
-
className: "whitespace-nowrap grow"
|
|
4981
|
-
}, t(`${value} mode label`)), /* @__PURE__ */ React3.createElement(Check, {
|
|
4982
|
-
className: value === mode ? "visible" : "invisible"
|
|
4983
|
-
}));
|
|
4984
|
-
})), /* @__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))));
|
|
4985
|
-
};
|
|
4986
4943
|
var HeadingIcons = {
|
|
4987
4944
|
"0": Paragraph,
|
|
4988
4945
|
"1": TextHOne,
|
|
@@ -5038,7 +4995,7 @@ var MarkdownHeading = () => {
|
|
|
5038
4995
|
classNames: "is-min md:is-min",
|
|
5039
4996
|
onCloseAutoFocus: (e) => e.preventDefault()
|
|
5040
4997
|
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
|
|
5041
|
-
const
|
|
4998
|
+
const Icon2 = HeadingIcons[level];
|
|
5042
4999
|
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
|
5043
5000
|
key: level,
|
|
5044
5001
|
checked: value === level,
|
|
@@ -5050,7 +5007,7 @@ var MarkdownHeading = () => {
|
|
|
5050
5007
|
className: "sr-only"
|
|
5051
5008
|
}, t("heading level label", {
|
|
5052
5009
|
count: parseInt(level)
|
|
5053
|
-
})), /* @__PURE__ */ React3.createElement(
|
|
5010
|
+
})), /* @__PURE__ */ React3.createElement(Icon2, {
|
|
5054
5011
|
className: iconStyles
|
|
5055
5012
|
}), /* @__PURE__ */ React3.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React3.createElement(Check, null)));
|
|
5056
5013
|
})), /* @__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))));
|
|
@@ -5088,10 +5045,10 @@ var MarkdownStyles = () => {
|
|
|
5088
5045
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
5089
5046
|
type: "multiple",
|
|
5090
5047
|
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
5091
|
-
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
|
5048
|
+
}, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
|
5092
5049
|
key: type,
|
|
5093
5050
|
value: type,
|
|
5094
|
-
Icon,
|
|
5051
|
+
Icon: Icon2,
|
|
5095
5052
|
disabled: state2?.blockType === "codeblock",
|
|
5096
5053
|
onClick: state2 ? () => onAction?.({
|
|
5097
5054
|
type,
|
|
@@ -5122,10 +5079,10 @@ var MarkdownLists = () => {
|
|
|
5122
5079
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
5123
5080
|
type: "single",
|
|
5124
5081
|
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
5125
|
-
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
|
5082
|
+
}, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
|
5126
5083
|
key: type,
|
|
5127
5084
|
value: type,
|
|
5128
|
-
Icon,
|
|
5085
|
+
Icon: Icon2,
|
|
5129
5086
|
onClick: state2 ? () => onAction?.({
|
|
5130
5087
|
type,
|
|
5131
5088
|
data: !getState(state2)
|
|
@@ -5157,10 +5114,10 @@ var MarkdownBlocks = () => {
|
|
|
5157
5114
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
5158
5115
|
type: "single",
|
|
5159
5116
|
value: value?.type ?? ""
|
|
5160
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
|
5117
|
+
}, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
|
|
5161
5118
|
key: type,
|
|
5162
5119
|
value: type,
|
|
5163
|
-
Icon,
|
|
5120
|
+
Icon: Icon2,
|
|
5164
5121
|
disabled: !state2 || disabled?.(state2),
|
|
5165
5122
|
onClick: state2 ? () => onAction?.({
|
|
5166
5123
|
type,
|
|
@@ -5212,16 +5169,86 @@ var MarkdownCustom = ({ onUpload } = {}) => {
|
|
|
5212
5169
|
onClick: () => open()
|
|
5213
5170
|
}, t("image label")));
|
|
5214
5171
|
};
|
|
5172
|
+
var ViewModeIcons = {
|
|
5173
|
+
preview: PencilSimple,
|
|
5174
|
+
readonly: PencilSimpleSlash,
|
|
5175
|
+
source: MarkdownLogo
|
|
5176
|
+
};
|
|
5177
|
+
var MarkdownView = ({ mode }) => {
|
|
5178
|
+
const { t } = useTranslation(translationKey);
|
|
5179
|
+
const { onAction } = useToolbarContext("ViewMode");
|
|
5180
|
+
const ModeIcon = ViewModeIcons[mode ?? "preview"];
|
|
5181
|
+
const suppressNextTooltip = useRef(false);
|
|
5182
|
+
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
|
5183
|
+
const [selectOpen, setSelectOpen] = useState3(false);
|
|
5184
|
+
return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
|
|
5185
|
+
open: tooltipOpen,
|
|
5186
|
+
onOpenChange: (nextOpen) => {
|
|
5187
|
+
if (nextOpen && suppressNextTooltip.current) {
|
|
5188
|
+
suppressNextTooltip.current = false;
|
|
5189
|
+
return setTooltipOpen(false);
|
|
5190
|
+
} else {
|
|
5191
|
+
return setTooltipOpen(nextOpen);
|
|
5192
|
+
}
|
|
5193
|
+
}
|
|
5194
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
|
5195
|
+
open: selectOpen,
|
|
5196
|
+
onOpenChange: (nextOpen) => {
|
|
5197
|
+
if (!nextOpen) {
|
|
5198
|
+
suppressNextTooltip.current = true;
|
|
5199
|
+
}
|
|
5200
|
+
return setSelectOpen(nextOpen);
|
|
5201
|
+
}
|
|
5202
|
+
}, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
5203
|
+
asChild: true
|
|
5204
|
+
}, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
5205
|
+
asChild: true
|
|
5206
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
|
5207
|
+
asChild: true
|
|
5208
|
+
}, /* @__PURE__ */ React3.createElement(Button, {
|
|
5209
|
+
variant: "ghost",
|
|
5210
|
+
classNames: buttonStyles
|
|
5211
|
+
}, /* @__PURE__ */ React3.createElement("span", {
|
|
5212
|
+
className: "sr-only"
|
|
5213
|
+
}, t("mode label")), /* @__PURE__ */ React3.createElement(ModeIcon, {
|
|
5214
|
+
className: iconStyles
|
|
5215
|
+
}), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
|
|
5216
|
+
classNames: "is-min md:is-min",
|
|
5217
|
+
onCloseAutoFocus: (e) => e.preventDefault()
|
|
5218
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
|
|
5219
|
+
const Icon2 = ViewModeIcons[value];
|
|
5220
|
+
return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
|
|
5221
|
+
key: value,
|
|
5222
|
+
checked: value === mode,
|
|
5223
|
+
onClick: () => onAction?.({
|
|
5224
|
+
type: "view-mode",
|
|
5225
|
+
data: value
|
|
5226
|
+
})
|
|
5227
|
+
}, /* @__PURE__ */ React3.createElement(Icon2, {
|
|
5228
|
+
className: iconStyles
|
|
5229
|
+
}), /* @__PURE__ */ React3.createElement("span", {
|
|
5230
|
+
className: "whitespace-nowrap grow"
|
|
5231
|
+
}, t(`${value} mode label`)), /* @__PURE__ */ React3.createElement(Check, {
|
|
5232
|
+
className: value === mode ? "visible" : "invisible"
|
|
5233
|
+
}));
|
|
5234
|
+
})), /* @__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))));
|
|
5235
|
+
};
|
|
5215
5236
|
var MarkdownActions = () => {
|
|
5216
5237
|
const { onAction, state: state2 } = useToolbarContext("MarkdownActions");
|
|
5217
5238
|
const { t } = useTranslation(translationKey);
|
|
5218
|
-
let
|
|
5239
|
+
let commentToolTipKey = "comment label";
|
|
5219
5240
|
if (state2?.comment) {
|
|
5220
|
-
|
|
5241
|
+
commentToolTipKey = "selection overlaps existing comment label";
|
|
5221
5242
|
} else if (state2?.selection === false) {
|
|
5222
|
-
|
|
5243
|
+
commentToolTipKey = "select text to comment label";
|
|
5223
5244
|
}
|
|
5224
5245
|
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
|
5246
|
+
value: "search",
|
|
5247
|
+
Icon: MagnifyingGlass,
|
|
5248
|
+
onClick: () => onAction?.({
|
|
5249
|
+
type: "search"
|
|
5250
|
+
})
|
|
5251
|
+
}, t("search label")), /* @__PURE__ */ React3.createElement(ToolbarButton, {
|
|
5225
5252
|
value: "comment",
|
|
5226
5253
|
Icon: ChatText,
|
|
5227
5254
|
"data-testid": "editor.toolbar.comment",
|
|
@@ -5229,7 +5256,7 @@ var MarkdownActions = () => {
|
|
|
5229
5256
|
type: "comment"
|
|
5230
5257
|
}),
|
|
5231
5258
|
disabled: !state2 || state2.comment || !state2.selection
|
|
5232
|
-
}, t(
|
|
5259
|
+
}, t(commentToolTipKey)));
|
|
5233
5260
|
};
|
|
5234
5261
|
var Toolbar = {
|
|
5235
5262
|
Root: ToolbarRoot,
|
|
@@ -5242,23 +5269,21 @@ var Toolbar = {
|
|
|
5242
5269
|
};
|
|
5243
5270
|
|
|
5244
5271
|
// packages/ui/react-ui-editor/src/defaults.ts
|
|
5245
|
-
import { EditorView as
|
|
5246
|
-
|
|
5272
|
+
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
5273
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
5274
|
+
var margin = "!mt-[16px]";
|
|
5275
|
+
var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
|
|
5276
|
+
var editorFullWidth = mx3(margin, "!ml-[3rem]");
|
|
5247
5277
|
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
5248
|
-
var editorGutter =
|
|
5278
|
+
var editorGutter = EditorView17.theme({
|
|
5279
|
+
// Match margin from content.
|
|
5249
5280
|
".cm-gutters": {
|
|
5250
|
-
|
|
5251
|
-
marginTop: "16px",
|
|
5252
|
-
marginBottom: "16px",
|
|
5253
|
-
// Inside within content margin.
|
|
5254
|
-
marginRight: "-32px",
|
|
5255
|
-
width: "32px",
|
|
5256
|
-
backgroundColor: "transparent !important"
|
|
5281
|
+
marginTop: "16px"
|
|
5257
5282
|
}
|
|
5258
5283
|
});
|
|
5259
|
-
var editorMonospace =
|
|
5284
|
+
var editorMonospace = EditorView17.theme({
|
|
5260
5285
|
".cm-content": {
|
|
5261
|
-
fontFamily:
|
|
5286
|
+
fontFamily: fontMono
|
|
5262
5287
|
}
|
|
5263
5288
|
});
|
|
5264
5289
|
|
|
@@ -5269,7 +5294,7 @@ var useActionHandler = (view) => {
|
|
|
5269
5294
|
|
|
5270
5295
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
5271
5296
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
5272
|
-
import { EditorView as
|
|
5297
|
+
import { EditorView as EditorView18 } from "@codemirror/view";
|
|
5273
5298
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
5274
5299
|
import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
|
|
5275
5300
|
import { log as log8 } from "@dxos/log";
|
|
@@ -5315,7 +5340,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
5315
5340
|
extensions: [
|
|
5316
5341
|
id && documentId2.of(id),
|
|
5317
5342
|
// NOTE: Doesn't catch errors in keymap functions.
|
|
5318
|
-
|
|
5343
|
+
EditorView18.exceptionSink.of((err) => {
|
|
5319
5344
|
log8.catch(err, void 0, {
|
|
5320
5345
|
F: __dxlog_file13,
|
|
5321
5346
|
L: 100,
|
|
@@ -5324,14 +5349,14 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
5324
5349
|
});
|
|
5325
5350
|
}),
|
|
5326
5351
|
extensions,
|
|
5327
|
-
|
|
5352
|
+
EditorView18.updateListener.of(() => {
|
|
5328
5353
|
setTimeout(() => {
|
|
5329
5354
|
onUpdate.current?.();
|
|
5330
5355
|
});
|
|
5331
5356
|
})
|
|
5332
5357
|
].filter(isNotFalsy4)
|
|
5333
5358
|
});
|
|
5334
|
-
view2 = new
|
|
5359
|
+
view2 = new EditorView18({
|
|
5335
5360
|
parent: parentRef.current,
|
|
5336
5361
|
selection: initialSelection,
|
|
5337
5362
|
state: state2,
|
|
@@ -5445,6 +5470,7 @@ export {
|
|
|
5445
5470
|
command,
|
|
5446
5471
|
comments,
|
|
5447
5472
|
commentsState,
|
|
5473
|
+
convertTreeToJson,
|
|
5448
5474
|
createBasicExtensions,
|
|
5449
5475
|
createComment,
|
|
5450
5476
|
createDataExtensions,
|
|
@@ -5453,11 +5479,13 @@ export {
|
|
|
5453
5479
|
createMarkdownExtensions,
|
|
5454
5480
|
createThemeExtensions,
|
|
5455
5481
|
debugNodeLogger,
|
|
5482
|
+
debugTree,
|
|
5456
5483
|
decorateMarkdown,
|
|
5457
5484
|
defaultOptions,
|
|
5458
5485
|
documentId2 as documentId,
|
|
5459
5486
|
dropFile,
|
|
5460
5487
|
editorContent,
|
|
5488
|
+
editorFullWidth,
|
|
5461
5489
|
editorGutter,
|
|
5462
5490
|
editorInputMode,
|
|
5463
5491
|
editorMonospace,
|
|
@@ -5467,7 +5495,6 @@ export {
|
|
|
5467
5495
|
formattingEquals,
|
|
5468
5496
|
formattingKeymap,
|
|
5469
5497
|
getFormatting,
|
|
5470
|
-
getToken,
|
|
5471
5498
|
image,
|
|
5472
5499
|
imageUpload,
|
|
5473
5500
|
insertTable,
|