@dxos/react-ui-editor 0.3.10-main.cbe7692 → 0.3.10-main.cc91b2d
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 -412
- 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 +35 -32
- 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, highlightActiveLine, 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,202 @@ 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
|
-
|
|
1158
|
+
drawSelection2(),
|
|
951
1159
|
highlightActiveLine(),
|
|
952
|
-
highlightActiveLineGutter(),
|
|
953
|
-
highlightSelectionMatches(),
|
|
954
|
-
highlightSpecialChars(),
|
|
955
1160
|
history(),
|
|
956
1161
|
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
|
-
]),
|
|
1162
|
+
_placeholder && placeholder2(_placeholder),
|
|
971
1163
|
// Main extension.
|
|
972
1164
|
// https://github.com/codemirror/lang-markdown
|
|
973
1165
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -982,8 +1174,8 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
982
1174
|
codeLanguages: languages,
|
|
983
1175
|
// Parser extensions.
|
|
984
1176
|
extensions: [
|
|
985
|
-
// GFM
|
|
986
|
-
|
|
1177
|
+
// GFM provided by default.
|
|
1178
|
+
markdownTagsExtensions
|
|
987
1179
|
]
|
|
988
1180
|
}),
|
|
989
1181
|
// https://github.com/codemirror/theme-one-dark
|
|
@@ -992,6 +1184,18 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
|
992
1184
|
syntaxHighlighting2(markdownHighlightStyle(readonly))
|
|
993
1185
|
].filter(Boolean);
|
|
994
1186
|
};
|
|
1187
|
+
var customKeymap = () => keymap5.of([
|
|
1188
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1189
|
+
indentWithTab,
|
|
1190
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1191
|
+
...standardKeymap,
|
|
1192
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
1193
|
+
...historyKeymap,
|
|
1194
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
1195
|
+
...closeBracketsKeymap,
|
|
1196
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
1197
|
+
...searchKeymap
|
|
1198
|
+
]);
|
|
995
1199
|
|
|
996
1200
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/mention.ts
|
|
997
1201
|
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
@@ -1019,60 +1223,62 @@ var mention = ({ onSearch }) => {
|
|
|
1019
1223
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
|
|
1020
1224
|
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1021
1225
|
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
|
|
1022
|
-
import { Decoration as
|
|
1226
|
+
import { Decoration as Decoration6, EditorView as EditorView9, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1023
1227
|
var table = (options = {}) => {
|
|
1024
1228
|
return StateField5.define({
|
|
1025
1229
|
create: (state) => update3(state, options),
|
|
1026
1230
|
update: (_, tr) => update3(tr.state, options),
|
|
1027
|
-
provide: (field) =>
|
|
1231
|
+
provide: (field) => EditorView9.decorations.from(field)
|
|
1028
1232
|
});
|
|
1029
1233
|
};
|
|
1030
1234
|
var update3 = (state, options) => {
|
|
1031
1235
|
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;
|
|
1236
|
+
const cursor = state.selection.main.head;
|
|
1237
|
+
const tables = [];
|
|
1238
|
+
const getTable = () => tables[tables.length - 1];
|
|
1239
|
+
const getRow = () => {
|
|
1240
|
+
const table2 = getTable();
|
|
1241
|
+
return table2.rows?.[table2.rows.length - 1];
|
|
1242
|
+
};
|
|
1243
|
+
syntaxTree3(state).iterate({
|
|
1244
|
+
enter: (node) => {
|
|
1245
|
+
switch (node.name) {
|
|
1246
|
+
case "Table": {
|
|
1247
|
+
tables.push({
|
|
1248
|
+
from: node.from,
|
|
1249
|
+
to: node.to
|
|
1250
|
+
});
|
|
1251
|
+
break;
|
|
1252
|
+
}
|
|
1253
|
+
case "TableHeader": {
|
|
1254
|
+
getTable().header = [];
|
|
1255
|
+
break;
|
|
1256
|
+
}
|
|
1257
|
+
case "TableRow": {
|
|
1258
|
+
(getTable().rows ??= []).push([]);
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1261
|
+
case "TableCell": {
|
|
1262
|
+
const row = getRow();
|
|
1263
|
+
if (row) {
|
|
1264
|
+
row.push(state.sliceDoc(node.from, node.to));
|
|
1265
|
+
} else {
|
|
1266
|
+
getTable().header?.push(state.sliceDoc(node.from, node.to));
|
|
1068
1267
|
}
|
|
1268
|
+
break;
|
|
1069
1269
|
}
|
|
1070
1270
|
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1273
|
+
tables.forEach((table2) => {
|
|
1274
|
+
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
1275
|
+
hide && builder.add(table2.from, table2.to, Decoration6.replace({
|
|
1073
1276
|
widget: new TableWidget(table2)
|
|
1074
|
-
}))
|
|
1075
|
-
|
|
1277
|
+
}));
|
|
1278
|
+
builder.add(table2.from, table2.to, Decoration6.mark({
|
|
1279
|
+
class: "cm-table"
|
|
1280
|
+
}));
|
|
1281
|
+
});
|
|
1076
1282
|
return builder.finish();
|
|
1077
1283
|
};
|
|
1078
1284
|
var TableWidget = class extends WidgetType4 {
|
|
@@ -1087,11 +1293,11 @@ var TableWidget = class extends WidgetType4 {
|
|
|
1087
1293
|
const table2 = document.createElement("table");
|
|
1088
1294
|
{
|
|
1089
1295
|
const header = table2.appendChild(document.createElement("thead"));
|
|
1090
|
-
const
|
|
1296
|
+
const tr = header.appendChild(document.createElement("tr"));
|
|
1091
1297
|
this._table.header?.forEach((cell) => {
|
|
1092
1298
|
const th = document.createElement("th");
|
|
1093
1299
|
th.setAttribute("class", "cm-table-head");
|
|
1094
|
-
|
|
1300
|
+
tr.appendChild(th).textContent = cell;
|
|
1095
1301
|
});
|
|
1096
1302
|
}
|
|
1097
1303
|
{
|
|
@@ -1110,7 +1316,13 @@ var TableWidget = class extends WidgetType4 {
|
|
|
1110
1316
|
};
|
|
1111
1317
|
|
|
1112
1318
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
|
|
1113
|
-
import { EditorView as
|
|
1319
|
+
import { EditorView as EditorView10, Decoration as Decoration7, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
|
|
1320
|
+
var styles4 = EditorView10.baseTheme({
|
|
1321
|
+
"& .cm-task-item": {
|
|
1322
|
+
paddingLeft: "4px",
|
|
1323
|
+
paddingRight: "8px"
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1114
1326
|
var CheckboxWidget = class extends WidgetType5 {
|
|
1115
1327
|
constructor(_pos, _checked, _indent, _onCheck) {
|
|
1116
1328
|
super();
|
|
@@ -1145,19 +1357,13 @@ var CheckboxWidget = class extends WidgetType5 {
|
|
|
1145
1357
|
return false;
|
|
1146
1358
|
}
|
|
1147
1359
|
};
|
|
1148
|
-
var styles2 = EditorView8.baseTheme({
|
|
1149
|
-
"& .cm-task-item": {
|
|
1150
|
-
paddingLeft: "4px",
|
|
1151
|
-
paddingRight: "8px"
|
|
1152
|
-
}
|
|
1153
|
-
});
|
|
1154
1360
|
var tasklist = (options = {}) => {
|
|
1155
1361
|
const taskMatcher = new MatchDecorator2({
|
|
1156
1362
|
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
1157
1363
|
decoration: (match, view, pos) => {
|
|
1158
1364
|
const indent = Math.floor(match[1].length / 2);
|
|
1159
1365
|
const checked = match[2] === "x" || match[2] === "X";
|
|
1160
|
-
return
|
|
1366
|
+
return Decoration7.replace({
|
|
1161
1367
|
widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
1162
1368
|
const idx = pos + match[0].indexOf("[") + 1;
|
|
1163
1369
|
view.dispatch({
|
|
@@ -1175,7 +1381,7 @@ var tasklist = (options = {}) => {
|
|
|
1175
1381
|
});
|
|
1176
1382
|
}
|
|
1177
1383
|
});
|
|
1178
|
-
const tasks =
|
|
1384
|
+
const tasks = ViewPlugin3.fromClass(class {
|
|
1179
1385
|
constructor(view) {
|
|
1180
1386
|
this.tasks = taskMatcher.createDeco(view);
|
|
1181
1387
|
}
|
|
@@ -1183,14 +1389,14 @@ var tasklist = (options = {}) => {
|
|
|
1183
1389
|
this.tasks = taskMatcher.updateDeco(update4, this.tasks);
|
|
1184
1390
|
}
|
|
1185
1391
|
}, {
|
|
1186
|
-
decorations: (
|
|
1187
|
-
provide: (plugin) =>
|
|
1188
|
-
return view.plugin(plugin)?.tasks ||
|
|
1392
|
+
decorations: (value) => value.tasks,
|
|
1393
|
+
provide: (plugin) => EditorView10.atomicRanges.of((view) => {
|
|
1394
|
+
return view.plugin(plugin)?.tasks || Decoration7.none;
|
|
1189
1395
|
})
|
|
1190
1396
|
});
|
|
1191
1397
|
return [
|
|
1192
1398
|
tasks,
|
|
1193
|
-
|
|
1399
|
+
styles4
|
|
1194
1400
|
];
|
|
1195
1401
|
};
|
|
1196
1402
|
|
|
@@ -1239,7 +1445,7 @@ var tooltip = ({ onHover, regexp = markdownLinkRegexp }) => hoverTooltip((view,
|
|
|
1239
1445
|
});
|
|
1240
1446
|
|
|
1241
1447
|
// packages/ui/react-ui-editor/src/components/TextEditor/themes/default.ts
|
|
1242
|
-
import
|
|
1448
|
+
import get3 from "lodash.get";
|
|
1243
1449
|
var defaultTheme = {
|
|
1244
1450
|
//
|
|
1245
1451
|
// Main layout:
|
|
@@ -1264,20 +1470,20 @@ var defaultTheme = {
|
|
|
1264
1470
|
fontSize: "16px"
|
|
1265
1471
|
},
|
|
1266
1472
|
"&light .cm-content": {
|
|
1267
|
-
color:
|
|
1473
|
+
color: get3(tokens, "extend.colors.neutral.900", "black"),
|
|
1268
1474
|
caretColor: "black"
|
|
1269
1475
|
},
|
|
1270
1476
|
"&dark .cm-content": {
|
|
1271
|
-
color:
|
|
1477
|
+
color: get3(tokens, "extend.colors.neutral.100", "white"),
|
|
1272
1478
|
caretColor: "white"
|
|
1273
1479
|
},
|
|
1274
1480
|
//
|
|
1275
1481
|
// Cursor
|
|
1276
1482
|
//
|
|
1277
|
-
"&light .cm-cursor": {
|
|
1483
|
+
"&light .cm-cursor, &light .cm-dropCursor": {
|
|
1278
1484
|
borderLeft: "2px solid black"
|
|
1279
1485
|
},
|
|
1280
|
-
"&dark .cm-cursor": {
|
|
1486
|
+
"&dark .cm-cursor, &dark .cm-dropCursor": {
|
|
1281
1487
|
borderLeft: "2px solid white"
|
|
1282
1488
|
},
|
|
1283
1489
|
"& .cm-placeholder": {
|
|
@@ -1297,16 +1503,16 @@ var defaultTheme = {
|
|
|
1297
1503
|
// selection
|
|
1298
1504
|
//
|
|
1299
1505
|
"&light .cm-selectionBackground, &light.cm-focused .cm-selectionBackground": {
|
|
1300
|
-
background:
|
|
1506
|
+
background: get3(tokens, "extend.colors.primary.150", "#00ffff")
|
|
1301
1507
|
},
|
|
1302
1508
|
"&dark .cm-selectionBackground, &dark.cm-focused .cm-selectionBackground": {
|
|
1303
|
-
background:
|
|
1509
|
+
background: get3(tokens, "extend.colors.primary.850", "#00ffff")
|
|
1304
1510
|
},
|
|
1305
1511
|
"&light .cm-selectionMatch": {
|
|
1306
|
-
background:
|
|
1512
|
+
background: get3(tokens, "extend.colors.primary.250", "#00ffff") + "44"
|
|
1307
1513
|
},
|
|
1308
1514
|
"&dark .cm-selectionMatch": {
|
|
1309
|
-
background:
|
|
1515
|
+
background: get3(tokens, "extend.colors.primary.600", "#00ffff") + "44"
|
|
1310
1516
|
},
|
|
1311
1517
|
//
|
|
1312
1518
|
// collaboration
|
|
@@ -1339,12 +1545,12 @@ var defaultTheme = {
|
|
|
1339
1545
|
// link
|
|
1340
1546
|
//
|
|
1341
1547
|
"& .cm-link": {
|
|
1342
|
-
color:
|
|
1548
|
+
color: get3(tokens, "extend.colors.primary.500"),
|
|
1343
1549
|
textDecorationLine: "underline",
|
|
1344
1550
|
textDecorationThickness: "1px",
|
|
1345
1551
|
textUnderlineOffset: "2px",
|
|
1346
1552
|
borderRadius: ".125rem",
|
|
1347
|
-
fontFamily:
|
|
1553
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1348
1554
|
},
|
|
1349
1555
|
//
|
|
1350
1556
|
// tooltip
|
|
@@ -1366,7 +1572,7 @@ var defaultTheme = {
|
|
|
1366
1572
|
display: "none"
|
|
1367
1573
|
},
|
|
1368
1574
|
"& .cm-completionLabel": {
|
|
1369
|
-
fontFamily:
|
|
1575
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1370
1576
|
},
|
|
1371
1577
|
"& .cm-completionMatchedText": {
|
|
1372
1578
|
textDecoration: "none"
|
|
@@ -1381,12 +1587,16 @@ var defaultTheme = {
|
|
|
1381
1587
|
//
|
|
1382
1588
|
// table
|
|
1383
1589
|
//
|
|
1590
|
+
"& .cm-table *": {
|
|
1591
|
+
fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
|
|
1592
|
+
textDecoration: "none !important"
|
|
1593
|
+
},
|
|
1384
1594
|
"& .cm-table-head": {
|
|
1385
1595
|
padding: "2px 16px 2px 0px",
|
|
1386
|
-
borderBottom: `1px solid ${
|
|
1596
|
+
borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
|
|
1387
1597
|
fontWeight: 100,
|
|
1388
1598
|
textAlign: "left",
|
|
1389
|
-
color:
|
|
1599
|
+
color: get3(tokens, "extend.colors.neutral.500")
|
|
1390
1600
|
},
|
|
1391
1601
|
"& .cm-table-cell": {
|
|
1392
1602
|
padding: "2px 16px 2px 0px"
|
|
@@ -1401,8 +1611,8 @@ var defaultTheme = {
|
|
|
1401
1611
|
// font size
|
|
1402
1612
|
// 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
1613
|
//
|
|
1404
|
-
...Object.keys(
|
|
1405
|
-
const height =
|
|
1614
|
+
...Object.keys(get3(tokens, "extend.fontSize", {})).reduce((acc, fontSize) => {
|
|
1615
|
+
const height = get3(tokens, [
|
|
1406
1616
|
"extend",
|
|
1407
1617
|
"fontSize",
|
|
1408
1618
|
fontSize,
|
|
@@ -1419,41 +1629,76 @@ var defaultTheme = {
|
|
|
1419
1629
|
height
|
|
1420
1630
|
};
|
|
1421
1631
|
return acc;
|
|
1422
|
-
}, {})
|
|
1632
|
+
}, {}),
|
|
1633
|
+
/**
|
|
1634
|
+
* Panels
|
|
1635
|
+
* https://github.com/codemirror/search/blob/main/src/search.ts#L745
|
|
1636
|
+
*
|
|
1637
|
+
* Find/replace panel.
|
|
1638
|
+
* <div class="cm-announced">...</div>
|
|
1639
|
+
* <div class="cm-scroller">...</div>
|
|
1640
|
+
* <div class="cm-panels cm-panels-bottom">
|
|
1641
|
+
* <div class="cm-search cm-panel">
|
|
1642
|
+
* <input class="cm-textfield" />
|
|
1643
|
+
* <button class="cm-button">...</button>
|
|
1644
|
+
* <label><input type="checkbox" />...</label>
|
|
1645
|
+
* </div>
|
|
1646
|
+
* </div
|
|
1647
|
+
*/
|
|
1648
|
+
"& .cm-panels": {
|
|
1649
|
+
border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`,
|
|
1650
|
+
borderBottom: "none"
|
|
1651
|
+
},
|
|
1652
|
+
"& .cm-panel": {
|
|
1653
|
+
background: get3(tokens, "extend.colors.neutral.50"),
|
|
1654
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1655
|
+
},
|
|
1656
|
+
"& .cm-button": {
|
|
1657
|
+
margin: "4px",
|
|
1658
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(","),
|
|
1659
|
+
background: get3(tokens, "extend.colors.neutral.100"),
|
|
1660
|
+
border: "none"
|
|
1661
|
+
},
|
|
1662
|
+
"& .cm-searchMatch": {
|
|
1663
|
+
backgroundColor: get3(tokens, "extend.colors.yellow.100")
|
|
1664
|
+
},
|
|
1665
|
+
"& .cm-searchMatch.cm-searchMatch-selected": {
|
|
1666
|
+
backgroundColor: get3(tokens, "extend.colors.primary.100")
|
|
1667
|
+
}
|
|
1423
1668
|
};
|
|
1424
1669
|
var textTheme = {
|
|
1425
1670
|
"& .cm-scroller": {
|
|
1426
|
-
fontFamily:
|
|
1671
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1427
1672
|
},
|
|
1428
1673
|
"& .cm-placeholder": {
|
|
1429
|
-
fontFamily:
|
|
1674
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1430
1675
|
}
|
|
1431
1676
|
};
|
|
1432
1677
|
var markdownTheme = {
|
|
1433
1678
|
// NOTE: Must leave base font family as is (i.e., monospace) due to fenced code blocks.
|
|
1434
1679
|
"& .cm-placeholder": {
|
|
1435
|
-
fontFamily:
|
|
1680
|
+
fontFamily: get3(tokens, "fontFamily.body", []).join(",")
|
|
1436
1681
|
}
|
|
1437
1682
|
};
|
|
1438
1683
|
var codeTheme = {
|
|
1439
1684
|
"& .cm-scroller": {
|
|
1440
|
-
fontFamily:
|
|
1685
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
1441
1686
|
},
|
|
1442
1687
|
"& .cm-placeholder": {
|
|
1443
|
-
fontFamily:
|
|
1688
|
+
fontFamily: get3(tokens, "fontFamily.mono", []).join(",")
|
|
1444
1689
|
}
|
|
1445
1690
|
};
|
|
1446
1691
|
|
|
1447
1692
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
1448
1693
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
1449
|
-
import { EditorView as
|
|
1694
|
+
import { EditorView as EditorView11 } from "@codemirror/view";
|
|
1450
1695
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
1451
1696
|
import { vim } from "@replit/codemirror-vim";
|
|
1452
1697
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
1453
|
-
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
1698
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useState } from "react";
|
|
1454
1699
|
import { generateName } from "@dxos/display-name";
|
|
1455
1700
|
import { useThemeContext } from "@dxos/react-ui";
|
|
1456
|
-
import { getColorForValue, inputSurface, mx as
|
|
1701
|
+
import { getColorForValue, inputSurface, mx as mx4 } from "@dxos/react-ui-theme";
|
|
1457
1702
|
var EditorModes = [
|
|
1458
1703
|
"default",
|
|
1459
1704
|
"vim"
|
|
@@ -1476,7 +1721,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1476
1721
|
root
|
|
1477
1722
|
]);
|
|
1478
1723
|
const { awareness, peer } = model;
|
|
1479
|
-
|
|
1724
|
+
useEffect2(() => {
|
|
1480
1725
|
if (awareness && peer) {
|
|
1481
1726
|
awareness.setLocalStateField("user", {
|
|
1482
1727
|
name: peer.name ?? generateName(peer.id),
|
|
@@ -1496,7 +1741,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1496
1741
|
peer,
|
|
1497
1742
|
themeMode
|
|
1498
1743
|
]);
|
|
1499
|
-
|
|
1744
|
+
useEffect2(() => {
|
|
1500
1745
|
if (!root) {
|
|
1501
1746
|
return;
|
|
1502
1747
|
}
|
|
@@ -1507,10 +1752,11 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1507
1752
|
// TODO(burdon): Factor out VIM mode?
|
|
1508
1753
|
editorMode === "vim" && vim(),
|
|
1509
1754
|
// Theme.
|
|
1510
|
-
|
|
1511
|
-
|
|
1755
|
+
// TODO(burdon): Make optional.
|
|
1756
|
+
EditorView11.baseTheme(defaultTheme),
|
|
1757
|
+
EditorView11.theme(slots?.editor?.theme ?? {}),
|
|
1512
1758
|
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
1513
|
-
|
|
1759
|
+
EditorView11.darkTheme.of(themeMode === "dark"),
|
|
1514
1760
|
// Storage and replication.
|
|
1515
1761
|
model.extension,
|
|
1516
1762
|
// Custom.
|
|
@@ -1518,7 +1764,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1518
1764
|
].filter(Boolean)
|
|
1519
1765
|
});
|
|
1520
1766
|
view?.destroy();
|
|
1521
|
-
setView(new
|
|
1767
|
+
setView(new EditorView11({
|
|
1522
1768
|
state: state2,
|
|
1523
1769
|
parent: root
|
|
1524
1770
|
}));
|
|
@@ -1560,15 +1806,6 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode,
|
|
|
1560
1806
|
onKeyUp: handleKeyUp
|
|
1561
1807
|
});
|
|
1562
1808
|
});
|
|
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
1809
|
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1573
1810
|
const { themeMode } = useThemeContext();
|
|
1574
1811
|
const slots = defaultsDeep2({}, _slots, defaultTextSlots);
|
|
@@ -1581,7 +1818,6 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
|
|
|
1581
1818
|
themeMode,
|
|
1582
1819
|
placeholder: slots?.editor?.placeholder
|
|
1583
1820
|
}),
|
|
1584
|
-
maybeDebug(),
|
|
1585
1821
|
...extensions
|
|
1586
1822
|
],
|
|
1587
1823
|
slots,
|
|
@@ -1600,7 +1836,6 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
1600
1836
|
themeMode,
|
|
1601
1837
|
placeholder: slots?.editor?.placeholder
|
|
1602
1838
|
}),
|
|
1603
|
-
maybeDebug(),
|
|
1604
1839
|
...extensions
|
|
1605
1840
|
],
|
|
1606
1841
|
slots,
|
|
@@ -1609,7 +1844,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
|
|
|
1609
1844
|
});
|
|
1610
1845
|
var defaultSlots = {
|
|
1611
1846
|
root: {
|
|
1612
|
-
className:
|
|
1847
|
+
className: mx4("p-2", inputSurface)
|
|
1613
1848
|
}
|
|
1614
1849
|
};
|
|
1615
1850
|
var defaultTextSlots = {
|
|
@@ -1626,15 +1861,15 @@ var defaultMarkdownSlots = {
|
|
|
1626
1861
|
};
|
|
1627
1862
|
|
|
1628
1863
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
1629
|
-
import
|
|
1630
|
-
import { useEffect as
|
|
1864
|
+
import get4 from "lodash.get";
|
|
1865
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
1631
1866
|
import { yCollab } from "y-codemirror.next";
|
|
1632
1867
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1633
1868
|
import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
|
|
1634
1869
|
|
|
1635
1870
|
// 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
|
|
1871
|
+
import { Annotation, Facet, StateEffect as StateEffect2, StateField as StateField6 } from "@codemirror/state";
|
|
1872
|
+
import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
|
|
1638
1873
|
import * as automerge2 from "@dxos/automerge/automerge";
|
|
1639
1874
|
|
|
1640
1875
|
// packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
|
|
@@ -1812,7 +2047,7 @@ var PatchSemaphore = class {
|
|
|
1812
2047
|
};
|
|
1813
2048
|
|
|
1814
2049
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
1815
|
-
var effectType =
|
|
2050
|
+
var effectType = StateEffect2.define({});
|
|
1816
2051
|
var updateHeads = (newHeads) => effectType.of({
|
|
1817
2052
|
newHeads
|
|
1818
2053
|
});
|
|
@@ -1852,7 +2087,7 @@ var automergePlugin = (handle, path) => {
|
|
|
1852
2087
|
}
|
|
1853
2088
|
});
|
|
1854
2089
|
const semaphore = new PatchSemaphore(stateField);
|
|
1855
|
-
const viewPlugin =
|
|
2090
|
+
const viewPlugin = ViewPlugin4.fromClass(class AutomergeCodemirrorViewPlugin {
|
|
1856
2091
|
constructor(view) {
|
|
1857
2092
|
this._handleChange = () => {
|
|
1858
2093
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
@@ -2028,7 +2263,7 @@ var useTextModel = ({ identity, space, text }) => {
|
|
|
2028
2263
|
space,
|
|
2029
2264
|
text
|
|
2030
2265
|
}));
|
|
2031
|
-
|
|
2266
|
+
useEffect3(() => {
|
|
2032
2267
|
setModel(createModel({
|
|
2033
2268
|
identity,
|
|
2034
2269
|
space,
|
|
@@ -2055,7 +2290,7 @@ var createModel = (options) => {
|
|
|
2055
2290
|
var createYjsModel = ({ identity, space, text }) => {
|
|
2056
2291
|
invariant3(text?.doc && text?.content, void 0, {
|
|
2057
2292
|
F: __dxlog_file4,
|
|
2058
|
-
L:
|
|
2293
|
+
L: 81,
|
|
2059
2294
|
S: void 0,
|
|
2060
2295
|
A: [
|
|
2061
2296
|
"text?.doc && text?.content",
|
|
@@ -2071,6 +2306,7 @@ var createYjsModel = ({ identity, space, text }) => {
|
|
|
2071
2306
|
id: text.doc.guid,
|
|
2072
2307
|
content: text.content,
|
|
2073
2308
|
text: () => text.content.toString(),
|
|
2309
|
+
ranges: [],
|
|
2074
2310
|
extension: yCollab(text.content, provider?.awareness),
|
|
2075
2311
|
awareness: provider?.awareness,
|
|
2076
2312
|
peer: identity ? {
|
|
@@ -2087,7 +2323,8 @@ var createAutomergeModel = ({ identity, text }) => {
|
|
|
2087
2323
|
return {
|
|
2088
2324
|
id: obj.id,
|
|
2089
2325
|
content: doc,
|
|
2090
|
-
text: () =>
|
|
2326
|
+
text: () => get4(doc.handle.docSync(), doc.path),
|
|
2327
|
+
ranges: [],
|
|
2091
2328
|
extension: automergePlugin(doc.handle, doc.path),
|
|
2092
2329
|
peer: identity ? {
|
|
2093
2330
|
id: identity.identityKey.toHex(),
|
|
@@ -2108,6 +2345,7 @@ export {
|
|
|
2108
2345
|
autocomplete,
|
|
2109
2346
|
basicBundle,
|
|
2110
2347
|
blast,
|
|
2348
|
+
code2 as code,
|
|
2111
2349
|
codeTheme,
|
|
2112
2350
|
comments,
|
|
2113
2351
|
cursorColor,
|
|
@@ -2117,13 +2355,16 @@ export {
|
|
|
2117
2355
|
defaultTextSlots,
|
|
2118
2356
|
defaultTheme,
|
|
2119
2357
|
demo,
|
|
2358
|
+
highlight,
|
|
2359
|
+
highlightDecorations,
|
|
2360
|
+
highlightStateField,
|
|
2120
2361
|
image,
|
|
2121
2362
|
link,
|
|
2122
|
-
listener,
|
|
2363
|
+
listener2 as listener,
|
|
2123
2364
|
markdownBundle,
|
|
2124
2365
|
markdownHighlightStyle,
|
|
2125
2366
|
markdownTags,
|
|
2126
|
-
|
|
2367
|
+
markdownTagsExtensions,
|
|
2127
2368
|
markdownTheme,
|
|
2128
2369
|
mention,
|
|
2129
2370
|
table,
|
|
@@ -2131,6 +2372,7 @@ export {
|
|
|
2131
2372
|
tasklist,
|
|
2132
2373
|
textTheme,
|
|
2133
2374
|
tooltip,
|
|
2375
|
+
useHighlights,
|
|
2134
2376
|
useTextModel
|
|
2135
2377
|
};
|
|
2136
2378
|
//# sourceMappingURL=index.mjs.map
|