@dxos/react-ui-editor 0.3.10-main.cbe7692 → 0.3.10-main.e948ee0
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 +654 -413
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +6 -3
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +3 -0
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts +1 -1
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/code.d.ts +2 -0
- package/dist/types/src/components/TextEditor/extensions/code.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +2 -2
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +1 -1
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +24 -0
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +2 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +8 -0
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts +3 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextModel.d.ts +6 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/hooks/yjs/yjs.stories.d.ts +1 -1
- package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +1 -1
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/testing/replicator.d.ts.map +1 -1
- package/package.json +22 -20
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +51 -32
- package/src/components/TextEditor/TextEditor.stories.tsx +12 -1
- package/src/components/TextEditor/TextEditor.tsx +21 -23
- package/src/components/TextEditor/extensions/basic.ts +4 -3
- package/src/components/TextEditor/extensions/blast.ts +27 -29
- package/src/components/TextEditor/extensions/code.ts +99 -0
- package/src/components/TextEditor/extensions/comments.ts +29 -46
- package/src/components/TextEditor/extensions/experimental.tsx +15 -36
- package/src/components/TextEditor/extensions/highlight.ts +128 -0
- package/src/components/TextEditor/extensions/image.ts +4 -5
- package/src/components/TextEditor/extensions/index.ts +2 -0
- package/src/components/TextEditor/extensions/link.ts +2 -2
- package/src/components/TextEditor/extensions/markdown/bundle.ts +36 -42
- package/src/components/TextEditor/extensions/markdown/highlight.ts +37 -11
- package/src/components/TextEditor/extensions/table.ts +44 -48
- package/src/components/TextEditor/extensions/tasklist.ts +9 -9
- package/src/components/TextEditor/themes/default.ts +43 -2
- package/src/hooks/automerge/automerge.stories.tsx +1 -0
- package/src/hooks/useTextModel.ts +9 -0
- package/src/hooks/yjs/yjs.stories.tsx +1 -1
- package/src/styles/markdown.ts +5 -4
- package/src/testing/replicator.ts +1 -0
|
@@ -42,25 +42,26 @@ var autocomplete = ({ onSearch }) => {
|
|
|
42
42
|
import { closeBrackets } from "@codemirror/autocomplete";
|
|
43
43
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
44
44
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
45
|
-
import { EditorView, placeholder } from "@codemirror/view";
|
|
45
|
+
import { drawSelection, EditorView, placeholder } from "@codemirror/view";
|
|
46
46
|
var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
|
|
47
|
+
EditorView.lineWrapping,
|
|
47
48
|
// TODO(burdon): Compare with minimalSetup.
|
|
48
49
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
49
50
|
bracketMatching(),
|
|
50
51
|
closeBrackets(),
|
|
51
|
-
|
|
52
|
+
drawSelection(),
|
|
52
53
|
_placeholder && placeholder(_placeholder),
|
|
53
54
|
// TODO(burdon): Is this required?
|
|
54
55
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
55
56
|
].filter(Boolean);
|
|
56
57
|
|
|
57
58
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts
|
|
58
|
-
import { StateField } from "@codemirror/state";
|
|
59
59
|
import { EditorView as EditorView2, keymap as keymap2 } from "@codemirror/view";
|
|
60
60
|
import defaultsDeep from "lodash.defaultsdeep";
|
|
61
61
|
import { invariant } from "@dxos/invariant";
|
|
62
62
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts";
|
|
63
63
|
var defaultOptions = {
|
|
64
|
+
effect: 2,
|
|
64
65
|
maxParticles: 200,
|
|
65
66
|
particleGravity: 0.08,
|
|
66
67
|
particleAlphaFadeout: 0.996,
|
|
@@ -85,7 +86,7 @@ var defaultOptions = {
|
|
|
85
86
|
particleShrinkRate: 0.95,
|
|
86
87
|
shakeIntensity: 5
|
|
87
88
|
};
|
|
88
|
-
var blast = (options) => {
|
|
89
|
+
var blast = (options = defaultOptions) => {
|
|
89
90
|
let blaster;
|
|
90
91
|
let last = 0;
|
|
91
92
|
const getPoint = (view, pos) => {
|
|
@@ -108,16 +109,24 @@ var blast = (options) => {
|
|
|
108
109
|
if (blaster) {
|
|
109
110
|
blaster.destroy();
|
|
110
111
|
}
|
|
111
|
-
blaster = new Blaster(update4.view.scrollDOM, defaultsDeep({
|
|
112
|
+
blaster = new Blaster(update4.view.scrollDOM, defaultsDeep({
|
|
113
|
+
particleGravity: 0.2,
|
|
114
|
+
particleShrinkRate: 0.995,
|
|
115
|
+
color: () => [
|
|
116
|
+
100 + Math.random() * 100,
|
|
117
|
+
0,
|
|
118
|
+
0
|
|
119
|
+
]
|
|
120
|
+
}, options, defaultOptions));
|
|
112
121
|
blaster.initialize();
|
|
113
122
|
blaster.start();
|
|
114
123
|
} else {
|
|
115
124
|
blaster.resize();
|
|
116
125
|
}
|
|
117
|
-
const current = update4.
|
|
126
|
+
const current = update4.state.selection.main.head;
|
|
118
127
|
if (current !== last) {
|
|
119
128
|
last = current;
|
|
120
|
-
const { element, point } = getPoint(update4.view, current);
|
|
129
|
+
const { element, point } = getPoint(update4.view, current - 1);
|
|
121
130
|
if (element && point) {
|
|
122
131
|
blaster.spawn({
|
|
123
132
|
element,
|
|
@@ -126,30 +135,16 @@ var blast = (options) => {
|
|
|
126
135
|
}
|
|
127
136
|
}
|
|
128
137
|
}),
|
|
129
|
-
// Document changed.
|
|
130
|
-
StateField.define({
|
|
131
|
-
create: () => null,
|
|
132
|
-
update: (_value, transaction) => {
|
|
133
|
-
if (blaster && transaction.docChanged) {
|
|
134
|
-
const view = EditorView2.findFromDOM(blaster.node);
|
|
135
|
-
const { element, point } = getPoint(view, transaction.selection.main.head);
|
|
136
|
-
if (element && point) {
|
|
137
|
-
blaster.spawn({
|
|
138
|
-
element,
|
|
139
|
-
point
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}),
|
|
146
138
|
keymap2.of([
|
|
147
139
|
{
|
|
148
|
-
any: (
|
|
149
|
-
if (blaster
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
140
|
+
any: (_, event) => {
|
|
141
|
+
if (blaster) {
|
|
142
|
+
if (event.key === "Enter" && event.shiftKey) {
|
|
143
|
+
blaster.shake({
|
|
144
|
+
time: 0.8
|
|
145
|
+
});
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
153
148
|
}
|
|
154
149
|
return false;
|
|
155
150
|
}
|
|
@@ -171,7 +166,7 @@ var Blaster = class {
|
|
|
171
166
|
y: 0
|
|
172
167
|
};
|
|
173
168
|
this.shake = throttle(({ time }) => {
|
|
174
|
-
this._shakeTime = this._shakeTimeMax;
|
|
169
|
+
this._shakeTime = this._shakeTimeMax || time;
|
|
175
170
|
this._shakeTimeMax = time;
|
|
176
171
|
}, 100);
|
|
177
172
|
this.spawn = throttle(({ element, point }) => {
|
|
@@ -192,7 +187,7 @@ var Blaster = class {
|
|
|
192
187
|
initialize() {
|
|
193
188
|
invariant(!this._canvas && !this._ctx, void 0, {
|
|
194
189
|
F: __dxlog_file,
|
|
195
|
-
L:
|
|
190
|
+
L: 138,
|
|
196
191
|
S: this,
|
|
197
192
|
A: [
|
|
198
193
|
"!this._canvas && !this._ctx",
|
|
@@ -229,7 +224,7 @@ var Blaster = class {
|
|
|
229
224
|
start() {
|
|
230
225
|
invariant(this._canvas && this._ctx, void 0, {
|
|
231
226
|
F: __dxlog_file,
|
|
232
|
-
L:
|
|
227
|
+
L: 177,
|
|
233
228
|
S: this,
|
|
234
229
|
A: [
|
|
235
230
|
"this._canvas && this._ctx",
|
|
@@ -370,6 +365,126 @@ var random = (min, max) => {
|
|
|
370
365
|
return min + ~~(Math.random() * (max - min + 1));
|
|
371
366
|
};
|
|
372
367
|
|
|
368
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/code.ts
|
|
369
|
+
import { ViewPlugin, EditorView as EditorView3, Decoration } from "@codemirror/view";
|
|
370
|
+
import get from "lodash.get";
|
|
371
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
372
|
+
|
|
373
|
+
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
374
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
375
|
+
var headings = {
|
|
376
|
+
1: [
|
|
377
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
378
|
+
"-ml-[10px]"
|
|
379
|
+
],
|
|
380
|
+
2: [
|
|
381
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
382
|
+
"-ml-[8px]"
|
|
383
|
+
],
|
|
384
|
+
3: [
|
|
385
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
386
|
+
"-ml-[7px]"
|
|
387
|
+
],
|
|
388
|
+
4: [
|
|
389
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
390
|
+
"-ml-[6px]"
|
|
391
|
+
],
|
|
392
|
+
5: [
|
|
393
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
394
|
+
"-ml-[5px]"
|
|
395
|
+
],
|
|
396
|
+
6: [
|
|
397
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline",
|
|
398
|
+
"-ml-[4px]"
|
|
399
|
+
]
|
|
400
|
+
};
|
|
401
|
+
var heading = (level, readonly) => {
|
|
402
|
+
const [style, offset] = headings[level];
|
|
403
|
+
return mx(style, readonly && offset);
|
|
404
|
+
};
|
|
405
|
+
var light = "text-neutral-200 dark:text-neutral-800";
|
|
406
|
+
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
407
|
+
var bold = "font-bold";
|
|
408
|
+
var italic = "italic";
|
|
409
|
+
var strikethrough = "line-through";
|
|
410
|
+
var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
|
|
411
|
+
var codeMark = "font-mono text-primary-500";
|
|
412
|
+
var inlineUrl = mx(code, "px-1");
|
|
413
|
+
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
414
|
+
var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
|
|
415
|
+
|
|
416
|
+
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
417
|
+
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
418
|
+
var tokens = tailwindConfig({}).theme;
|
|
419
|
+
|
|
420
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/code.ts
|
|
421
|
+
var CODE_REGEX = /```[\s\S]*?```/gs;
|
|
422
|
+
var styles = EditorView3.baseTheme({
|
|
423
|
+
"& .cm-code-block": {
|
|
424
|
+
display: "block",
|
|
425
|
+
paddingInline: "4px !important"
|
|
426
|
+
},
|
|
427
|
+
"&light .cm-code-block": {
|
|
428
|
+
background: get(tokens, "extend.colors.neutral.50")
|
|
429
|
+
},
|
|
430
|
+
"&dark .cm-code-block": {
|
|
431
|
+
background: get(tokens, "extend.colors.neutral.850")
|
|
432
|
+
},
|
|
433
|
+
"& .cm-code-block-first": {
|
|
434
|
+
paddingTop: "4px !important",
|
|
435
|
+
borderTopLeftRadius: "4px",
|
|
436
|
+
borderTopRightRadius: "4px"
|
|
437
|
+
},
|
|
438
|
+
"& .cm-code-block-last": {
|
|
439
|
+
paddingBottom: "4px !important",
|
|
440
|
+
borderBottomLeftRadius: "4px",
|
|
441
|
+
borderBottomRightRadius: "4px"
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
var getLineRange = (lines, from, to) => {
|
|
445
|
+
const start = lines.findIndex((line) => line.from >= from);
|
|
446
|
+
const end = lines.findIndex((line) => line.to >= to);
|
|
447
|
+
return [
|
|
448
|
+
start,
|
|
449
|
+
end
|
|
450
|
+
];
|
|
451
|
+
};
|
|
452
|
+
var code2 = () => {
|
|
453
|
+
const getDecorations = (view) => {
|
|
454
|
+
const decorations = [];
|
|
455
|
+
if (view.state.readOnly) {
|
|
456
|
+
const text = view.state.doc.sliceString(0);
|
|
457
|
+
const matches = text.matchAll(CODE_REGEX);
|
|
458
|
+
const blocks = view.viewportLineBlocks;
|
|
459
|
+
for (const match of matches) {
|
|
460
|
+
const range = getLineRange(blocks, match.index, match.index + match[0].length);
|
|
461
|
+
for (let i = range[0]; i <= range[1]; i++) {
|
|
462
|
+
const block = blocks[i];
|
|
463
|
+
decorations.push(Decoration.line({
|
|
464
|
+
class: mx2("cm-code-block", i === range[0] && "cm-code-block-first", i === range[1] && "cm-code-block-last")
|
|
465
|
+
}).range(block.from));
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return Decoration.set(decorations);
|
|
470
|
+
};
|
|
471
|
+
return [
|
|
472
|
+
ViewPlugin.fromClass(class {
|
|
473
|
+
constructor(view) {
|
|
474
|
+
this.decorations = getDecorations(view);
|
|
475
|
+
}
|
|
476
|
+
update(update4) {
|
|
477
|
+
if (update4.docChanged || update4.viewportChanged) {
|
|
478
|
+
this.decorations = getDecorations(update4.view);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}, {
|
|
482
|
+
decorations: (value) => value.decorations
|
|
483
|
+
}),
|
|
484
|
+
styles
|
|
485
|
+
];
|
|
486
|
+
};
|
|
487
|
+
|
|
373
488
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/demo.ts
|
|
374
489
|
import { keymap as keymap3 } from "@codemirror/view";
|
|
375
490
|
var defaultItems = [
|
|
@@ -428,18 +543,30 @@ var demo = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
428
543
|
};
|
|
429
544
|
|
|
430
545
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
|
|
431
|
-
import { keymap as keymap4, Decoration, EditorView as
|
|
546
|
+
import { keymap as keymap4, Decoration as Decoration2, EditorView as EditorView4, MatchDecorator, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
|
|
432
547
|
import { debounce } from "@dxos/async";
|
|
433
548
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
434
549
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
|
|
550
|
+
var styles2 = EditorView4.baseTheme({
|
|
551
|
+
"& .cm-bookmark": {
|
|
552
|
+
cursor: "pointer",
|
|
553
|
+
margin: "4px",
|
|
554
|
+
padding: "4px",
|
|
555
|
+
backgroundColor: "yellow"
|
|
556
|
+
},
|
|
557
|
+
"& .cm-bookmark-selected": {
|
|
558
|
+
backgroundColor: "orange"
|
|
559
|
+
}
|
|
560
|
+
});
|
|
435
561
|
var BookmarkWidget = class extends WidgetType {
|
|
436
|
-
constructor(_pos, _id) {
|
|
562
|
+
constructor(_pos, _id, _handleClick) {
|
|
437
563
|
super();
|
|
438
564
|
this._pos = _pos;
|
|
439
565
|
this._id = _id;
|
|
566
|
+
this._handleClick = _handleClick;
|
|
440
567
|
invariant2(this._id, void 0, {
|
|
441
568
|
F: __dxlog_file2,
|
|
442
|
-
L:
|
|
569
|
+
L: 37,
|
|
443
570
|
S: this,
|
|
444
571
|
A: [
|
|
445
572
|
"this._id",
|
|
@@ -453,34 +580,26 @@ var BookmarkWidget = class extends WidgetType {
|
|
|
453
580
|
toDOM() {
|
|
454
581
|
const span = document.createElement("span");
|
|
455
582
|
span.className = "cm-bookmark";
|
|
456
|
-
span.textContent = "\
|
|
583
|
+
span.textContent = "\xA7";
|
|
584
|
+
span.onclick = () => this._handleClick();
|
|
457
585
|
return span;
|
|
458
586
|
}
|
|
459
587
|
};
|
|
460
|
-
var styles = EditorView3.baseTheme({
|
|
461
|
-
"& .cm-bookmark": {
|
|
462
|
-
cursor: "pointer",
|
|
463
|
-
margin: "4px",
|
|
464
|
-
padding: "4px",
|
|
465
|
-
backgroundColor: "yellow"
|
|
466
|
-
},
|
|
467
|
-
"& .cm-bookmark-selected": {
|
|
468
|
-
backgroundColor: "orange"
|
|
469
|
-
}
|
|
470
|
-
});
|
|
471
588
|
var comments = (options = {}) => {
|
|
472
589
|
let active;
|
|
473
590
|
const bookmarkMatcher = new MatchDecorator({
|
|
474
591
|
regexp: /\[\^(\w+)\]/g,
|
|
475
592
|
decoration: (match, view, pos) => {
|
|
476
593
|
const id = match[1];
|
|
477
|
-
return
|
|
594
|
+
return Decoration2.replace({
|
|
478
595
|
id,
|
|
479
|
-
widget: new BookmarkWidget(pos, id)
|
|
596
|
+
widget: new BookmarkWidget(pos, id, () => handleUpdate({
|
|
597
|
+
active: id
|
|
598
|
+
}))
|
|
480
599
|
});
|
|
481
600
|
}
|
|
482
601
|
});
|
|
483
|
-
const bookmarks =
|
|
602
|
+
const bookmarks = ViewPlugin2.fromClass(class {
|
|
484
603
|
constructor(view) {
|
|
485
604
|
this.bookmarks = bookmarkMatcher.createDeco(view);
|
|
486
605
|
}
|
|
@@ -489,11 +608,11 @@ var comments = (options = {}) => {
|
|
|
489
608
|
}
|
|
490
609
|
}, {
|
|
491
610
|
decorations: (instance) => instance.bookmarks,
|
|
492
|
-
provide: (plugin) =>
|
|
493
|
-
return view.plugin(plugin)?.bookmarks ||
|
|
611
|
+
provide: (plugin) => EditorView4.atomicRanges.of((view) => {
|
|
612
|
+
return view.plugin(plugin)?.bookmarks || Decoration2.none;
|
|
494
613
|
})
|
|
495
614
|
});
|
|
496
|
-
const
|
|
615
|
+
const handleUpdate = debounce((data) => {
|
|
497
616
|
options.onUpdate?.(data);
|
|
498
617
|
}, 200);
|
|
499
618
|
return [
|
|
@@ -501,17 +620,17 @@ var comments = (options = {}) => {
|
|
|
501
620
|
{
|
|
502
621
|
key: options?.key ?? "shift-meta-c",
|
|
503
622
|
run: (view) => {
|
|
504
|
-
const
|
|
623
|
+
const { from, to, head } = view.state.selection.main;
|
|
624
|
+
const id = options.onCreate?.(from, to);
|
|
505
625
|
if (id) {
|
|
506
|
-
const pos = view.state.selection.main.head;
|
|
507
626
|
const tag = `[^${id}]`;
|
|
508
627
|
view.dispatch({
|
|
509
628
|
changes: {
|
|
510
|
-
from:
|
|
629
|
+
from: head,
|
|
511
630
|
insert: tag
|
|
512
631
|
},
|
|
513
632
|
selection: {
|
|
514
|
-
anchor:
|
|
633
|
+
anchor: head + tag.length
|
|
515
634
|
}
|
|
516
635
|
});
|
|
517
636
|
return true;
|
|
@@ -522,20 +641,23 @@ var comments = (options = {}) => {
|
|
|
522
641
|
]),
|
|
523
642
|
bookmarks,
|
|
524
643
|
// Monitor cursor movement.
|
|
525
|
-
|
|
644
|
+
EditorView4.updateListener.of((update4) => {
|
|
526
645
|
active = void 0;
|
|
527
646
|
if (!options.onUpdate) {
|
|
528
647
|
return;
|
|
529
648
|
}
|
|
530
|
-
const view = update4
|
|
531
|
-
const pos =
|
|
649
|
+
const { view, state } = update4;
|
|
650
|
+
const pos = state.selection.main.head;
|
|
532
651
|
const decorations = [];
|
|
533
652
|
const rangeSet = view.plugin(bookmarks)?.bookmarks;
|
|
534
653
|
let closest = Infinity;
|
|
535
|
-
const { from, to } =
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
654
|
+
const { from, to } = (
|
|
655
|
+
/* view.visibleRanges?.[0] ?? */
|
|
656
|
+
{
|
|
657
|
+
from: 0,
|
|
658
|
+
to: state.doc.length
|
|
659
|
+
}
|
|
660
|
+
);
|
|
539
661
|
rangeSet?.between(from, to, (from2, to2, value) => {
|
|
540
662
|
decorations.push({
|
|
541
663
|
from: from2,
|
|
@@ -549,7 +671,7 @@ var comments = (options = {}) => {
|
|
|
549
671
|
}
|
|
550
672
|
});
|
|
551
673
|
if (decorations.length) {
|
|
552
|
-
|
|
674
|
+
handleUpdate({
|
|
553
675
|
active,
|
|
554
676
|
items: decorations.map(({ from: from2, value: { spec: { id } } }) => ({
|
|
555
677
|
id,
|
|
@@ -559,30 +681,134 @@ var comments = (options = {}) => {
|
|
|
559
681
|
});
|
|
560
682
|
}
|
|
561
683
|
}),
|
|
562
|
-
|
|
684
|
+
styles2
|
|
685
|
+
];
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/highlight.ts
|
|
689
|
+
import { StateEffect, StateField } from "@codemirror/state";
|
|
690
|
+
import { Decoration as Decoration3, EditorView as EditorView5 } from "@codemirror/view";
|
|
691
|
+
import sortBy from "lodash.sortby";
|
|
692
|
+
import { useEffect } from "react";
|
|
693
|
+
var styles3 = EditorView5.baseTheme({
|
|
694
|
+
"& .cm-highlight": {
|
|
695
|
+
backgroundColor: "yellow"
|
|
696
|
+
},
|
|
697
|
+
"& .cm-highlight::before": {
|
|
698
|
+
content: "]"
|
|
699
|
+
},
|
|
700
|
+
"& .cm-highlight-active": {
|
|
701
|
+
backgroundColor: "lime"
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
var marks = {
|
|
705
|
+
highlight: Decoration3.mark({
|
|
706
|
+
class: "cm-highlight"
|
|
707
|
+
}),
|
|
708
|
+
HighlightActive: Decoration3.mark({
|
|
709
|
+
class: "cm-highlight-active"
|
|
710
|
+
})
|
|
711
|
+
};
|
|
712
|
+
var setHighlights = StateEffect.define();
|
|
713
|
+
var useHighlights = (view, ranges = []) => {
|
|
714
|
+
useEffect(() => {
|
|
715
|
+
view?.dispatch({
|
|
716
|
+
effects: setHighlights.of(ranges)
|
|
717
|
+
});
|
|
718
|
+
}, [
|
|
719
|
+
view,
|
|
720
|
+
ranges
|
|
721
|
+
]);
|
|
722
|
+
};
|
|
723
|
+
var highlightStateField = StateField.define({
|
|
724
|
+
create: () => [],
|
|
725
|
+
update: (threads, tr) => {
|
|
726
|
+
for (const effect of tr.effects) {
|
|
727
|
+
if (effect.is(setHighlights)) {
|
|
728
|
+
return effect.value;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return threads;
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
var highlightDecorations = EditorView5.decorations.compute([
|
|
735
|
+
highlightStateField
|
|
736
|
+
], (state) => {
|
|
737
|
+
const selectionRanges = state.field(highlightStateField);
|
|
738
|
+
const decorations = sortBy(selectionRanges ?? [], (selection) => selection.from)?.flatMap((selection) => {
|
|
739
|
+
const range = {
|
|
740
|
+
from: selection.from,
|
|
741
|
+
to: selection.to + 1
|
|
742
|
+
};
|
|
743
|
+
if (selection.to > selection.from) {
|
|
744
|
+
if (selection.active) {
|
|
745
|
+
return marks.HighlightActive.range(range.from, range.to);
|
|
746
|
+
} else {
|
|
747
|
+
return marks.highlight.range(range.from, range.to);
|
|
748
|
+
}
|
|
749
|
+
} else {
|
|
750
|
+
return [];
|
|
751
|
+
}
|
|
752
|
+
}) ?? [];
|
|
753
|
+
return Decoration3.set(decorations);
|
|
754
|
+
});
|
|
755
|
+
var listener = (options) => {
|
|
756
|
+
return EditorView5.updateListener.of((update4) => {
|
|
757
|
+
const { view, state } = update4;
|
|
758
|
+
const { head } = state.selection.main;
|
|
759
|
+
const ranges = state.field(highlightStateField);
|
|
760
|
+
let mod = false;
|
|
761
|
+
const newRanges = ranges.map((range) => {
|
|
762
|
+
const active = head >= range.from && head <= range.to;
|
|
763
|
+
if (active !== range.active) {
|
|
764
|
+
mod = true;
|
|
765
|
+
return {
|
|
766
|
+
...range,
|
|
767
|
+
active
|
|
768
|
+
};
|
|
769
|
+
} else {
|
|
770
|
+
return range;
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
if (mod) {
|
|
774
|
+
view.dispatch({
|
|
775
|
+
effects: setHighlights.of(newRanges)
|
|
776
|
+
});
|
|
777
|
+
options?.onChange?.(newRanges.find((range) => range.active)?.id);
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
};
|
|
781
|
+
var highlight = (options = {}) => {
|
|
782
|
+
return [
|
|
783
|
+
highlightStateField,
|
|
784
|
+
highlightDecorations,
|
|
785
|
+
listener(options),
|
|
786
|
+
styles3
|
|
563
787
|
];
|
|
564
788
|
};
|
|
565
789
|
|
|
566
790
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/image.ts
|
|
567
791
|
import { syntaxTree } from "@codemirror/language";
|
|
568
792
|
import { RangeSetBuilder, StateField as StateField2 } from "@codemirror/state";
|
|
569
|
-
import { Decoration as
|
|
793
|
+
import { Decoration as Decoration4, EditorView as EditorView6, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
570
794
|
var image = (options = {}) => {
|
|
571
795
|
return StateField2.define({
|
|
572
796
|
create: (state) => update(state, options),
|
|
573
797
|
update: (_, tr) => update(tr.state, options),
|
|
574
|
-
provide: (field) =>
|
|
798
|
+
provide: (field) => EditorView6.decorations.from(field)
|
|
575
799
|
});
|
|
576
800
|
};
|
|
577
801
|
var update = (state, options) => {
|
|
578
802
|
const builder = new RangeSetBuilder();
|
|
803
|
+
const cursor = state.selection.main.head;
|
|
579
804
|
syntaxTree(state).iterate({
|
|
580
805
|
enter: (node) => {
|
|
581
806
|
if (node.name === "Image") {
|
|
582
807
|
const urlNode = node.node.getChild("URL");
|
|
583
808
|
if (urlNode) {
|
|
809
|
+
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
584
810
|
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
585
|
-
builder.add(
|
|
811
|
+
builder.add(hide ? node.from : node.to, node.to, Decoration4.replace({
|
|
586
812
|
widget: new ImageWidget(url)
|
|
587
813
|
}));
|
|
588
814
|
}
|
|
@@ -610,12 +836,12 @@ var ImageWidget = class extends WidgetType2 {
|
|
|
610
836
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/link.ts
|
|
611
837
|
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
612
838
|
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField3 } from "@codemirror/state";
|
|
613
|
-
import { Decoration as
|
|
839
|
+
import { Decoration as Decoration5, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
614
840
|
var link = (options = {}) => {
|
|
615
841
|
return StateField3.define({
|
|
616
842
|
create: (state) => update2(state, options),
|
|
617
843
|
update: (_, tr) => update2(tr.state, options),
|
|
618
|
-
provide: (field) =>
|
|
844
|
+
provide: (field) => EditorView7.decorations.from(field)
|
|
619
845
|
});
|
|
620
846
|
};
|
|
621
847
|
var LinkButton = class extends WidgetType3 {
|
|
@@ -670,20 +896,20 @@ var update2 = (state, options) => {
|
|
|
670
896
|
syntaxTree2(state).iterate({
|
|
671
897
|
enter: (node) => {
|
|
672
898
|
if (node.name === "Link") {
|
|
673
|
-
const
|
|
674
|
-
const text =
|
|
899
|
+
const marks2 = node.node.getChildren("LinkMark");
|
|
900
|
+
const text = marks2.length >= 2 ? state.sliceDoc(marks2[0].to, marks2[1].from) : "";
|
|
675
901
|
const urlNode = node.node.getChild("URL");
|
|
676
902
|
const url = urlNode ? state.sliceDoc(urlNode.from, urlNode.to) : "";
|
|
677
903
|
if (!url) {
|
|
678
904
|
return false;
|
|
679
905
|
}
|
|
680
|
-
if (cursor < node.from || cursor > node.to) {
|
|
681
|
-
builder.add(node.from, node.to,
|
|
906
|
+
if (state.readOnly || cursor < node.from || cursor > node.to) {
|
|
907
|
+
builder.add(node.from, node.to, Decoration5.replace({
|
|
682
908
|
widget: new LinkText(node.from, text, options.link ? url : void 0)
|
|
683
909
|
}));
|
|
684
910
|
}
|
|
685
911
|
if (options.onRender) {
|
|
686
|
-
builder.add(node.to, node.to,
|
|
912
|
+
builder.add(node.to, node.to, Decoration5.replace({
|
|
687
913
|
widget: new LinkButton(node.from, url, options.onRender)
|
|
688
914
|
}));
|
|
689
915
|
}
|
|
@@ -696,7 +922,7 @@ var update2 = (state, options) => {
|
|
|
696
922
|
|
|
697
923
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/listener.ts
|
|
698
924
|
import { StateField as StateField4 } from "@codemirror/state";
|
|
699
|
-
var
|
|
925
|
+
var listener2 = ({ onChange }) => {
|
|
700
926
|
return StateField4.define({
|
|
701
927
|
create: () => null,
|
|
702
928
|
update: (_value, transaction) => {
|
|
@@ -710,70 +936,22 @@ var listener = ({ onChange }) => {
|
|
|
710
936
|
|
|
711
937
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
712
938
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
713
|
-
import {
|
|
939
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
714
940
|
import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
|
|
715
941
|
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
716
942
|
import { languages } from "@codemirror/language-data";
|
|
717
|
-
import {
|
|
943
|
+
import { searchKeymap } from "@codemirror/search";
|
|
718
944
|
import { EditorState } from "@codemirror/state";
|
|
719
945
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
720
|
-
import { crosshairCursor, drawSelection, dropCursor, EditorView as
|
|
946
|
+
import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView8, keymap as keymap5, placeholder as placeholder2 } from "@codemirror/view";
|
|
721
947
|
|
|
722
948
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
|
|
723
949
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
724
950
|
import { HighlightStyle } from "@codemirror/language";
|
|
725
951
|
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
726
|
-
import
|
|
727
|
-
import
|
|
728
|
-
|
|
729
|
-
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
730
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
731
|
-
var headings = {
|
|
732
|
-
1: [
|
|
733
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
734
|
-
"-ml-1.5"
|
|
735
|
-
],
|
|
736
|
-
2: [
|
|
737
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
738
|
-
"-ml-1.5"
|
|
739
|
-
],
|
|
740
|
-
3: [
|
|
741
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
742
|
-
"-ml-1.5"
|
|
743
|
-
],
|
|
744
|
-
4: [
|
|
745
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
746
|
-
"-ml-[5px]"
|
|
747
|
-
],
|
|
748
|
-
5: [
|
|
749
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
750
|
-
"-ml-[5px]"
|
|
751
|
-
],
|
|
752
|
-
6: [
|
|
753
|
-
"mbs-4 mbe-2 font-medium text-inherit no-underline",
|
|
754
|
-
"-ml-[4px]"
|
|
755
|
-
]
|
|
756
|
-
};
|
|
757
|
-
var heading = (level, readonly) => {
|
|
758
|
-
const [style, offset] = headings[level];
|
|
759
|
-
return mx(style, readonly && offset);
|
|
760
|
-
};
|
|
761
|
-
var light = "text-neutral-200 dark:text-neutral-800";
|
|
762
|
-
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
763
|
-
var bold = "font-bold";
|
|
764
|
-
var italic = "italic";
|
|
765
|
-
var strikethrough = "line-through";
|
|
766
|
-
var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
|
|
767
|
-
var codeMark = "font-mono text-primary-500";
|
|
768
|
-
var inlineUrl = mx(code, "px-1");
|
|
769
|
-
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
770
|
-
var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
|
|
771
|
-
|
|
772
|
-
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
773
|
-
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
774
|
-
var tokens = tailwindConfig({}).theme;
|
|
775
|
-
|
|
776
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
|
|
952
|
+
import { Table } from "@lezer/markdown";
|
|
953
|
+
import get2 from "lodash.get";
|
|
954
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
777
955
|
var markdownTags = {
|
|
778
956
|
Blockquote: Tag.define(),
|
|
779
957
|
CodeMark: Tag.define(),
|
|
@@ -786,188 +964,201 @@ var markdownTags = {
|
|
|
786
964
|
LinkReference: Tag.define(),
|
|
787
965
|
ListMark: Tag.define(),
|
|
788
966
|
QuoteMark: Tag.define(),
|
|
789
|
-
URL: Tag.define()
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
props: [
|
|
793
|
-
styleTags(markdownTags)
|
|
794
|
-
]
|
|
967
|
+
URL: Tag.define(),
|
|
968
|
+
// Custom.
|
|
969
|
+
TableCell: Tag.define()
|
|
795
970
|
};
|
|
796
|
-
|
|
797
|
-
{
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
tags.character,
|
|
803
|
-
tags.propertyName,
|
|
804
|
-
tags.macroName,
|
|
805
|
-
tags.color,
|
|
806
|
-
tags.constant(tags.name),
|
|
807
|
-
tags.standard(tags.name),
|
|
808
|
-
tags.definition(tags.name),
|
|
809
|
-
tags.separator,
|
|
810
|
-
tags.typeName,
|
|
811
|
-
tags.className,
|
|
812
|
-
tags.number,
|
|
813
|
-
tags.changed,
|
|
814
|
-
tags.annotation,
|
|
815
|
-
tags.modifier,
|
|
816
|
-
tags.self,
|
|
817
|
-
tags.namespace,
|
|
818
|
-
tags.operator,
|
|
819
|
-
tags.operatorKeyword,
|
|
820
|
-
tags.escape,
|
|
821
|
-
tags.regexp,
|
|
822
|
-
tags.special(tags.string),
|
|
823
|
-
tags.meta,
|
|
824
|
-
tags.comment,
|
|
825
|
-
tags.atom,
|
|
826
|
-
tags.bool,
|
|
827
|
-
tags.special(tags.variableName),
|
|
828
|
-
tags.processingInstruction,
|
|
829
|
-
tags.string,
|
|
830
|
-
tags.inserted,
|
|
831
|
-
tags.invalid
|
|
832
|
-
],
|
|
833
|
-
color: "inherit !important"
|
|
834
|
-
},
|
|
835
|
-
// Markdown marks.
|
|
836
|
-
{
|
|
837
|
-
tag: [
|
|
838
|
-
tags.meta,
|
|
839
|
-
tags.processingInstruction,
|
|
840
|
-
markdownTags.LinkLabel,
|
|
841
|
-
markdownTags.LinkReference,
|
|
842
|
-
markdownTags.ListMark
|
|
843
|
-
],
|
|
844
|
-
class: mark
|
|
845
|
-
},
|
|
846
|
-
// Markdown marks.
|
|
847
|
-
{
|
|
848
|
-
tag: [
|
|
849
|
-
markdownTags.CodeMark,
|
|
850
|
-
markdownTags.HeaderMark,
|
|
851
|
-
markdownTags.QuoteMark,
|
|
852
|
-
markdownTags.EmphasisMark
|
|
853
|
-
],
|
|
854
|
-
class: readonly ? "hidden" : mark
|
|
855
|
-
},
|
|
856
|
-
// E.g., code block language (after ```).
|
|
857
|
-
{
|
|
858
|
-
tag: [
|
|
859
|
-
tags.function(tags.variableName),
|
|
860
|
-
tags.labelName
|
|
861
|
-
],
|
|
862
|
-
class: readonly ? "hidden" : codeMark
|
|
863
|
-
},
|
|
864
|
-
// Headings.
|
|
865
|
-
{
|
|
866
|
-
tag: tags.heading1,
|
|
867
|
-
class: heading(1, readonly)
|
|
868
|
-
},
|
|
869
|
-
{
|
|
870
|
-
tag: tags.heading2,
|
|
871
|
-
class: heading(2, readonly)
|
|
872
|
-
},
|
|
873
|
-
{
|
|
874
|
-
tag: tags.heading3,
|
|
875
|
-
class: heading(3, readonly)
|
|
876
|
-
},
|
|
877
|
-
{
|
|
878
|
-
tag: tags.heading4,
|
|
879
|
-
class: heading(4, readonly)
|
|
880
|
-
},
|
|
881
|
-
{
|
|
882
|
-
tag: tags.heading5,
|
|
883
|
-
class: heading(5, readonly)
|
|
884
|
-
},
|
|
885
|
-
{
|
|
886
|
-
tag: tags.heading6,
|
|
887
|
-
class: heading(6, readonly)
|
|
888
|
-
},
|
|
889
|
-
// Emphasis.
|
|
890
|
-
{
|
|
891
|
-
tag: tags.emphasis,
|
|
892
|
-
class: italic
|
|
893
|
-
},
|
|
894
|
-
{
|
|
895
|
-
tag: tags.strong,
|
|
896
|
-
class: bold
|
|
897
|
-
},
|
|
898
|
-
{
|
|
899
|
-
tag: tags.strikethrough,
|
|
900
|
-
class: strikethrough
|
|
901
|
-
},
|
|
902
|
-
// Naked URLs.
|
|
903
|
-
{
|
|
904
|
-
tag: [
|
|
905
|
-
markdownTags.URL
|
|
906
|
-
],
|
|
907
|
-
class: inlineUrl
|
|
908
|
-
},
|
|
909
|
-
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
910
|
-
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
911
|
-
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
912
|
-
// the code, but all other CSS properties will be inherited.
|
|
913
|
-
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
914
|
-
{
|
|
915
|
-
tag: [
|
|
916
|
-
markdownTags.CodeText,
|
|
917
|
-
markdownTags.InlineCode
|
|
918
|
-
],
|
|
919
|
-
class: code
|
|
920
|
-
},
|
|
921
|
-
{
|
|
922
|
-
tag: [
|
|
923
|
-
markdownTags.QuoteMark
|
|
924
|
-
],
|
|
925
|
-
class: blockquote
|
|
926
|
-
},
|
|
927
|
-
{
|
|
928
|
-
tag: [
|
|
929
|
-
markdownTags.HorizontalRule
|
|
930
|
-
],
|
|
931
|
-
class: mx2(horizontalRule, readonly && "-indent-[100rem]")
|
|
932
|
-
}
|
|
933
|
-
], {
|
|
934
|
-
scope: markdownLanguage,
|
|
935
|
-
all: {
|
|
936
|
-
fontFamily: get(tokens, "fontFamily.body", []).join(",")
|
|
971
|
+
Table.defineNodes?.forEach((node) => {
|
|
972
|
+
switch (node?.name) {
|
|
973
|
+
case "TableCell": {
|
|
974
|
+
node.style = markdownTags.TableCell;
|
|
975
|
+
break;
|
|
976
|
+
}
|
|
937
977
|
}
|
|
938
978
|
});
|
|
979
|
+
var markdownTagsExtensions = [
|
|
980
|
+
Table,
|
|
981
|
+
{
|
|
982
|
+
props: [
|
|
983
|
+
styleTags(markdownTags)
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
];
|
|
987
|
+
var markdownHighlightStyle = (readonly) => {
|
|
988
|
+
return HighlightStyle.define([
|
|
989
|
+
{
|
|
990
|
+
tag: [
|
|
991
|
+
tags.keyword,
|
|
992
|
+
tags.name,
|
|
993
|
+
tags.deleted,
|
|
994
|
+
tags.character,
|
|
995
|
+
tags.propertyName,
|
|
996
|
+
tags.macroName,
|
|
997
|
+
tags.color,
|
|
998
|
+
tags.constant(tags.name),
|
|
999
|
+
tags.standard(tags.name),
|
|
1000
|
+
tags.definition(tags.name),
|
|
1001
|
+
tags.separator,
|
|
1002
|
+
tags.typeName,
|
|
1003
|
+
tags.className,
|
|
1004
|
+
tags.number,
|
|
1005
|
+
tags.changed,
|
|
1006
|
+
tags.annotation,
|
|
1007
|
+
tags.modifier,
|
|
1008
|
+
tags.self,
|
|
1009
|
+
tags.namespace,
|
|
1010
|
+
tags.operator,
|
|
1011
|
+
tags.operatorKeyword,
|
|
1012
|
+
tags.escape,
|
|
1013
|
+
tags.regexp,
|
|
1014
|
+
tags.special(tags.string),
|
|
1015
|
+
tags.meta,
|
|
1016
|
+
tags.comment,
|
|
1017
|
+
tags.atom,
|
|
1018
|
+
tags.bool,
|
|
1019
|
+
tags.special(tags.variableName),
|
|
1020
|
+
tags.processingInstruction,
|
|
1021
|
+
tags.string,
|
|
1022
|
+
tags.inserted,
|
|
1023
|
+
tags.invalid
|
|
1024
|
+
],
|
|
1025
|
+
color: "inherit !important"
|
|
1026
|
+
},
|
|
1027
|
+
// Markdown marks.
|
|
1028
|
+
{
|
|
1029
|
+
tag: [
|
|
1030
|
+
tags.meta,
|
|
1031
|
+
tags.processingInstruction,
|
|
1032
|
+
markdownTags.LinkLabel,
|
|
1033
|
+
markdownTags.LinkReference,
|
|
1034
|
+
markdownTags.ListMark
|
|
1035
|
+
],
|
|
1036
|
+
class: mark
|
|
1037
|
+
},
|
|
1038
|
+
// Markdown marks.
|
|
1039
|
+
{
|
|
1040
|
+
tag: [
|
|
1041
|
+
markdownTags.CodeMark,
|
|
1042
|
+
markdownTags.HeaderMark,
|
|
1043
|
+
markdownTags.QuoteMark,
|
|
1044
|
+
markdownTags.EmphasisMark
|
|
1045
|
+
],
|
|
1046
|
+
class: readonly ? "hidden" : mark
|
|
1047
|
+
},
|
|
1048
|
+
// E.g., code block language (after ```).
|
|
1049
|
+
{
|
|
1050
|
+
tag: [
|
|
1051
|
+
tags.function(tags.variableName),
|
|
1052
|
+
tags.labelName
|
|
1053
|
+
],
|
|
1054
|
+
class: readonly ? "hidden" : codeMark
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
tag: [
|
|
1058
|
+
tags.monospace
|
|
1059
|
+
],
|
|
1060
|
+
class: "font-mono"
|
|
1061
|
+
},
|
|
1062
|
+
// Headings.
|
|
1063
|
+
{
|
|
1064
|
+
tag: tags.heading1,
|
|
1065
|
+
class: heading(1, readonly)
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
tag: tags.heading2,
|
|
1069
|
+
class: heading(2, readonly)
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
tag: tags.heading3,
|
|
1073
|
+
class: heading(3, readonly)
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
tag: tags.heading4,
|
|
1077
|
+
class: heading(4, readonly)
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
tag: tags.heading5,
|
|
1081
|
+
class: heading(5, readonly)
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
tag: tags.heading6,
|
|
1085
|
+
class: heading(6, readonly)
|
|
1086
|
+
},
|
|
1087
|
+
// Emphasis.
|
|
1088
|
+
{
|
|
1089
|
+
tag: tags.emphasis,
|
|
1090
|
+
class: italic
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
tag: tags.strong,
|
|
1094
|
+
class: bold
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
tag: tags.strikethrough,
|
|
1098
|
+
class: strikethrough
|
|
1099
|
+
},
|
|
1100
|
+
// Naked URLs.
|
|
1101
|
+
{
|
|
1102
|
+
tag: [
|
|
1103
|
+
markdownTags.URL
|
|
1104
|
+
],
|
|
1105
|
+
class: inlineUrl
|
|
1106
|
+
},
|
|
1107
|
+
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
1108
|
+
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
1109
|
+
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
1110
|
+
// the code, but all other CSS properties will be inherited.
|
|
1111
|
+
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
1112
|
+
{
|
|
1113
|
+
tag: [
|
|
1114
|
+
markdownTags.CodeText,
|
|
1115
|
+
markdownTags.InlineCode
|
|
1116
|
+
],
|
|
1117
|
+
class: code
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
tag: [
|
|
1121
|
+
markdownTags.QuoteMark
|
|
1122
|
+
],
|
|
1123
|
+
class: blockquote
|
|
1124
|
+
},
|
|
1125
|
+
// TODO(burdon): Replace with extension.
|
|
1126
|
+
{
|
|
1127
|
+
tag: [
|
|
1128
|
+
markdownTags.HorizontalRule
|
|
1129
|
+
],
|
|
1130
|
+
class: mx3(horizontalRule, readonly && "-indent-[100rem]")
|
|
1131
|
+
},
|
|
1132
|
+
// TODO(burdon): Only if being edited.
|
|
1133
|
+
{
|
|
1134
|
+
tag: [
|
|
1135
|
+
markdownTags.TableCell
|
|
1136
|
+
],
|
|
1137
|
+
class: "font-mono"
|
|
1138
|
+
}
|
|
1139
|
+
], {
|
|
1140
|
+
scope: markdownLanguage,
|
|
1141
|
+
all: {
|
|
1142
|
+
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
};
|
|
939
1146
|
|
|
940
1147
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
941
1148
|
var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
942
1149
|
return [
|
|
1150
|
+
EditorState.allowMultipleSelections.of(true),
|
|
1151
|
+
EditorState.tabSize.of(2),
|
|
1152
|
+
EditorView8.lineWrapping,
|
|
1153
|
+
customKeymap(),
|
|
943
1154
|
bracketMatching2(),
|
|
944
1155
|
closeBrackets2(),
|
|
945
|
-
_placeholder && placeholder2(_placeholder),
|
|
946
|
-
EditorState.allowMultipleSelections.of(true),
|
|
947
|
-
EditorView6.lineWrapping,
|
|
948
1156
|
crosshairCursor(),
|
|
949
1157
|
dropCursor(),
|
|
950
|
-
|
|
951
|
-
highlightActiveLine(),
|
|
952
|
-
highlightActiveLineGutter(),
|
|
953
|
-
highlightSelectionMatches(),
|
|
954
|
-
highlightSpecialChars(),
|
|
1158
|
+
drawSelection2(),
|
|
955
1159
|
history(),
|
|
956
1160
|
indentOnInput(),
|
|
957
|
-
|
|
958
|
-
// https://codemirror.net/docs/ref/#view.keymap
|
|
959
|
-
keymap5.of([
|
|
960
|
-
// https://codemirror.net/docs/ref/#commands.defaultKeymap
|
|
961
|
-
...defaultKeymap,
|
|
962
|
-
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
963
|
-
...historyKeymap,
|
|
964
|
-
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
965
|
-
...closeBracketsKeymap,
|
|
966
|
-
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
967
|
-
...searchKeymap,
|
|
968
|
-
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
969
|
-
indentWithTab
|
|
970
|
-
]),
|
|
1161
|
+
_placeholder && placeholder2(_placeholder),
|
|
971
1162
|
// Main extension.
|
|
972
1163
|
// https://github.com/codemirror/lang-markdown
|
|
973
1164
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -982,8 +1173,8 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
982
1173
|
codeLanguages: languages,
|
|
983
1174
|
// Parser extensions.
|
|
984
1175
|
extensions: [
|
|
985
|
-
// GFM
|
|
986
|
-
|
|
1176
|
+
// GFM provided by default.
|
|
1177
|
+
markdownTagsExtensions
|
|
987
1178
|
]
|
|
988
1179
|
}),
|
|
989
1180
|
// https://github.com/codemirror/theme-one-dark
|
|
@@ -992,6 +1183,18 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
992
1183
|
syntaxHighlighting2(markdownHighlightStyle(readonly))
|
|
993
1184
|
].filter(Boolean);
|
|
994
1185
|
};
|
|
1186
|
+
var customKeymap = () => keymap5.of([
|
|
1187
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1188
|
+
indentWithTab,
|
|
1189
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1190
|
+
...standardKeymap,
|
|
1191
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
1192
|
+
...historyKeymap,
|
|
1193
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
1194
|
+
...closeBracketsKeymap,
|
|
1195
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
1196
|
+
...searchKeymap
|
|
1197
|
+
]);
|
|
995
1198
|
|
|
996
1199
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/mention.ts
|
|
997
1200
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
@@ -1019,60 +1222,62 @@ var mention = ({ onSearch }) => {
|
|
|
1019
1222
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
|
|
1020
1223
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1021
1224
|
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
|
|
1022
|
-
import { Decoration as
|
|
1225
|
+
import { Decoration as Decoration6, EditorView as EditorView9, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1023
1226
|
var table = (options = {}) => {
|
|
1024
1227
|
return StateField5.define({
|
|
1025
1228
|
create: (state) => update3(state, options),
|
|
1026
1229
|
update: (_, tr) => update3(tr.state, options),
|
|
1027
|
-
provide: (field) =>
|
|
1230
|
+
provide: (field) => EditorView9.decorations.from(field)
|
|
1028
1231
|
});
|
|
1029
1232
|
};
|
|
1030
1233
|
var update3 = (state, options) => {
|
|
1031
1234
|
const builder = new RangeSetBuilder3();
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
break;
|
|
1064
|
-
}
|
|
1065
|
-
case "TableDelimiter": {
|
|
1066
|
-
getTable().to = node.to;
|
|
1067
|
-
break;
|
|
1235
|
+
const cursor = state.selection.main.head;
|
|
1236
|
+
const tables = [];
|
|
1237
|
+
const getTable = () => tables[tables.length - 1];
|
|
1238
|
+
const getRow = () => {
|
|
1239
|
+
const table2 = getTable();
|
|
1240
|
+
return table2.rows?.[table2.rows.length - 1];
|
|
1241
|
+
};
|
|
1242
|
+
syntaxTree3(state).iterate({
|
|
1243
|
+
enter: (node) => {
|
|
1244
|
+
switch (node.name) {
|
|
1245
|
+
case "Table": {
|
|
1246
|
+
tables.push({
|
|
1247
|
+
from: node.from,
|
|
1248
|
+
to: node.to
|
|
1249
|
+
});
|
|
1250
|
+
break;
|
|
1251
|
+
}
|
|
1252
|
+
case "TableHeader": {
|
|
1253
|
+
getTable().header = [];
|
|
1254
|
+
break;
|
|
1255
|
+
}
|
|
1256
|
+
case "TableRow": {
|
|
1257
|
+
(getTable().rows ??= []).push([]);
|
|
1258
|
+
break;
|
|
1259
|
+
}
|
|
1260
|
+
case "TableCell": {
|
|
1261
|
+
const row = getRow();
|
|
1262
|
+
if (row) {
|
|
1263
|
+
row.push(state.sliceDoc(node.from, node.to));
|
|
1264
|
+
} else {
|
|
1265
|
+
getTable().header?.push(state.sliceDoc(node.from, node.to));
|
|
1068
1266
|
}
|
|
1267
|
+
break;
|
|
1069
1268
|
}
|
|
1070
1269
|
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
tables.forEach((table2) => {
|
|
1273
|
+
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
1274
|
+
hide && builder.add(table2.from, table2.to, Decoration6.replace({
|
|
1073
1275
|
widget: new TableWidget(table2)
|
|
1074
|
-
}))
|
|
1075
|
-
|
|
1276
|
+
}));
|
|
1277
|
+
builder.add(table2.from, table2.to, Decoration6.mark({
|
|
1278
|
+
class: "cm-table"
|
|
1279
|
+
}));
|
|
1280
|
+
});
|
|
1076
1281
|
return builder.finish();
|
|
1077
1282
|
};
|
|
1078
1283
|
var TableWidget = class extends WidgetType4 {
|
|
@@ -1087,11 +1292,11 @@ var TableWidget = class extends WidgetType4 {
|
|
|
1087
1292
|
const table2 = document.createElement("table");
|
|
1088
1293
|
{
|
|
1089
1294
|
const header = table2.appendChild(document.createElement("thead"));
|
|
1090
|
-
const
|
|
1295
|
+
const tr = header.appendChild(document.createElement("tr"));
|
|
1091
1296
|
this._table.header?.forEach((cell) => {
|
|
1092
1297
|
const th = document.createElement("th");
|
|
1093
1298
|
th.setAttribute("class", "cm-table-head");
|
|
1094
|
-
|
|
1299
|
+
tr.appendChild(th).textContent = cell;
|
|
1095
1300
|
});
|
|
1096
1301
|
}
|
|
1097
1302
|
{
|
|
@@ -1110,7 +1315,13 @@ var TableWidget = class extends WidgetType4 {
|
|
|
1110
1315
|
};
|
|
1111
1316
|
|
|
1112
1317
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
|
|
1113
|
-
import { EditorView as
|
|
1318
|
+
import { EditorView as EditorView10, Decoration as Decoration7, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
|
|
1319
|
+
var styles4 = EditorView10.baseTheme({
|
|
1320
|
+
"& .cm-task-item": {
|
|
1321
|
+
paddingLeft: "4px",
|
|
1322
|
+
paddingRight: "8px"
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1114
1325
|
var CheckboxWidget = class extends WidgetType5 {
|
|
1115
1326
|
constructor(_pos, _checked, _indent, _onCheck) {
|
|
1116
1327
|
super();
|
|
@@ -1145,19 +1356,13 @@ var CheckboxWidget = class extends WidgetType5 {
|
|
|
1145
1356
|
return false;
|
|
1146
1357
|
}
|
|
1147
1358
|
};
|
|
1148
|
-
var styles2 = EditorView8.baseTheme({
|
|
1149
|
-
"& .cm-task-item": {
|
|
1150
|
-
paddingLeft: "4px",
|
|
1151
|
-
paddingRight: "8px"
|
|
1152
|
-
}
|
|
1153
|
-
});
|
|
1154
1359
|
var tasklist = (options = {}) => {
|
|
1155
1360
|
const taskMatcher = new MatchDecorator2({
|
|
1156
1361
|
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
1157
1362
|
decoration: (match, view, pos) => {
|
|
1158
1363
|
const indent = Math.floor(match[1].length / 2);
|
|
1159
1364
|
const checked = match[2] === "x" || match[2] === "X";
|
|
1160
|
-
return
|
|
1365
|
+
return Decoration7.replace({
|
|
1161
1366
|
widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
1162
1367
|
const idx = pos + match[0].indexOf("[") + 1;
|
|
1163
1368
|
view.dispatch({
|
|
@@ -1175,7 +1380,7 @@ var tasklist = (options = {}) => {
|
|
|
1175
1380
|
});
|
|
1176
1381
|
}
|
|
1177
1382
|
});
|
|
1178
|
-
const tasks =
|
|
1383
|
+
const tasks = ViewPlugin3.fromClass(class {
|
|
1179
1384
|
constructor(view) {
|
|
1180
1385
|
this.tasks = taskMatcher.createDeco(view);
|
|
1181
1386
|
}
|
|
@@ -1183,14 +1388,14 @@ var tasklist = (options = {}) => {
|
|
|
1183
1388
|
this.tasks = taskMatcher.updateDeco(update4, this.tasks);
|
|
1184
1389
|
}
|
|
1185
1390
|
}, {
|
|
1186
|
-
decorations: (
|
|
1187
|
-
provide: (plugin) =>
|
|
1188
|
-
return view.plugin(plugin)?.tasks ||
|
|
1391
|
+
decorations: (value) => value.tasks,
|
|
1392
|
+
provide: (plugin) => EditorView10.atomicRanges.of((view) => {
|
|
1393
|
+
return view.plugin(plugin)?.tasks || Decoration7.none;
|
|
1189
1394
|
})
|
|
1190
1395
|
});
|
|
1191
1396
|
return [
|
|
1192
1397
|
tasks,
|
|
1193
|
-
|
|
1398
|
+
styles4
|
|
1194
1399
|
];
|
|
1195
1400
|
};
|
|
1196
1401
|
|
|
@@ -1239,7 +1444,7 @@ var tooltip = ({ onHover, regexp = markdownLinkRegexp }) => hoverTooltip((view,
|
|
|
1239
1444
|
});
|
|
1240
1445
|
|
|
1241
1446
|
// packages/ui/react-ui-editor/src/components/TextEditor/themes/default.ts
|
|
1242
|
-
import
|
|
1447
|
+
import get3 from "lodash.get";
|
|
1243
1448
|
var defaultTheme = {
|
|
1244
1449
|
//
|
|
1245
1450
|
// Main layout:
|
|
@@ -1264,20 +1469,20 @@ var defaultTheme = {
|
|
|
1264
1469
|
fontSize: "16px"
|
|
1265
1470
|
},
|
|
1266
1471
|
"&light .cm-content": {
|
|
1267
|
-
color:
|
|
1472
|
+
color: get3(tokens, "extend.colors.neutral.900", "black"),
|
|
1268
1473
|
caretColor: "black"
|
|
1269
1474
|
},
|
|
1270
1475
|
"&dark .cm-content": {
|
|
1271
|
-
color:
|
|
1476
|
+
color: get3(tokens, "extend.colors.neutral.100", "white"),
|
|
1272
1477
|
caretColor: "white"
|
|
1273
1478
|
},
|
|
1274
1479
|
//
|
|
1275
1480
|
// Cursor
|
|
1276
1481
|
//
|
|
1277
|
-
"&light .cm-cursor": {
|
|
1482
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
1278
1483
|
borderLeft: "2px solid black"
|
|
1279
1484
|
},
|
|
1280
|
-
"&dark .cm-cursor": {
|
|
1485
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
1281
1486
|
borderLeft: "2px solid white"
|
|
1282
1487
|
},
|
|
1283
1488
|
"& .cm-placeholder": {
|
|
@@ -1297,16 +1502,16 @@ var defaultTheme = {
|
|
|
1297
1502
|
// selection
|
|
1298
1503
|
//
|
|
1299
1504
|
"&light .cm-selectionBackground, &light.cm-focused .cm-selectionBackground": {
|
|
1300
|
-
background:
|
|
1505
|
+
background: get3(tokens, "extend.colors.primary.150", "#00ffff")
|
|
1301
1506
|
},
|
|
1302
1507
|
"&dark .cm-selectionBackground, &dark.cm-focused .cm-selectionBackground": {
|
|
1303
|
-
background:
|
|
1508
|
+
background: get3(tokens, "extend.colors.primary.850", "#00ffff")
|
|
1304
1509
|
},
|
|
1305
1510
|
"&light .cm-selectionMatch": {
|
|
1306
|
-
background:
|
|
1511
|
+
background: get3(tokens, "extend.colors.primary.250", "#00ffff") + "44"
|
|
1307
1512
|
},
|
|
1308
1513
|
"&dark .cm-selectionMatch": {
|
|
1309
|
-
background:
|
|
1514
|
+
background: get3(tokens, "extend.colors.primary.600", "#00ffff") + "44"
|
|
1310
1515
|
},
|
|
1311
1516
|
//
|
|
1312
1517
|
// collaboration
|
|
@@ -1339,12 +1544,12 @@ var defaultTheme = {
|
|
|
1339
1544
|
// link
|
|
1340
1545
|
//
|
|
1341
1546
|
"& .cm-link": {
|
|
1342
|
-
color:
|
|
1547
|
+
color: get3(tokens, "extend.colors.primary.500"),
|
|
1343
1548
|
textDecorationLine: "underline",
|
|
1344
1549
|
textDecorationThickness: "1px",
|
|
1345
1550
|
textUnderlineOffset: "2px",
|
|
1346
1551
|
borderRadius: ".125rem",
|
|
1347
|
-
fontFamily:
|
|
1552
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1348
1553
|
},
|
|
1349
1554
|
//
|
|
1350
1555
|
// tooltip
|
|
@@ -1366,7 +1571,7 @@ var defaultTheme = {
|
|
|
1366
1571
|
display: "none"
|
|
1367
1572
|
},
|
|
1368
1573
|
"& .cm-completionLabel": {
|
|
1369
|
-
fontFamily:
|
|
1574
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1370
1575
|
},
|
|
1371
1576
|
"& .cm-completionMatchedText": {
|
|
1372
1577
|
textDecoration: "none"
|
|
@@ -1381,12 +1586,16 @@ var defaultTheme = {
|
|
|
1381
1586
|
//
|
|
1382
1587
|
// table
|
|
1383
1588
|
//
|
|
1589
|
+
"& .cm-table *": {
|
|
1590
|
+
fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
1591
|
+
textDecoration: "none !important"
|
|
1592
|
+
},
|
|
1384
1593
|
"& .cm-table-head": {
|
|
1385
1594
|
padding: "2px 16px 2px 0px",
|
|
1386
|
-
borderBottom: `1px solid ${
|
|
1595
|
+
borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
|
|
1387
1596
|
fontWeight: 100,
|
|
1388
1597
|
textAlign: "left",
|
|
1389
|
-
color:
|
|
1598
|
+
color: get3(tokens, "extend.colors.neutral.500")
|
|
1390
1599
|
},
|
|
1391
1600
|
"& .cm-table-cell": {
|
|
1392
1601
|
padding: "2px 16px 2px 0px"
|
|
@@ -1401,8 +1610,8 @@ var defaultTheme = {
|
|
|
1401
1610
|
// font size
|
|
1402
1611
|
// TODO(thure): This appears to be the best or only way to set selection caret heights, but it's far more verbose than it needs to be.
|
|
1403
1612
|
//
|
|
1404
|
-
...Object.keys(
|
|
1405
|
-
const height =
|
|
1613
|
+
...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
|
|
1614
|
+
const height = get3(tokens, [
|
|
1406
1615
|
"extend",
|
|
1407
1616
|
"fontSize",
|
|
1408
1617
|
fontSize,
|
|
@@ -1419,41 +1628,76 @@ var defaultTheme = {
|
|
|
1419
1628
|
height
|
|
1420
1629
|
};
|
|
1421
1630
|
return acc;
|
|
1422
|
-
}, {})
|
|
1631
|
+
}, {}),
|
|
1632
|
+
/**
|
|
1633
|
+
* Panels
|
|
1634
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
1635
|
+
*
|
|
1636
|
+
* Find/replace panel.
|
|
1637
|
+
* <div class="cm-announced">...</div>
|
|
1638
|
+
* <div class="cm-scroller">...</div>
|
|
1639
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
1640
|
+
* <div class="cm-search cm-panel">
|
|
1641
|
+
* <input class="cm-textfield" />
|
|
1642
|
+
* <button class="cm-button">...</button>
|
|
1643
|
+
* <label><input type="checkbox" />...</label>
|
|
1644
|
+
* </div>
|
|
1645
|
+
* </div
|
|
1646
|
+
*/
|
|
1647
|
+
"& .cm-panels": {
|
|
1648
|
+
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`,
|
|
1649
|
+
borderBottom: "none"
|
|
1650
|
+
},
|
|
1651
|
+
"& .cm-panel": {
|
|
1652
|
+
background: get3(tokens, "extend.colors.neutral.50"),
|
|
1653
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1654
|
+
},
|
|
1655
|
+
"& .cm-button": {
|
|
1656
|
+
margin: "4px",
|
|
1657
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
1658
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
1659
|
+
border: "none"
|
|
1660
|
+
},
|
|
1661
|
+
"& .cm-searchMatch": {
|
|
1662
|
+
backgroundColor: get3(tokens, "extend.colors.yellow.100")
|
|
1663
|
+
},
|
|
1664
|
+
"& .cm-searchMatch.cm-searchMatch-selected": {
|
|
1665
|
+
backgroundColor: get3(tokens, "extend.colors.primary.100")
|
|
1666
|
+
}
|
|
1423
1667
|
};
|
|
1424
1668
|
var textTheme = {
|
|
1425
1669
|
"& .cm-scroller": {
|
|
1426
|
-
fontFamily:
|
|
1670
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1427
1671
|
},
|
|
1428
1672
|
"& .cm-placeholder": {
|
|
1429
|
-
fontFamily:
|
|
1673
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1430
1674
|
}
|
|
1431
1675
|
};
|
|
1432
1676
|
var markdownTheme = {
|
|
1433
1677
|
// NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
|
|
1434
1678
|
"& .cm-placeholder": {
|
|
1435
|
-
fontFamily:
|
|
1679
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1436
1680
|
}
|
|
1437
1681
|
};
|
|
1438
1682
|
var codeTheme = {
|
|
1439
1683
|
"& .cm-scroller": {
|
|
1440
|
-
fontFamily:
|
|
1684
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
1441
1685
|
},
|
|
1442
1686
|
"& .cm-placeholder": {
|
|
1443
|
-
fontFamily:
|
|
1687
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
1444
1688
|
}
|
|
1445
1689
|
};
|
|
1446
1690
|
|
|
1447
1691
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
1448
1692
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
1449
|
-
import { EditorView as
|
|
1693
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
1450
1694
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
1451
1695
|
import { vim } from "@replit/codemirror-vim";
|
|
1452
1696
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1453
|
-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
1697
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useState } from "react";
|
|
1454
1698
|
import { generateName } from "@dxos/display-name";
|
|
1455
1699
|
import { useThemeContext } from "@dxos/react-ui";
|
|
1456
|
-
import { getColorForValue, inputSurface, mx as
|
|
1700
|
+
import { getColorForValue, inputSurface, mx as mx4 } from "@dxos/react-ui-theme";
|
|
1457
1701
|
var EditorModes = [
|
|
1458
1702
|
"default",
|
|
1459
1703
|
"vim"
|
|
@@ -1476,7 +1720,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1476
1720
|
root
|
|
1477
1721
|
]);
|
|
1478
1722
|
const { awareness, peer } = model;
|
|
1479
|
-
|
|
1723
|
+
useEffect2(() => {
|
|
1480
1724
|
if (awareness && peer) {
|
|
1481
1725
|
awareness.setLocalStateField("user", {
|
|
1482
1726
|
name: peer.name ?? generateName(peer.id),
|
|
@@ -1496,7 +1740,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1496
1740
|
peer,
|
|
1497
1741
|
themeMode
|
|
1498
1742
|
]);
|
|
1499
|
-
|
|
1743
|
+
useEffect2(() => {
|
|
1500
1744
|
if (!root) {
|
|
1501
1745
|
return;
|
|
1502
1746
|
}
|
|
@@ -1507,10 +1751,11 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1507
1751
|
// TODO(burdon): Factor out VIM mode?
|
|
1508
1752
|
editorMode === "vim" && vim(),
|
|
1509
1753
|
// Theme.
|
|
1510
|
-
|
|
1511
|
-
|
|
1754
|
+
// TODO(burdon): Make optional.
|
|
1755
|
+
EditorView11.baseTheme(defaultTheme),
|
|
1756
|
+
EditorView11.theme(slots?.editor?.theme ?? {}),
|
|
1512
1757
|
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
1513
|
-
|
|
1758
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
|
1514
1759
|
// Storage and replication.
|
|
1515
1760
|
model.extension,
|
|
1516
1761
|
// Custom.
|
|
@@ -1518,7 +1763,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1518
1763
|
].filter(Boolean)
|
|
1519
1764
|
});
|
|
1520
1765
|
view?.destroy();
|
|
1521
|
-
setView(new
|
|
1766
|
+
setView(new EditorView11({
|
|
1522
1767
|
state: state2,
|
|
1523
1768
|
parent: root
|
|
1524
1769
|
}));
|
|
@@ -1560,15 +1805,6 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1560
1805
|
onKeyUp: handleKeyUp
|
|
1561
1806
|
});
|
|
1562
1807
|
});
|
|
1563
|
-
var maybeDebug = () => {
|
|
1564
|
-
const items = localStorage.getItem("dxos.composer.demo");
|
|
1565
|
-
if (items) {
|
|
1566
|
-
return demo({
|
|
1567
|
-
items: items.split(",")
|
|
1568
|
-
});
|
|
1569
|
-
}
|
|
1570
|
-
return [];
|
|
1571
|
-
};
|
|
1572
1808
|
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1573
1809
|
const { themeMode } = useThemeContext();
|
|
1574
1810
|
const slots = defaultsDeep2({}, _slots, defaultTextSlots);
|
|
@@ -1581,7 +1817,6 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
|
|
|
1581
1817
|
themeMode,
|
|
1582
1818
|
placeholder: slots?.editor?.placeholder
|
|
1583
1819
|
}),
|
|
1584
|
-
maybeDebug(),
|
|
1585
1820
|
...extensions
|
|
1586
1821
|
],
|
|
1587
1822
|
slots,
|
|
@@ -1600,7 +1835,6 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
1600
1835
|
themeMode,
|
|
1601
1836
|
placeholder: slots?.editor?.placeholder
|
|
1602
1837
|
}),
|
|
1603
|
-
maybeDebug(),
|
|
1604
1838
|
...extensions
|
|
1605
1839
|
],
|
|
1606
1840
|
slots,
|
|
@@ -1609,7 +1843,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
1609
1843
|
});
|
|
1610
1844
|
var defaultSlots = {
|
|
1611
1845
|
root: {
|
|
1612
|
-
className:
|
|
1846
|
+
className: mx4("p-2", inputSurface)
|
|
1613
1847
|
}
|
|
1614
1848
|
};
|
|
1615
1849
|
var defaultTextSlots = {
|
|
@@ -1626,15 +1860,15 @@ var defaultMarkdownSlots = {
|
|
|
1626
1860
|
};
|
|
1627
1861
|
|
|
1628
1862
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
1629
|
-
import
|
|
1630
|
-
import { useEffect as
|
|
1863
|
+
import get4 from "lodash.get";
|
|
1864
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
1631
1865
|
import { yCollab } from "y-codemirror.next";
|
|
1632
1866
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1633
1867
|
import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
|
|
1634
1868
|
|
|
1635
1869
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
1636
|
-
import { Annotation, Facet, StateEffect, StateField as StateField6 } from "@codemirror/state";
|
|
1637
|
-
import { ViewPlugin as
|
|
1870
|
+
import { Annotation, Facet, StateEffect as StateEffect2, StateField as StateField6 } from "@codemirror/state";
|
|
1871
|
+
import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1638
1872
|
import * as automerge2 from "@dxos/automerge/automerge";
|
|
1639
1873
|
|
|
1640
1874
|
// packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
|
|
@@ -1812,7 +2046,7 @@ var PatchSemaphore = class {
|
|
|
1812
2046
|
};
|
|
1813
2047
|
|
|
1814
2048
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
1815
|
-
var effectType =
|
|
2049
|
+
var effectType = StateEffect2.define({});
|
|
1816
2050
|
var updateHeads = (newHeads) => effectType.of({
|
|
1817
2051
|
newHeads
|
|
1818
2052
|
});
|
|
@@ -1852,7 +2086,7 @@ var automergePlugin = (handle, path) => {
|
|
|
1852
2086
|
}
|
|
1853
2087
|
});
|
|
1854
2088
|
const semaphore = new PatchSemaphore(stateField);
|
|
1855
|
-
const viewPlugin =
|
|
2089
|
+
const viewPlugin = ViewPlugin4.fromClass(class AutomergeCodemirrorViewPlugin {
|
|
1856
2090
|
constructor(view) {
|
|
1857
2091
|
this._handleChange = () => {
|
|
1858
2092
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
@@ -2028,7 +2262,7 @@ var useTextModel = ({ identity, space, text }) => {
|
|
|
2028
2262
|
space,
|
|
2029
2263
|
text
|
|
2030
2264
|
}));
|
|
2031
|
-
|
|
2265
|
+
useEffect3(() => {
|
|
2032
2266
|
setModel(createModel({
|
|
2033
2267
|
identity,
|
|
2034
2268
|
space,
|
|
@@ -2055,7 +2289,7 @@ var createModel = (options) => {
|
|
|
2055
2289
|
var createYjsModel = ({ identity, space, text }) => {
|
|
2056
2290
|
invariant3(text?.doc && text?.content, void 0, {
|
|
2057
2291
|
F: __dxlog_file4,
|
|
2058
|
-
L:
|
|
2292
|
+
L: 81,
|
|
2059
2293
|
S: void 0,
|
|
2060
2294
|
A: [
|
|
2061
2295
|
"text?.doc && text?.content",
|
|
@@ -2071,6 +2305,7 @@ var createYjsModel = ({ identity, space, text }) => {
|
|
|
2071
2305
|
id: text.doc.guid,
|
|
2072
2306
|
content: text.content,
|
|
2073
2307
|
text: () => text.content.toString(),
|
|
2308
|
+
ranges: [],
|
|
2074
2309
|
extension: yCollab(text.content, provider?.awareness),
|
|
2075
2310
|
awareness: provider?.awareness,
|
|
2076
2311
|
peer: identity ? {
|
|
@@ -2087,7 +2322,8 @@ var createAutomergeModel = ({ identity, text }) => {
|
|
|
2087
2322
|
return {
|
|
2088
2323
|
id: obj.id,
|
|
2089
2324
|
content: doc,
|
|
2090
|
-
text: () =>
|
|
2325
|
+
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2326
|
+
ranges: [],
|
|
2091
2327
|
extension: automergePlugin(doc.handle, doc.path),
|
|
2092
2328
|
peer: identity ? {
|
|
2093
2329
|
id: identity.identityKey.toHex(),
|
|
@@ -2108,6 +2344,7 @@ export {
|
|
|
2108
2344
|
autocomplete,
|
|
2109
2345
|
basicBundle,
|
|
2110
2346
|
blast,
|
|
2347
|
+
code2 as code,
|
|
2111
2348
|
codeTheme,
|
|
2112
2349
|
comments,
|
|
2113
2350
|
cursorColor,
|
|
@@ -2117,13 +2354,16 @@ export {
|
|
|
2117
2354
|
defaultTextSlots,
|
|
2118
2355
|
defaultTheme,
|
|
2119
2356
|
demo,
|
|
2357
|
+
highlight,
|
|
2358
|
+
highlightDecorations,
|
|
2359
|
+
highlightStateField,
|
|
2120
2360
|
image,
|
|
2121
2361
|
link,
|
|
2122
|
-
listener,
|
|
2362
|
+
listener2 as listener,
|
|
2123
2363
|
markdownBundle,
|
|
2124
2364
|
markdownHighlightStyle,
|
|
2125
2365
|
markdownTags,
|
|
2126
|
-
|
|
2366
|
+
markdownTagsExtensions,
|
|
2127
2367
|
markdownTheme,
|
|
2128
2368
|
mention,
|
|
2129
2369
|
table,
|
|
@@ -2131,6 +2371,7 @@ export {
|
|
|
2131
2371
|
tasklist,
|
|
2132
2372
|
textTheme,
|
|
2133
2373
|
tooltip,
|
|
2374
|
+
useHighlights,
|
|
2134
2375
|
useTextModel
|
|
2135
2376
|
};
|
|
2136
2377
|
//# sourceMappingURL=index.mjs.map
|