@dxos/react-ui-editor 0.3.10-main.90b298e → 0.3.10-main.92d1f2c
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 +897 -293
- 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 +19 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts +25 -0
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +1 -1
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/demo.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/image.d.ts +4 -0
- package/dist/types/src/components/TextEditor/extensions/image.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +4 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +2 -1
- 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 +9 -3
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/mention.d.ts +6 -0
- package/dist/types/src/components/TextEditor/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts +8 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/themes/default.d.ts +5 -0
- package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts +8 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor → hooks/yjs}/yjs.stories.d.ts +1 -1
- package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +1 -0
- package/dist/types/src/styles/markdown.d.ts +3 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +102 -27
- package/src/components/TextEditor/TextEditor.tsx +13 -23
- package/src/components/TextEditor/extensions/autocomplete.ts +5 -20
- package/src/components/TextEditor/extensions/basic.ts +2 -1
- package/src/components/TextEditor/extensions/blast.ts +387 -0
- package/src/components/TextEditor/extensions/comments.ts +21 -39
- package/src/components/TextEditor/extensions/demo.ts +4 -1
- package/src/components/TextEditor/extensions/experimental.tsx +14 -35
- package/src/components/TextEditor/extensions/image.ts +67 -0
- package/src/components/TextEditor/extensions/index.ts +4 -0
- package/src/components/TextEditor/extensions/link.ts +17 -25
- package/src/components/TextEditor/extensions/listener.ts +3 -3
- package/src/components/TextEditor/extensions/markdown/bundle.ts +30 -19
- package/src/components/TextEditor/extensions/markdown/highlight.ts +147 -108
- package/src/components/TextEditor/extensions/mention.ts +31 -0
- package/src/components/TextEditor/extensions/table.ts +122 -0
- package/src/components/TextEditor/extensions/tasklist.ts +41 -27
- package/src/components/TextEditor/themes/default.ts +54 -2
- package/src/hooks/automerge/automerge.stories.tsx +3 -2
- package/src/{components/TextEditor → hooks/yjs}/yjs.stories.tsx +1 -1
- package/src/styles/markdown.ts +14 -8
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
|
@@ -24,13 +24,13 @@ var autocomplete = ({ onSearch }) => {
|
|
|
24
24
|
// TODO(burdon): Optional decoration via addToOptions
|
|
25
25
|
override: [
|
|
26
26
|
(context) => {
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
27
|
+
const match = context.matchBefore(/\w*/);
|
|
28
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
29
29
|
return null;
|
|
30
30
|
}
|
|
31
31
|
return {
|
|
32
|
-
from:
|
|
33
|
-
options: onSearch(
|
|
32
|
+
from: match.from,
|
|
33
|
+
options: onSearch(match.text.toLowerCase())
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
]
|
|
@@ -43,7 +43,7 @@ import { closeBrackets } from "@codemirror/autocomplete";
|
|
|
43
43
|
import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
44
44
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
|
|
45
45
|
import { EditorView, placeholder } from "@codemirror/view";
|
|
46
|
-
var basicBundle = ({ themeMode, placeholder: _placeholder }) => [
|
|
46
|
+
var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
|
|
47
47
|
// TODO(burdon): Compare with minimalSetup.
|
|
48
48
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|
|
49
49
|
bracketMatching(),
|
|
@@ -54,8 +54,333 @@ var basicBundle = ({ themeMode, placeholder: _placeholder }) => [
|
|
|
54
54
|
themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
|
|
55
55
|
].filter(Boolean);
|
|
56
56
|
|
|
57
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts
|
|
58
|
+
import { StateField } from "@codemirror/state";
|
|
59
|
+
import { EditorView as EditorView2, keymap as keymap2 } from "@codemirror/view";
|
|
60
|
+
import defaultsDeep from "lodash.defaultsdeep";
|
|
61
|
+
import { invariant } from "@dxos/invariant";
|
|
62
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts";
|
|
63
|
+
var defaultOptions = {
|
|
64
|
+
effect: 2,
|
|
65
|
+
maxParticles: 200,
|
|
66
|
+
particleGravity: 0.08,
|
|
67
|
+
particleAlphaFadeout: 0.996,
|
|
68
|
+
particleSize: {
|
|
69
|
+
min: 2,
|
|
70
|
+
max: 8
|
|
71
|
+
},
|
|
72
|
+
particleNumRange: {
|
|
73
|
+
min: 5,
|
|
74
|
+
max: 10
|
|
75
|
+
},
|
|
76
|
+
particleVelocityRange: {
|
|
77
|
+
x: [
|
|
78
|
+
-1,
|
|
79
|
+
1
|
|
80
|
+
],
|
|
81
|
+
y: [
|
|
82
|
+
-3.5,
|
|
83
|
+
-1.5
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
particleShrinkRate: 0.95,
|
|
87
|
+
shakeIntensity: 5
|
|
88
|
+
};
|
|
89
|
+
var blast = (options) => {
|
|
90
|
+
let blaster;
|
|
91
|
+
let last = 0;
|
|
92
|
+
const getPoint = (view, pos) => {
|
|
93
|
+
const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
|
|
94
|
+
const element = document.elementFromPoint(x, y);
|
|
95
|
+
const { offsetLeft: left = 0, offsetTop: top = 0 } = view.scrollDOM.parentElement ?? {};
|
|
96
|
+
const point = {
|
|
97
|
+
x: x - left,
|
|
98
|
+
y: y - top
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
element,
|
|
102
|
+
point
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
return [
|
|
106
|
+
// Cursor moved.
|
|
107
|
+
EditorView2.updateListener.of((update4) => {
|
|
108
|
+
if (blaster?.node !== update4.view.scrollDOM) {
|
|
109
|
+
if (blaster) {
|
|
110
|
+
blaster.destroy();
|
|
111
|
+
}
|
|
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));
|
|
121
|
+
blaster.initialize();
|
|
122
|
+
blaster.start();
|
|
123
|
+
} else {
|
|
124
|
+
blaster.resize();
|
|
125
|
+
}
|
|
126
|
+
const current = update4.view.state.selection.main.head;
|
|
127
|
+
if (current !== last) {
|
|
128
|
+
last = current;
|
|
129
|
+
const { element, point } = getPoint(update4.view, current);
|
|
130
|
+
if (element && point) {
|
|
131
|
+
blaster.spawn({
|
|
132
|
+
element,
|
|
133
|
+
point
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}),
|
|
138
|
+
// Document changed.
|
|
139
|
+
StateField.define({
|
|
140
|
+
create: () => null,
|
|
141
|
+
update: (_value, transaction) => {
|
|
142
|
+
if (blaster && transaction.docChanged) {
|
|
143
|
+
const view = EditorView2.findFromDOM(blaster.node);
|
|
144
|
+
const { element, point } = getPoint(view, transaction.selection.main.head);
|
|
145
|
+
if (element && point) {
|
|
146
|
+
blaster.spawn({
|
|
147
|
+
element,
|
|
148
|
+
point
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}),
|
|
155
|
+
keymap2.of([
|
|
156
|
+
{
|
|
157
|
+
any: (view, event) => {
|
|
158
|
+
if (blaster && event.key === "Enter" && event.shiftKey) {
|
|
159
|
+
blaster.shake({
|
|
160
|
+
time: 0.4
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
])
|
|
167
|
+
];
|
|
168
|
+
};
|
|
169
|
+
var Blaster = class {
|
|
170
|
+
constructor(_node, _options) {
|
|
171
|
+
this._node = _node;
|
|
172
|
+
this._options = _options;
|
|
173
|
+
this._running = false;
|
|
174
|
+
this._shakeTime = 0;
|
|
175
|
+
this._shakeTimeMax = 0;
|
|
176
|
+
this._particles = [];
|
|
177
|
+
this._particlePointer = 0;
|
|
178
|
+
this._lastPoint = {
|
|
179
|
+
x: 0,
|
|
180
|
+
y: 0
|
|
181
|
+
};
|
|
182
|
+
this.shake = throttle(({ time }) => {
|
|
183
|
+
this._shakeTime = this._shakeTimeMax;
|
|
184
|
+
this._shakeTimeMax = time;
|
|
185
|
+
}, 100);
|
|
186
|
+
this.spawn = throttle(({ element, point }) => {
|
|
187
|
+
const color = getRGBComponents(element, this._options.color);
|
|
188
|
+
const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
|
|
189
|
+
const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
|
|
190
|
+
this._lastPoint = point;
|
|
191
|
+
for (let i = numParticles; i--; i > 0) {
|
|
192
|
+
this._particles[this._particlePointer] = this._effect.create(point.x - dir * 16, point.y, color);
|
|
193
|
+
this._particlePointer = (this._particlePointer + 1) % this._options.maxParticles;
|
|
194
|
+
}
|
|
195
|
+
}, 100);
|
|
196
|
+
this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);
|
|
197
|
+
}
|
|
198
|
+
get node() {
|
|
199
|
+
return this._node;
|
|
200
|
+
}
|
|
201
|
+
initialize() {
|
|
202
|
+
invariant(!this._canvas && !this._ctx, void 0, {
|
|
203
|
+
F: __dxlog_file,
|
|
204
|
+
L: 152,
|
|
205
|
+
S: this,
|
|
206
|
+
A: [
|
|
207
|
+
"!this._canvas && !this._ctx",
|
|
208
|
+
""
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
this._canvas = document.createElement("canvas");
|
|
212
|
+
this._canvas.id = "code-blast-canvas";
|
|
213
|
+
this._canvas.style.position = "absolute";
|
|
214
|
+
this._canvas.style.zIndex = "0";
|
|
215
|
+
this._canvas.style.pointerEvents = "none";
|
|
216
|
+
this._ctx = this._canvas.getContext("2d");
|
|
217
|
+
const parent = this._node.parentElement?.parentElement;
|
|
218
|
+
parent?.appendChild(this._canvas);
|
|
219
|
+
this.resize();
|
|
220
|
+
}
|
|
221
|
+
destroy() {
|
|
222
|
+
this.stop();
|
|
223
|
+
if (this._canvas) {
|
|
224
|
+
this._canvas.remove();
|
|
225
|
+
this._canvas = void 0;
|
|
226
|
+
this._ctx = void 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
resize() {
|
|
230
|
+
if (this._node.parentElement && this._canvas) {
|
|
231
|
+
const { offsetLeft: x, offsetTop: y, offsetWidth: width, offsetHeight: height } = this._node.parentElement;
|
|
232
|
+
this._canvas.style.top = `${y}px`;
|
|
233
|
+
this._canvas.style.left = `${x}px`;
|
|
234
|
+
this._canvas.width = width;
|
|
235
|
+
this._canvas.height = height;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
start() {
|
|
239
|
+
invariant(this._canvas && this._ctx, void 0, {
|
|
240
|
+
F: __dxlog_file,
|
|
241
|
+
L: 191,
|
|
242
|
+
S: this,
|
|
243
|
+
A: [
|
|
244
|
+
"this._canvas && this._ctx",
|
|
245
|
+
""
|
|
246
|
+
]
|
|
247
|
+
});
|
|
248
|
+
this._running = true;
|
|
249
|
+
this.loop();
|
|
250
|
+
}
|
|
251
|
+
stop() {
|
|
252
|
+
this._running = false;
|
|
253
|
+
this._node.style.transform = "translate(0px, 0px)";
|
|
254
|
+
}
|
|
255
|
+
loop() {
|
|
256
|
+
if (!this._running || !this._canvas || !this._ctx) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this._ctx.clearRect(0, 0, this._canvas.width ?? 0, this._canvas.height ?? 0);
|
|
260
|
+
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
261
|
+
this._lastTime ??= now;
|
|
262
|
+
const dt = (now - this._lastTime) / 1e3;
|
|
263
|
+
this._lastTime = now;
|
|
264
|
+
if (this._shakeTime > 0) {
|
|
265
|
+
this._shakeTime -= dt;
|
|
266
|
+
const magnitude = this._shakeTime / this._shakeTimeMax * this._options.shakeIntensity;
|
|
267
|
+
const shakeX = random(-magnitude, magnitude);
|
|
268
|
+
const shakeY = random(-magnitude, magnitude);
|
|
269
|
+
this._node.style.transform = `translate(${shakeX}px,${shakeY}px)`;
|
|
270
|
+
}
|
|
271
|
+
this.drawParticles();
|
|
272
|
+
requestAnimationFrame(this.loop.bind(this));
|
|
273
|
+
}
|
|
274
|
+
drawParticles() {
|
|
275
|
+
for (let i = this._particles.length; i--; i > 0) {
|
|
276
|
+
const particle = this._particles[i];
|
|
277
|
+
if (!particle) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (particle.alpha < 0.01 || particle.size <= 0.5) {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
this._effect.update(this._ctx, particle);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
var Effect = class {
|
|
288
|
+
constructor(_options) {
|
|
289
|
+
this._options = _options;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
var Effect1 = class extends Effect {
|
|
293
|
+
create(x, y, color) {
|
|
294
|
+
return {
|
|
295
|
+
x,
|
|
296
|
+
y: y + 10,
|
|
297
|
+
vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),
|
|
298
|
+
vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),
|
|
299
|
+
size: random(this._options.particleSize.min, this._options.particleSize.max),
|
|
300
|
+
color,
|
|
301
|
+
alpha: 1
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
update(ctx, particle) {
|
|
305
|
+
particle.vy += this._options.particleGravity;
|
|
306
|
+
particle.x += particle.vx;
|
|
307
|
+
particle.y += particle.vy;
|
|
308
|
+
particle.alpha *= this._options.particleAlphaFadeout;
|
|
309
|
+
ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;
|
|
310
|
+
ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
var Effect2 = class extends Effect {
|
|
314
|
+
create(x, y, color) {
|
|
315
|
+
return {
|
|
316
|
+
x,
|
|
317
|
+
y: y + 10,
|
|
318
|
+
vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),
|
|
319
|
+
vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),
|
|
320
|
+
size: random(this._options.particleSize.min, this._options.particleSize.max),
|
|
321
|
+
color,
|
|
322
|
+
alpha: 1,
|
|
323
|
+
theta: random(0, 360) * Math.PI / 180,
|
|
324
|
+
drag: 0.92,
|
|
325
|
+
wander: 0.15
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
update(ctx, particle) {
|
|
329
|
+
particle.vy += this._options.particleGravity;
|
|
330
|
+
particle.x += particle.vx;
|
|
331
|
+
particle.y += particle.vy;
|
|
332
|
+
particle.vx *= particle.drag;
|
|
333
|
+
particle.vy *= particle.drag;
|
|
334
|
+
particle.theta += random(-0.5, 0.5);
|
|
335
|
+
particle.vx += Math.sin(particle.theta) * 0.1;
|
|
336
|
+
particle.vy += Math.cos(particle.theta) * 0.1;
|
|
337
|
+
particle.size *= this._options.particleShrinkRate;
|
|
338
|
+
particle.alpha *= this._options.particleAlphaFadeout;
|
|
339
|
+
ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;
|
|
340
|
+
ctx.beginPath();
|
|
341
|
+
ctx.arc(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, 0, 2 * Math.PI);
|
|
342
|
+
ctx.fill();
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
function throttle(callback, limit) {
|
|
346
|
+
let wait = false;
|
|
347
|
+
return function(...args) {
|
|
348
|
+
if (!wait) {
|
|
349
|
+
callback.apply(this, args);
|
|
350
|
+
wait = true;
|
|
351
|
+
setTimeout(() => {
|
|
352
|
+
wait = false;
|
|
353
|
+
}, limit);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
var getRGBComponents = (node, color) => {
|
|
358
|
+
if (typeof color === "function") {
|
|
359
|
+
return color();
|
|
360
|
+
}
|
|
361
|
+
const bgColor = getComputedStyle(node).color;
|
|
362
|
+
if (bgColor) {
|
|
363
|
+
const x = bgColor.match(/(\d+), (\d+), (\d+)/)?.slice(1);
|
|
364
|
+
if (x) {
|
|
365
|
+
return x;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return [
|
|
369
|
+
50,
|
|
370
|
+
50,
|
|
371
|
+
50
|
|
372
|
+
];
|
|
373
|
+
};
|
|
374
|
+
var random = (min, max) => {
|
|
375
|
+
if (!max) {
|
|
376
|
+
max = min;
|
|
377
|
+
min = 0;
|
|
378
|
+
}
|
|
379
|
+
return min + ~~(Math.random() * (max - min + 1));
|
|
380
|
+
};
|
|
381
|
+
|
|
57
382
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/demo.ts
|
|
58
|
-
import { keymap as
|
|
383
|
+
import { keymap as keymap3 } from "@codemirror/view";
|
|
59
384
|
var defaultItems = [
|
|
60
385
|
"hello world!",
|
|
61
386
|
"this is a test.",
|
|
@@ -65,7 +390,7 @@ var demo = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
65
390
|
let t;
|
|
66
391
|
let idx = 0;
|
|
67
392
|
return [
|
|
68
|
-
|
|
393
|
+
keymap3.of([
|
|
69
394
|
{
|
|
70
395
|
// Reset.
|
|
71
396
|
key: "alt-meta-'",
|
|
@@ -112,18 +437,30 @@ var demo = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
112
437
|
};
|
|
113
438
|
|
|
114
439
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
|
|
115
|
-
import { keymap as
|
|
440
|
+
import { keymap as keymap4, Decoration, EditorView as EditorView3, MatchDecorator, ViewPlugin, WidgetType } from "@codemirror/view";
|
|
116
441
|
import { debounce } from "@dxos/async";
|
|
117
|
-
import { invariant } from "@dxos/invariant";
|
|
118
|
-
var
|
|
442
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
443
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
|
|
444
|
+
var styles = EditorView3.baseTheme({
|
|
445
|
+
"& .cm-bookmark": {
|
|
446
|
+
cursor: "pointer",
|
|
447
|
+
margin: "4px",
|
|
448
|
+
padding: "4px",
|
|
449
|
+
backgroundColor: "yellow"
|
|
450
|
+
},
|
|
451
|
+
"& .cm-bookmark-selected": {
|
|
452
|
+
backgroundColor: "orange"
|
|
453
|
+
}
|
|
454
|
+
});
|
|
119
455
|
var BookmarkWidget = class extends WidgetType {
|
|
120
|
-
constructor(_pos, _id) {
|
|
456
|
+
constructor(_pos, _id, _handleClick) {
|
|
121
457
|
super();
|
|
122
458
|
this._pos = _pos;
|
|
123
459
|
this._id = _id;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
460
|
+
this._handleClick = _handleClick;
|
|
461
|
+
invariant2(this._id, void 0, {
|
|
462
|
+
F: __dxlog_file2,
|
|
463
|
+
L: 37,
|
|
127
464
|
S: this,
|
|
128
465
|
A: [
|
|
129
466
|
"this._id",
|
|
@@ -137,21 +474,11 @@ var BookmarkWidget = class extends WidgetType {
|
|
|
137
474
|
toDOM() {
|
|
138
475
|
const span = document.createElement("span");
|
|
139
476
|
span.className = "cm-bookmark";
|
|
140
|
-
span.textContent = "\
|
|
477
|
+
span.textContent = "\xA7";
|
|
478
|
+
span.onclick = () => this._handleClick();
|
|
141
479
|
return span;
|
|
142
480
|
}
|
|
143
481
|
};
|
|
144
|
-
var styles = EditorView2.baseTheme({
|
|
145
|
-
"& .cm-bookmark": {
|
|
146
|
-
cursor: "pointer",
|
|
147
|
-
margin: "4px",
|
|
148
|
-
padding: "4px",
|
|
149
|
-
backgroundColor: "yellow"
|
|
150
|
-
},
|
|
151
|
-
"& .cm-bookmark-selected": {
|
|
152
|
-
backgroundColor: "orange"
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
482
|
var comments = (options = {}) => {
|
|
156
483
|
let active;
|
|
157
484
|
const bookmarkMatcher = new MatchDecorator({
|
|
@@ -160,7 +487,9 @@ var comments = (options = {}) => {
|
|
|
160
487
|
const id = match[1];
|
|
161
488
|
return Decoration.replace({
|
|
162
489
|
id,
|
|
163
|
-
widget: new BookmarkWidget(pos, id)
|
|
490
|
+
widget: new BookmarkWidget(pos, id, () => handleUpdate({
|
|
491
|
+
active: id
|
|
492
|
+
}))
|
|
164
493
|
});
|
|
165
494
|
}
|
|
166
495
|
});
|
|
@@ -168,20 +497,20 @@ var comments = (options = {}) => {
|
|
|
168
497
|
constructor(view) {
|
|
169
498
|
this.bookmarks = bookmarkMatcher.createDeco(view);
|
|
170
499
|
}
|
|
171
|
-
update(
|
|
172
|
-
this.bookmarks = bookmarkMatcher.updateDeco(
|
|
500
|
+
update(update4) {
|
|
501
|
+
this.bookmarks = bookmarkMatcher.updateDeco(update4, this.bookmarks);
|
|
173
502
|
}
|
|
174
503
|
}, {
|
|
175
504
|
decorations: (instance) => instance.bookmarks,
|
|
176
|
-
provide: (plugin) =>
|
|
505
|
+
provide: (plugin) => EditorView3.atomicRanges.of((view) => {
|
|
177
506
|
return view.plugin(plugin)?.bookmarks || Decoration.none;
|
|
178
507
|
})
|
|
179
508
|
});
|
|
180
|
-
const
|
|
509
|
+
const handleUpdate = debounce((data) => {
|
|
181
510
|
options.onUpdate?.(data);
|
|
182
511
|
}, 200);
|
|
183
512
|
return [
|
|
184
|
-
|
|
513
|
+
keymap4.of([
|
|
185
514
|
{
|
|
186
515
|
key: options?.key ?? "shift-meta-c",
|
|
187
516
|
run: (view) => {
|
|
@@ -206,20 +535,23 @@ var comments = (options = {}) => {
|
|
|
206
535
|
]),
|
|
207
536
|
bookmarks,
|
|
208
537
|
// Monitor cursor movement.
|
|
209
|
-
|
|
538
|
+
EditorView3.updateListener.of((update4) => {
|
|
210
539
|
active = void 0;
|
|
211
540
|
if (!options.onUpdate) {
|
|
212
541
|
return;
|
|
213
542
|
}
|
|
214
|
-
const view =
|
|
543
|
+
const view = update4.view;
|
|
215
544
|
const pos = view.state.selection.main.head;
|
|
216
545
|
const decorations = [];
|
|
217
546
|
const rangeSet = view.plugin(bookmarks)?.bookmarks;
|
|
218
547
|
let closest = Infinity;
|
|
219
|
-
const { from, to } =
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
548
|
+
const { from, to } = (
|
|
549
|
+
/* view.visibleRanges?.[0] ?? */
|
|
550
|
+
{
|
|
551
|
+
from: 0,
|
|
552
|
+
to: view.state.doc.length
|
|
553
|
+
}
|
|
554
|
+
);
|
|
223
555
|
rangeSet?.between(from, to, (from2, to2, value) => {
|
|
224
556
|
decorations.push({
|
|
225
557
|
from: from2,
|
|
@@ -233,7 +565,7 @@ var comments = (options = {}) => {
|
|
|
233
565
|
}
|
|
234
566
|
});
|
|
235
567
|
if (decorations.length) {
|
|
236
|
-
|
|
568
|
+
handleUpdate({
|
|
237
569
|
active,
|
|
238
570
|
items: decorations.map(({ from: from2, value: { spec: { id } } }) => ({
|
|
239
571
|
id,
|
|
@@ -247,11 +579,64 @@ var comments = (options = {}) => {
|
|
|
247
579
|
];
|
|
248
580
|
};
|
|
249
581
|
|
|
250
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/
|
|
582
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/image.ts
|
|
251
583
|
import { syntaxTree } from "@codemirror/language";
|
|
252
|
-
import { RangeSetBuilder, StateField } from "@codemirror/state";
|
|
253
|
-
import { Decoration as Decoration2, EditorView as
|
|
254
|
-
var
|
|
584
|
+
import { RangeSetBuilder, StateField as StateField2 } from "@codemirror/state";
|
|
585
|
+
import { Decoration as Decoration2, EditorView as EditorView4, WidgetType as WidgetType2 } from "@codemirror/view";
|
|
586
|
+
var image = (options = {}) => {
|
|
587
|
+
return StateField2.define({
|
|
588
|
+
create: (state) => update(state, options),
|
|
589
|
+
update: (_, tr) => update(tr.state, options),
|
|
590
|
+
provide: (field) => EditorView4.decorations.from(field)
|
|
591
|
+
});
|
|
592
|
+
};
|
|
593
|
+
var update = (state, options) => {
|
|
594
|
+
const builder = new RangeSetBuilder();
|
|
595
|
+
const cursor = state.selection.main.head;
|
|
596
|
+
syntaxTree(state).iterate({
|
|
597
|
+
enter: (node) => {
|
|
598
|
+
if (node.name === "Image") {
|
|
599
|
+
const urlNode = node.node.getChild("URL");
|
|
600
|
+
if (urlNode) {
|
|
601
|
+
const hide = state.readOnly || cursor < node.from || cursor > node.to;
|
|
602
|
+
const url = state.sliceDoc(urlNode.from, urlNode.to);
|
|
603
|
+
builder.add(hide ? node.from : node.to, node.to, Decoration2.replace({
|
|
604
|
+
widget: new ImageWidget(url)
|
|
605
|
+
}));
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
return builder.finish();
|
|
611
|
+
};
|
|
612
|
+
var ImageWidget = class extends WidgetType2 {
|
|
613
|
+
constructor(_url) {
|
|
614
|
+
super();
|
|
615
|
+
this._url = _url;
|
|
616
|
+
}
|
|
617
|
+
eq(other) {
|
|
618
|
+
return this._url === other?._url;
|
|
619
|
+
}
|
|
620
|
+
toDOM(view) {
|
|
621
|
+
const img = document.createElement("img");
|
|
622
|
+
img.setAttribute("src", this._url);
|
|
623
|
+
img.setAttribute("class", "cm-image");
|
|
624
|
+
return img;
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/link.ts
|
|
629
|
+
import { syntaxTree as syntaxTree2 } from "@codemirror/language";
|
|
630
|
+
import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField3 } from "@codemirror/state";
|
|
631
|
+
import { Decoration as Decoration3, EditorView as EditorView5, WidgetType as WidgetType3 } from "@codemirror/view";
|
|
632
|
+
var link = (options = {}) => {
|
|
633
|
+
return StateField3.define({
|
|
634
|
+
create: (state) => update2(state, options),
|
|
635
|
+
update: (_, tr) => update2(tr.state, options),
|
|
636
|
+
provide: (field) => EditorView5.decorations.from(field)
|
|
637
|
+
});
|
|
638
|
+
};
|
|
639
|
+
var LinkButton = class extends WidgetType3 {
|
|
255
640
|
constructor(_pos, _url, _onAttach) {
|
|
256
641
|
super();
|
|
257
642
|
this._pos = _pos;
|
|
@@ -267,7 +652,7 @@ var LinkButton = class extends WidgetType2 {
|
|
|
267
652
|
return el;
|
|
268
653
|
}
|
|
269
654
|
};
|
|
270
|
-
var LinkText = class extends
|
|
655
|
+
var LinkText = class extends WidgetType3 {
|
|
271
656
|
constructor(_pos, _text, _url) {
|
|
272
657
|
super();
|
|
273
658
|
this._pos = _pos;
|
|
@@ -297,10 +682,10 @@ var LinkText = class extends WidgetType2 {
|
|
|
297
682
|
return link2;
|
|
298
683
|
}
|
|
299
684
|
};
|
|
300
|
-
var
|
|
301
|
-
const builder = new
|
|
685
|
+
var update2 = (state, options) => {
|
|
686
|
+
const builder = new RangeSetBuilder2();
|
|
302
687
|
const cursor = state.selection.main.head;
|
|
303
|
-
|
|
688
|
+
syntaxTree2(state).iterate({
|
|
304
689
|
enter: (node) => {
|
|
305
690
|
if (node.name === "Link") {
|
|
306
691
|
const marks = node.node.getChildren("LinkMark");
|
|
@@ -310,13 +695,13 @@ var update = (state, options) => {
|
|
|
310
695
|
if (!url) {
|
|
311
696
|
return false;
|
|
312
697
|
}
|
|
313
|
-
if (cursor < node.from || cursor > node.to) {
|
|
314
|
-
builder.add(node.from, node.to,
|
|
698
|
+
if (state.readOnly || cursor < node.from || cursor > node.to) {
|
|
699
|
+
builder.add(node.from, node.to, Decoration3.replace({
|
|
315
700
|
widget: new LinkText(node.from, text, options.link ? url : void 0)
|
|
316
701
|
}));
|
|
317
702
|
}
|
|
318
703
|
if (options.onRender) {
|
|
319
|
-
builder.add(node.to, node.to,
|
|
704
|
+
builder.add(node.to, node.to, Decoration3.replace({
|
|
320
705
|
widget: new LinkButton(node.from, url, options.onRender)
|
|
321
706
|
}));
|
|
322
707
|
}
|
|
@@ -326,52 +711,71 @@ var update = (state, options) => {
|
|
|
326
711
|
});
|
|
327
712
|
return builder.finish();
|
|
328
713
|
};
|
|
329
|
-
var link = (options = {}) => {
|
|
330
|
-
return StateField.define({
|
|
331
|
-
create: (state) => update(state, options),
|
|
332
|
-
update: (_, tr) => update(tr.state, options),
|
|
333
|
-
provide: (field) => EditorView3.decorations.from(field)
|
|
334
|
-
});
|
|
335
|
-
};
|
|
336
714
|
|
|
337
715
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/listener.ts
|
|
338
|
-
import { StateField as
|
|
339
|
-
var listener = ({ onChange }) =>
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
716
|
+
import { StateField as StateField4 } from "@codemirror/state";
|
|
717
|
+
var listener = ({ onChange }) => {
|
|
718
|
+
return StateField4.define({
|
|
719
|
+
create: () => null,
|
|
720
|
+
update: (_value, transaction) => {
|
|
721
|
+
if (transaction.docChanged && onChange) {
|
|
722
|
+
onChange(transaction.newDoc.toString());
|
|
723
|
+
}
|
|
724
|
+
return null;
|
|
344
725
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
});
|
|
726
|
+
});
|
|
727
|
+
};
|
|
348
728
|
|
|
349
729
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
350
730
|
import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
|
|
351
|
-
import {
|
|
731
|
+
import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
|
|
352
732
|
import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
|
|
353
733
|
import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
|
|
354
734
|
import { languages } from "@codemirror/language-data";
|
|
355
735
|
import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
|
|
356
736
|
import { EditorState } from "@codemirror/state";
|
|
357
737
|
import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
|
|
358
|
-
import { crosshairCursor, drawSelection, dropCursor, EditorView as
|
|
738
|
+
import { crosshairCursor, drawSelection, dropCursor, EditorView as EditorView6, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap as keymap5, placeholder as placeholder2, rectangularSelection } from "@codemirror/view";
|
|
359
739
|
|
|
360
740
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
|
|
361
741
|
import { markdownLanguage } from "@codemirror/lang-markdown";
|
|
362
742
|
import { HighlightStyle } from "@codemirror/language";
|
|
363
743
|
import { tags, styleTags, Tag } from "@lezer/highlight";
|
|
744
|
+
import { Table } from "@lezer/markdown";
|
|
364
745
|
import get from "lodash.get";
|
|
746
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
365
747
|
|
|
366
748
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
367
749
|
import { mx } from "@dxos/react-ui-theme";
|
|
368
|
-
var
|
|
369
|
-
1:
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
750
|
+
var headings = {
|
|
751
|
+
1: [
|
|
752
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
|
|
753
|
+
"-ml-1.5"
|
|
754
|
+
],
|
|
755
|
+
2: [
|
|
756
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
|
|
757
|
+
"-ml-1.5"
|
|
758
|
+
],
|
|
759
|
+
3: [
|
|
760
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
|
|
761
|
+
"-ml-1.5"
|
|
762
|
+
],
|
|
763
|
+
4: [
|
|
764
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
|
|
765
|
+
"-ml-[5px]"
|
|
766
|
+
],
|
|
767
|
+
5: [
|
|
768
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
|
|
769
|
+
"-ml-[5px]"
|
|
770
|
+
],
|
|
771
|
+
6: [
|
|
772
|
+
"mbs-4 mbe-2 font-medium text-inherit no-underline",
|
|
773
|
+
"-ml-[4px]"
|
|
774
|
+
]
|
|
775
|
+
};
|
|
776
|
+
var heading = (level, readonly) => {
|
|
777
|
+
const [style, offset] = headings[level];
|
|
778
|
+
return mx(style, readonly && offset);
|
|
375
779
|
};
|
|
376
780
|
var light = "text-neutral-200 dark:text-neutral-800";
|
|
377
781
|
var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
|
|
@@ -382,7 +786,7 @@ var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
|
|
|
382
786
|
var codeMark = "font-mono text-primary-500";
|
|
383
787
|
var inlineUrl = mx(code, "px-1");
|
|
384
788
|
var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
|
|
385
|
-
var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-
|
|
789
|
+
var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
|
|
386
790
|
|
|
387
791
|
// packages/ui/react-ui-editor/src/styles/tokens.ts
|
|
388
792
|
import { tailwindConfig } from "@dxos/react-ui-theme";
|
|
@@ -401,159 +805,193 @@ var markdownTags = {
|
|
|
401
805
|
LinkReference: Tag.define(),
|
|
402
806
|
ListMark: Tag.define(),
|
|
403
807
|
QuoteMark: Tag.define(),
|
|
404
|
-
URL: Tag.define()
|
|
808
|
+
URL: Tag.define(),
|
|
809
|
+
// Custom.
|
|
810
|
+
TableCell: Tag.define()
|
|
405
811
|
};
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
{
|
|
413
|
-
tag: [
|
|
414
|
-
tags.keyword,
|
|
415
|
-
tags.name,
|
|
416
|
-
tags.deleted,
|
|
417
|
-
tags.character,
|
|
418
|
-
tags.propertyName,
|
|
419
|
-
tags.macroName,
|
|
420
|
-
tags.color,
|
|
421
|
-
tags.constant(tags.name),
|
|
422
|
-
tags.standard(tags.name),
|
|
423
|
-
tags.definition(tags.name),
|
|
424
|
-
tags.separator,
|
|
425
|
-
tags.typeName,
|
|
426
|
-
tags.className,
|
|
427
|
-
tags.number,
|
|
428
|
-
tags.changed,
|
|
429
|
-
tags.annotation,
|
|
430
|
-
tags.modifier,
|
|
431
|
-
tags.self,
|
|
432
|
-
tags.namespace,
|
|
433
|
-
tags.operator,
|
|
434
|
-
tags.operatorKeyword,
|
|
435
|
-
tags.escape,
|
|
436
|
-
tags.regexp,
|
|
437
|
-
tags.special(tags.string),
|
|
438
|
-
tags.meta,
|
|
439
|
-
tags.comment,
|
|
440
|
-
tags.atom,
|
|
441
|
-
tags.bool,
|
|
442
|
-
tags.special(tags.variableName),
|
|
443
|
-
tags.processingInstruction,
|
|
444
|
-
tags.string,
|
|
445
|
-
tags.inserted,
|
|
446
|
-
tags.invalid
|
|
447
|
-
],
|
|
448
|
-
color: "inherit !important"
|
|
449
|
-
},
|
|
450
|
-
// Markdown marks.
|
|
451
|
-
{
|
|
452
|
-
tag: [
|
|
453
|
-
tags.meta,
|
|
454
|
-
tags.processingInstruction,
|
|
455
|
-
markdownTags.CodeMark,
|
|
456
|
-
markdownTags.EmphasisMark,
|
|
457
|
-
markdownTags.HeaderMark,
|
|
458
|
-
markdownTags.LinkLabel,
|
|
459
|
-
markdownTags.LinkReference,
|
|
460
|
-
markdownTags.ListMark,
|
|
461
|
-
markdownTags.QuoteMark
|
|
462
|
-
],
|
|
463
|
-
class: mark
|
|
464
|
-
},
|
|
465
|
-
// Headings.
|
|
466
|
-
{
|
|
467
|
-
tag: tags.heading1,
|
|
468
|
-
class: heading[1]
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
tag: tags.heading2,
|
|
472
|
-
class: heading[2]
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
tag: tags.heading3,
|
|
476
|
-
class: heading[3]
|
|
477
|
-
},
|
|
478
|
-
{
|
|
479
|
-
tag: tags.heading4,
|
|
480
|
-
class: heading[4]
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
tag: tags.heading5,
|
|
484
|
-
class: heading[5]
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
tag: tags.heading6,
|
|
488
|
-
class: heading[6]
|
|
489
|
-
},
|
|
490
|
-
// Emphasis.
|
|
491
|
-
{
|
|
492
|
-
tag: tags.emphasis,
|
|
493
|
-
class: italic
|
|
494
|
-
},
|
|
495
|
-
{
|
|
496
|
-
tag: tags.strong,
|
|
497
|
-
class: bold
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
tag: tags.strikethrough,
|
|
501
|
-
class: strikethrough
|
|
502
|
-
},
|
|
503
|
-
// Naked URLs.
|
|
504
|
-
{
|
|
505
|
-
tag: [
|
|
506
|
-
markdownTags.URL
|
|
507
|
-
],
|
|
508
|
-
class: inlineUrl
|
|
509
|
-
},
|
|
510
|
-
// E.g., code block language (after ```).
|
|
511
|
-
{
|
|
512
|
-
tag: [
|
|
513
|
-
tags.function(tags.variableName),
|
|
514
|
-
tags.labelName
|
|
515
|
-
],
|
|
516
|
-
class: codeMark
|
|
517
|
-
},
|
|
518
|
-
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
519
|
-
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
520
|
-
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
521
|
-
// the code, but all other CSS properties will be inherited.
|
|
522
|
-
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
523
|
-
{
|
|
524
|
-
tag: [
|
|
525
|
-
markdownTags.CodeText,
|
|
526
|
-
markdownTags.InlineCode
|
|
527
|
-
],
|
|
528
|
-
class: code
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
tag: [
|
|
532
|
-
markdownTags.QuoteMark
|
|
533
|
-
],
|
|
534
|
-
class: blockquote
|
|
535
|
-
},
|
|
536
|
-
{
|
|
537
|
-
tag: [
|
|
538
|
-
markdownTags.HorizontalRule
|
|
539
|
-
],
|
|
540
|
-
class: horizontalRule
|
|
541
|
-
}
|
|
542
|
-
], {
|
|
543
|
-
scope: markdownLanguage,
|
|
544
|
-
all: {
|
|
545
|
-
fontFamily: get(tokens, "fontFamily.body", []).join(",")
|
|
812
|
+
Table.defineNodes?.forEach((node) => {
|
|
813
|
+
switch (node?.name) {
|
|
814
|
+
case "TableCell": {
|
|
815
|
+
node.style = markdownTags.TableCell;
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
546
818
|
}
|
|
547
819
|
});
|
|
820
|
+
var markdownTagsExtensions = [
|
|
821
|
+
Table,
|
|
822
|
+
{
|
|
823
|
+
props: [
|
|
824
|
+
styleTags(markdownTags)
|
|
825
|
+
]
|
|
826
|
+
}
|
|
827
|
+
];
|
|
828
|
+
var markdownHighlightStyle = (readonly) => {
|
|
829
|
+
return HighlightStyle.define([
|
|
830
|
+
{
|
|
831
|
+
tag: [
|
|
832
|
+
tags.keyword,
|
|
833
|
+
tags.name,
|
|
834
|
+
tags.deleted,
|
|
835
|
+
tags.character,
|
|
836
|
+
tags.propertyName,
|
|
837
|
+
tags.macroName,
|
|
838
|
+
tags.color,
|
|
839
|
+
tags.constant(tags.name),
|
|
840
|
+
tags.standard(tags.name),
|
|
841
|
+
tags.definition(tags.name),
|
|
842
|
+
tags.separator,
|
|
843
|
+
tags.typeName,
|
|
844
|
+
tags.className,
|
|
845
|
+
tags.number,
|
|
846
|
+
tags.changed,
|
|
847
|
+
tags.annotation,
|
|
848
|
+
tags.modifier,
|
|
849
|
+
tags.self,
|
|
850
|
+
tags.namespace,
|
|
851
|
+
tags.operator,
|
|
852
|
+
tags.operatorKeyword,
|
|
853
|
+
tags.escape,
|
|
854
|
+
tags.regexp,
|
|
855
|
+
tags.special(tags.string),
|
|
856
|
+
tags.meta,
|
|
857
|
+
tags.comment,
|
|
858
|
+
tags.atom,
|
|
859
|
+
tags.bool,
|
|
860
|
+
tags.special(tags.variableName),
|
|
861
|
+
tags.processingInstruction,
|
|
862
|
+
tags.string,
|
|
863
|
+
tags.inserted,
|
|
864
|
+
tags.invalid
|
|
865
|
+
],
|
|
866
|
+
color: "inherit !important"
|
|
867
|
+
},
|
|
868
|
+
// Markdown marks.
|
|
869
|
+
{
|
|
870
|
+
tag: [
|
|
871
|
+
tags.meta,
|
|
872
|
+
tags.processingInstruction,
|
|
873
|
+
markdownTags.LinkLabel,
|
|
874
|
+
markdownTags.LinkReference,
|
|
875
|
+
markdownTags.ListMark
|
|
876
|
+
],
|
|
877
|
+
class: mark
|
|
878
|
+
},
|
|
879
|
+
// Markdown marks.
|
|
880
|
+
{
|
|
881
|
+
tag: [
|
|
882
|
+
markdownTags.CodeMark,
|
|
883
|
+
markdownTags.HeaderMark,
|
|
884
|
+
markdownTags.QuoteMark,
|
|
885
|
+
markdownTags.EmphasisMark
|
|
886
|
+
],
|
|
887
|
+
class: readonly ? "hidden" : mark
|
|
888
|
+
},
|
|
889
|
+
// E.g., code block language (after ```).
|
|
890
|
+
{
|
|
891
|
+
tag: [
|
|
892
|
+
tags.function(tags.variableName),
|
|
893
|
+
tags.labelName
|
|
894
|
+
],
|
|
895
|
+
class: readonly ? "hidden" : codeMark
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
tag: [
|
|
899
|
+
tags.monospace
|
|
900
|
+
],
|
|
901
|
+
class: "font-mono"
|
|
902
|
+
},
|
|
903
|
+
// Headings.
|
|
904
|
+
{
|
|
905
|
+
tag: tags.heading1,
|
|
906
|
+
class: heading(1, readonly)
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
tag: tags.heading2,
|
|
910
|
+
class: heading(2, readonly)
|
|
911
|
+
},
|
|
912
|
+
{
|
|
913
|
+
tag: tags.heading3,
|
|
914
|
+
class: heading(3, readonly)
|
|
915
|
+
},
|
|
916
|
+
{
|
|
917
|
+
tag: tags.heading4,
|
|
918
|
+
class: heading(4, readonly)
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
tag: tags.heading5,
|
|
922
|
+
class: heading(5, readonly)
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
tag: tags.heading6,
|
|
926
|
+
class: heading(6, readonly)
|
|
927
|
+
},
|
|
928
|
+
// Emphasis.
|
|
929
|
+
{
|
|
930
|
+
tag: tags.emphasis,
|
|
931
|
+
class: italic
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
tag: tags.strong,
|
|
935
|
+
class: bold
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
tag: tags.strikethrough,
|
|
939
|
+
class: strikethrough
|
|
940
|
+
},
|
|
941
|
+
// Naked URLs.
|
|
942
|
+
{
|
|
943
|
+
tag: [
|
|
944
|
+
markdownTags.URL
|
|
945
|
+
],
|
|
946
|
+
class: inlineUrl
|
|
947
|
+
},
|
|
948
|
+
// NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
|
|
949
|
+
// However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
|
|
950
|
+
// when a language is specified. In this case, the syntax highlighting extensions will colorize
|
|
951
|
+
// the code, but all other CSS properties will be inherited.
|
|
952
|
+
// IMPORTANT: Therefore, the fenced code block will use the base editor font.
|
|
953
|
+
{
|
|
954
|
+
tag: [
|
|
955
|
+
markdownTags.CodeText,
|
|
956
|
+
markdownTags.InlineCode
|
|
957
|
+
],
|
|
958
|
+
class: code
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
tag: [
|
|
962
|
+
markdownTags.QuoteMark
|
|
963
|
+
],
|
|
964
|
+
class: blockquote
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
tag: [
|
|
968
|
+
markdownTags.HorizontalRule
|
|
969
|
+
],
|
|
970
|
+
class: mx2(horizontalRule, readonly && "-indent-[100rem]")
|
|
971
|
+
},
|
|
972
|
+
// TODO(burdon): Only if being edited.
|
|
973
|
+
{
|
|
974
|
+
tag: [
|
|
975
|
+
markdownTags.TableCell
|
|
976
|
+
],
|
|
977
|
+
class: "font-mono"
|
|
978
|
+
}
|
|
979
|
+
], {
|
|
980
|
+
scope: markdownLanguage,
|
|
981
|
+
all: {
|
|
982
|
+
fontFamily: get(tokens, "fontFamily.body", []).join(",")
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
};
|
|
548
986
|
|
|
549
987
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
|
|
550
|
-
var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
988
|
+
var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
|
|
551
989
|
return [
|
|
552
990
|
bracketMatching2(),
|
|
553
991
|
closeBrackets2(),
|
|
554
992
|
_placeholder && placeholder2(_placeholder),
|
|
555
993
|
EditorState.allowMultipleSelections.of(true),
|
|
556
|
-
|
|
994
|
+
EditorView6.lineWrapping,
|
|
557
995
|
crosshairCursor(),
|
|
558
996
|
dropCursor(),
|
|
559
997
|
drawSelection(),
|
|
@@ -564,16 +1002,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
564
1002
|
history(),
|
|
565
1003
|
indentOnInput(),
|
|
566
1004
|
rectangularSelection(),
|
|
567
|
-
|
|
568
|
-
keymap4.of([
|
|
569
|
-
...closeBracketsKeymap,
|
|
570
|
-
...defaultKeymap,
|
|
571
|
-
// ...foldKeymap,
|
|
572
|
-
// ...historyKeymap,
|
|
573
|
-
// ...lintKeymap,
|
|
574
|
-
...searchKeymap,
|
|
575
|
-
indentWithTab
|
|
576
|
-
]),
|
|
1005
|
+
customkeymap(),
|
|
577
1006
|
// Main extension.
|
|
578
1007
|
// https://github.com/codemirror/lang-markdown
|
|
579
1008
|
// https://codemirror.net/5/mode/markdown/index.html (demo).
|
|
@@ -588,20 +1017,153 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
|
|
|
588
1017
|
codeLanguages: languages,
|
|
589
1018
|
// Parser extensions.
|
|
590
1019
|
extensions: [
|
|
591
|
-
// GFM
|
|
592
|
-
|
|
1020
|
+
// GFM provided by default.
|
|
1021
|
+
markdownTagsExtensions
|
|
593
1022
|
]
|
|
594
1023
|
}),
|
|
1024
|
+
// https://github.com/codemirror/theme-one-dark
|
|
1025
|
+
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2),
|
|
595
1026
|
// Custom styles.
|
|
596
|
-
syntaxHighlighting2(markdownHighlightStyle)
|
|
597
|
-
// TODO(thure): All but one rule here apply to both themes; rename or refactor.
|
|
598
|
-
themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2)
|
|
1027
|
+
syntaxHighlighting2(markdownHighlightStyle(readonly))
|
|
599
1028
|
].filter(Boolean);
|
|
600
1029
|
};
|
|
1030
|
+
var customkeymap = () => keymap5.of([
|
|
1031
|
+
// https://codemirror.net/docs/ref/#commands.indentWithTab
|
|
1032
|
+
indentWithTab,
|
|
1033
|
+
// https://codemirror.net/docs/ref/#commands.standardKeymap
|
|
1034
|
+
...standardKeymap,
|
|
1035
|
+
// https://codemirror.net/docs/ref/#commands.historyKeymap
|
|
1036
|
+
...historyKeymap,
|
|
1037
|
+
// https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
|
|
1038
|
+
...closeBracketsKeymap,
|
|
1039
|
+
// https://codemirror.net/docs/ref/#search.searchKeymap
|
|
1040
|
+
...searchKeymap
|
|
1041
|
+
]);
|
|
1042
|
+
|
|
1043
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/mention.ts
|
|
1044
|
+
import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
|
|
1045
|
+
var mention = ({ onSearch }) => {
|
|
1046
|
+
return autocompletion2({
|
|
1047
|
+
closeOnBlur: false,
|
|
1048
|
+
override: [
|
|
1049
|
+
(context) => {
|
|
1050
|
+
const match = context.matchBefore(/@(\w+)?/);
|
|
1051
|
+
if (!match || match.from === match.to && !context.explicit) {
|
|
1052
|
+
return null;
|
|
1053
|
+
}
|
|
1054
|
+
console.log(match);
|
|
1055
|
+
return {
|
|
1056
|
+
from: match.from,
|
|
1057
|
+
options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
|
|
1058
|
+
label: `@${value}`
|
|
1059
|
+
}))
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
]
|
|
1063
|
+
});
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
|
|
1067
|
+
import { syntaxTree as syntaxTree3 } from "@codemirror/language";
|
|
1068
|
+
import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
|
|
1069
|
+
import { Decoration as Decoration4, EditorView as EditorView7, WidgetType as WidgetType4 } from "@codemirror/view";
|
|
1070
|
+
var table = (options = {}) => {
|
|
1071
|
+
return StateField5.define({
|
|
1072
|
+
create: (state) => update3(state, options),
|
|
1073
|
+
update: (_, tr) => update3(tr.state, options),
|
|
1074
|
+
provide: (field) => EditorView7.decorations.from(field)
|
|
1075
|
+
});
|
|
1076
|
+
};
|
|
1077
|
+
var update3 = (state, options) => {
|
|
1078
|
+
const builder = new RangeSetBuilder3();
|
|
1079
|
+
const cursor = state.selection.main.head;
|
|
1080
|
+
const tables = [];
|
|
1081
|
+
const getTable = () => tables[tables.length - 1];
|
|
1082
|
+
const getRow = () => {
|
|
1083
|
+
const table2 = getTable();
|
|
1084
|
+
return table2.rows?.[table2.rows.length - 1];
|
|
1085
|
+
};
|
|
1086
|
+
syntaxTree3(state).iterate({
|
|
1087
|
+
enter: (node) => {
|
|
1088
|
+
switch (node.name) {
|
|
1089
|
+
case "Table": {
|
|
1090
|
+
tables.push({
|
|
1091
|
+
from: node.from,
|
|
1092
|
+
to: node.to
|
|
1093
|
+
});
|
|
1094
|
+
break;
|
|
1095
|
+
}
|
|
1096
|
+
case "TableHeader": {
|
|
1097
|
+
getTable().header = [];
|
|
1098
|
+
break;
|
|
1099
|
+
}
|
|
1100
|
+
case "TableRow": {
|
|
1101
|
+
(getTable().rows ??= []).push([]);
|
|
1102
|
+
break;
|
|
1103
|
+
}
|
|
1104
|
+
case "TableCell": {
|
|
1105
|
+
const row = getRow();
|
|
1106
|
+
if (row) {
|
|
1107
|
+
row.push(state.sliceDoc(node.from, node.to));
|
|
1108
|
+
} else {
|
|
1109
|
+
getTable().header?.push(state.sliceDoc(node.from, node.to));
|
|
1110
|
+
}
|
|
1111
|
+
break;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
tables.forEach((table2) => {
|
|
1117
|
+
const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
|
|
1118
|
+
hide && builder.add(table2.from, table2.to, Decoration4.replace({
|
|
1119
|
+
widget: new TableWidget(table2)
|
|
1120
|
+
}));
|
|
1121
|
+
});
|
|
1122
|
+
return builder.finish();
|
|
1123
|
+
};
|
|
1124
|
+
var TableWidget = class extends WidgetType4 {
|
|
1125
|
+
constructor(_table) {
|
|
1126
|
+
super();
|
|
1127
|
+
this._table = _table;
|
|
1128
|
+
}
|
|
1129
|
+
eq(other) {
|
|
1130
|
+
return this._table.from === other?._table?.from;
|
|
1131
|
+
}
|
|
1132
|
+
toDOM(view) {
|
|
1133
|
+
const table2 = document.createElement("table");
|
|
1134
|
+
{
|
|
1135
|
+
const header = table2.appendChild(document.createElement("thead"));
|
|
1136
|
+
const tr = header.appendChild(document.createElement("tr"));
|
|
1137
|
+
this._table.header?.forEach((cell) => {
|
|
1138
|
+
const th = document.createElement("th");
|
|
1139
|
+
th.setAttribute("class", "cm-table-head");
|
|
1140
|
+
tr.appendChild(th).textContent = cell;
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
{
|
|
1144
|
+
const body = table2.appendChild(document.createElement("tbody"));
|
|
1145
|
+
this._table.rows?.forEach((row) => {
|
|
1146
|
+
const tr = body.appendChild(document.createElement("tr"));
|
|
1147
|
+
row.forEach((cell) => {
|
|
1148
|
+
const td = document.createElement("td");
|
|
1149
|
+
td.setAttribute("class", "cm-table-cell");
|
|
1150
|
+
tr.appendChild(td).textContent = cell;
|
|
1151
|
+
});
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
return table2;
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
601
1157
|
|
|
602
1158
|
// packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
|
|
603
|
-
import { EditorView as
|
|
604
|
-
var
|
|
1159
|
+
import { EditorView as EditorView8, Decoration as Decoration5, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin2 } from "@codemirror/view";
|
|
1160
|
+
var styles2 = EditorView8.baseTheme({
|
|
1161
|
+
"& .cm-task-item": {
|
|
1162
|
+
paddingLeft: "4px",
|
|
1163
|
+
paddingRight: "8px"
|
|
1164
|
+
}
|
|
1165
|
+
});
|
|
1166
|
+
var CheckboxWidget = class extends WidgetType5 {
|
|
605
1167
|
constructor(_pos, _checked, _indent, _onCheck) {
|
|
606
1168
|
super();
|
|
607
1169
|
this._pos = _pos;
|
|
@@ -620,30 +1182,29 @@ var CheckboxWidget = class extends WidgetType3 {
|
|
|
620
1182
|
const input = wrap.appendChild(document.createElement("input"));
|
|
621
1183
|
input.type = "checkbox";
|
|
622
1184
|
input.checked = this._checked;
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
1185
|
+
if (!this._onCheck) {
|
|
1186
|
+
input.setAttribute("disabled", "true");
|
|
1187
|
+
}
|
|
1188
|
+
if (this._onCheck) {
|
|
1189
|
+
input.onchange = (event) => {
|
|
1190
|
+
this._onCheck?.(event.target.checked);
|
|
1191
|
+
return true;
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
627
1194
|
return wrap;
|
|
628
1195
|
}
|
|
629
1196
|
ignoreEvent() {
|
|
630
1197
|
return false;
|
|
631
1198
|
}
|
|
632
1199
|
};
|
|
633
|
-
var
|
|
634
|
-
"& .cm-task-item": {
|
|
635
|
-
paddingLeft: "4px",
|
|
636
|
-
paddingRight: "8px"
|
|
637
|
-
}
|
|
638
|
-
});
|
|
639
|
-
var tasklist = () => {
|
|
1200
|
+
var tasklist = (options = {}) => {
|
|
640
1201
|
const taskMatcher = new MatchDecorator2({
|
|
641
1202
|
regexp: /^(\s*)- \[([ xX])\]\s/g,
|
|
642
1203
|
decoration: (match, view, pos) => {
|
|
643
1204
|
const indent = Math.floor(match[1].length / 2);
|
|
644
1205
|
const checked = match[2] === "x" || match[2] === "X";
|
|
645
|
-
return
|
|
646
|
-
widget: new CheckboxWidget(pos, checked, indent, (checked2) => {
|
|
1206
|
+
return Decoration5.replace({
|
|
1207
|
+
widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
|
|
647
1208
|
const idx = pos + match[0].indexOf("[") + 1;
|
|
648
1209
|
view.dispatch({
|
|
649
1210
|
changes: {
|
|
@@ -664,13 +1225,13 @@ var tasklist = () => {
|
|
|
664
1225
|
constructor(view) {
|
|
665
1226
|
this.tasks = taskMatcher.createDeco(view);
|
|
666
1227
|
}
|
|
667
|
-
update(
|
|
668
|
-
this.tasks = taskMatcher.updateDeco(
|
|
1228
|
+
update(update4) {
|
|
1229
|
+
this.tasks = taskMatcher.updateDeco(update4, this.tasks);
|
|
669
1230
|
}
|
|
670
1231
|
}, {
|
|
671
1232
|
decorations: (instance) => instance.tasks,
|
|
672
|
-
provide: (plugin) =>
|
|
673
|
-
return view.plugin(plugin)?.tasks ||
|
|
1233
|
+
provide: (plugin) => EditorView8.atomicRanges.of((view) => {
|
|
1234
|
+
return view.plugin(plugin)?.tasks || Decoration5.none;
|
|
674
1235
|
})
|
|
675
1236
|
});
|
|
676
1237
|
return [
|
|
@@ -837,8 +1398,51 @@ var defaultTheme = {
|
|
|
837
1398
|
"& .cm-tooltip": {
|
|
838
1399
|
border: "none"
|
|
839
1400
|
},
|
|
840
|
-
|
|
841
|
-
//
|
|
1401
|
+
"& .cm-tooltip-below": {},
|
|
1402
|
+
//
|
|
1403
|
+
// autocomplete
|
|
1404
|
+
//
|
|
1405
|
+
"& .cm-tooltip-autocomplete": {
|
|
1406
|
+
marginTop: "4px",
|
|
1407
|
+
marginLeft: "-3px"
|
|
1408
|
+
},
|
|
1409
|
+
"& .cm-tooltip-autocomplete ul li": {},
|
|
1410
|
+
"& .cm-tooltip-autocomplete ul li[aria-selected]": {},
|
|
1411
|
+
"& .cm-completionIcon": {
|
|
1412
|
+
display: "none"
|
|
1413
|
+
},
|
|
1414
|
+
"& .cm-completionLabel": {
|
|
1415
|
+
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
1416
|
+
},
|
|
1417
|
+
"& .cm-completionMatchedText": {
|
|
1418
|
+
textDecoration: "none"
|
|
1419
|
+
},
|
|
1420
|
+
//
|
|
1421
|
+
// widgets
|
|
1422
|
+
//
|
|
1423
|
+
"& .cm-widgetBuffer": {
|
|
1424
|
+
display: "none",
|
|
1425
|
+
height: 0
|
|
1426
|
+
},
|
|
1427
|
+
//
|
|
1428
|
+
// table
|
|
1429
|
+
//
|
|
1430
|
+
"& .cm-table-head": {
|
|
1431
|
+
padding: "2px 16px 2px 0px",
|
|
1432
|
+
borderBottom: `1px solid ${get2(tokens, "extend.colors.neutral.500")}`,
|
|
1433
|
+
fontWeight: 100,
|
|
1434
|
+
textAlign: "left",
|
|
1435
|
+
color: get2(tokens, "extend.colors.neutral.500")
|
|
1436
|
+
},
|
|
1437
|
+
"& .cm-table-cell": {
|
|
1438
|
+
padding: "2px 16px 2px 0px"
|
|
1439
|
+
},
|
|
1440
|
+
//
|
|
1441
|
+
// image
|
|
1442
|
+
//
|
|
1443
|
+
"& .cm-image": {
|
|
1444
|
+
margin: "0.5rem 0"
|
|
1445
|
+
},
|
|
842
1446
|
//
|
|
843
1447
|
// font size
|
|
844
1448
|
// 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.
|
|
@@ -888,19 +1492,19 @@ var codeTheme = {
|
|
|
888
1492
|
|
|
889
1493
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
890
1494
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
891
|
-
import { EditorView as
|
|
1495
|
+
import { EditorView as EditorView9 } from "@codemirror/view";
|
|
892
1496
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
893
1497
|
import { vim } from "@replit/codemirror-vim";
|
|
894
|
-
import
|
|
1498
|
+
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
895
1499
|
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
|
|
896
1500
|
import { generateName } from "@dxos/display-name";
|
|
897
1501
|
import { useThemeContext } from "@dxos/react-ui";
|
|
898
|
-
import { getColorForValue, inputSurface, mx as
|
|
1502
|
+
import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
899
1503
|
var EditorModes = [
|
|
900
1504
|
"default",
|
|
901
1505
|
"vim"
|
|
902
1506
|
];
|
|
903
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots = defaultSlots
|
|
1507
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
|
|
904
1508
|
const { themeMode } = useThemeContext();
|
|
905
1509
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
906
1510
|
tabBehavior: "limited"
|
|
@@ -945,13 +1549,14 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
945
1549
|
const state2 = EditorState2.create({
|
|
946
1550
|
doc: model.text(),
|
|
947
1551
|
extensions: [
|
|
1552
|
+
readonly && EditorState2.readOnly.of(readonly),
|
|
948
1553
|
// TODO(burdon): Factor out VIM mode?
|
|
949
1554
|
editorMode === "vim" && vim(),
|
|
950
1555
|
// Theme.
|
|
951
|
-
|
|
952
|
-
|
|
1556
|
+
EditorView9.baseTheme(defaultTheme),
|
|
1557
|
+
EditorView9.theme(slots?.editor?.theme ?? {}),
|
|
953
1558
|
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
954
|
-
|
|
1559
|
+
EditorView9.darkTheme.of(themeMode === "dark"),
|
|
955
1560
|
// Storage and replication.
|
|
956
1561
|
model.extension,
|
|
957
1562
|
// Custom.
|
|
@@ -959,7 +1564,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
959
1564
|
].filter(Boolean)
|
|
960
1565
|
});
|
|
961
1566
|
view?.destroy();
|
|
962
|
-
setView(new
|
|
1567
|
+
setView(new EditorView9({
|
|
963
1568
|
state: state2,
|
|
964
1569
|
parent: root
|
|
965
1570
|
}));
|
|
@@ -973,6 +1578,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
973
1578
|
root,
|
|
974
1579
|
model,
|
|
975
1580
|
themeMode,
|
|
1581
|
+
readonly,
|
|
976
1582
|
editorMode
|
|
977
1583
|
]);
|
|
978
1584
|
const handleKeyUp = useCallback((event) => {
|
|
@@ -1000,43 +1606,36 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
|
|
|
1000
1606
|
onKeyUp: handleKeyUp
|
|
1001
1607
|
});
|
|
1002
1608
|
});
|
|
1003
|
-
var
|
|
1004
|
-
const items = localStorage.getItem("dxos.composer.demo");
|
|
1005
|
-
if (items) {
|
|
1006
|
-
return demo({
|
|
1007
|
-
items: items.split(",")
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
return [];
|
|
1011
|
-
};
|
|
1012
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1609
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1013
1610
|
const { themeMode } = useThemeContext();
|
|
1014
|
-
const slots =
|
|
1611
|
+
const slots = defaultsDeep2({}, _slots, defaultTextSlots);
|
|
1015
1612
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
1016
1613
|
ref: forwardedRef,
|
|
1614
|
+
readonly,
|
|
1017
1615
|
extensions: [
|
|
1018
1616
|
basicBundle({
|
|
1617
|
+
readonly,
|
|
1019
1618
|
themeMode,
|
|
1020
1619
|
placeholder: slots?.editor?.placeholder
|
|
1021
1620
|
}),
|
|
1022
|
-
maybeDebug(),
|
|
1023
1621
|
...extensions
|
|
1024
1622
|
],
|
|
1025
1623
|
slots,
|
|
1026
1624
|
...props
|
|
1027
1625
|
});
|
|
1028
1626
|
});
|
|
1029
|
-
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1627
|
+
var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
1030
1628
|
const { themeMode } = useThemeContext();
|
|
1031
|
-
const slots =
|
|
1629
|
+
const slots = defaultsDeep2({}, _slots, defaultMarkdownSlots);
|
|
1032
1630
|
return /* @__PURE__ */ React.createElement(BaseTextEditor, {
|
|
1033
1631
|
ref: forwardedRef,
|
|
1632
|
+
readonly,
|
|
1034
1633
|
extensions: [
|
|
1035
1634
|
markdownBundle({
|
|
1635
|
+
readonly,
|
|
1036
1636
|
themeMode,
|
|
1037
1637
|
placeholder: slots?.editor?.placeholder
|
|
1038
1638
|
}),
|
|
1039
|
-
maybeDebug(),
|
|
1040
1639
|
...extensions
|
|
1041
1640
|
],
|
|
1042
1641
|
slots,
|
|
@@ -1045,7 +1644,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slot
|
|
|
1045
1644
|
});
|
|
1046
1645
|
var defaultSlots = {
|
|
1047
1646
|
root: {
|
|
1048
|
-
className:
|
|
1647
|
+
className: mx3("p-2", inputSurface)
|
|
1049
1648
|
}
|
|
1050
1649
|
};
|
|
1051
1650
|
var defaultTextSlots = {
|
|
@@ -1065,11 +1664,11 @@ var defaultMarkdownSlots = {
|
|
|
1065
1664
|
import get3 from "lodash.get";
|
|
1066
1665
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1067
1666
|
import { yCollab } from "y-codemirror.next";
|
|
1068
|
-
import { invariant as
|
|
1667
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1069
1668
|
import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
|
|
1070
1669
|
|
|
1071
1670
|
// packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
|
|
1072
|
-
import { Annotation, Facet, StateEffect, StateField as
|
|
1671
|
+
import { Annotation, Facet, StateEffect, StateField as StateField6 } from "@codemirror/state";
|
|
1073
1672
|
import { ViewPlugin as ViewPlugin3 } from "@codemirror/view";
|
|
1074
1673
|
import * as automerge2 from "@dxos/automerge/automerge";
|
|
1075
1674
|
|
|
@@ -1258,7 +1857,7 @@ var semaphoreFacet = Facet.define({
|
|
|
1258
1857
|
combine: (values) => values.at(-1)
|
|
1259
1858
|
});
|
|
1260
1859
|
var automergePlugin = (handle, path) => {
|
|
1261
|
-
const stateField =
|
|
1860
|
+
const stateField = StateField6.define({
|
|
1262
1861
|
create: () => ({
|
|
1263
1862
|
lastHeads: automerge2.getHeads(handle.docSync()),
|
|
1264
1863
|
unreconciledTransactions: [],
|
|
@@ -1296,8 +1895,8 @@ var automergePlugin = (handle, path) => {
|
|
|
1296
1895
|
this._view = view;
|
|
1297
1896
|
handle.addListener("change", this._handleChange);
|
|
1298
1897
|
}
|
|
1299
|
-
update(
|
|
1300
|
-
if (
|
|
1898
|
+
update(update4) {
|
|
1899
|
+
if (update4.transactions.length > 0 && update4.transactions.some((t) => !isReconcileTx(t))) {
|
|
1301
1900
|
queueMicrotask(() => {
|
|
1302
1901
|
this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
|
|
1303
1902
|
});
|
|
@@ -1319,7 +1918,7 @@ var reconcileAnnotationType = Annotation.define();
|
|
|
1319
1918
|
var isReconcileTx = (tr) => !!tr.annotation(reconcileAnnotationType);
|
|
1320
1919
|
|
|
1321
1920
|
// packages/ui/react-ui-editor/src/hooks/yjs/cursors.ts
|
|
1322
|
-
import * as
|
|
1921
|
+
import * as random2 from "lib0/random";
|
|
1323
1922
|
var cursorColors = [
|
|
1324
1923
|
{
|
|
1325
1924
|
color: "#30bced",
|
|
@@ -1354,7 +1953,7 @@ var cursorColors = [
|
|
|
1354
1953
|
light: "#1be7ff33"
|
|
1355
1954
|
}
|
|
1356
1955
|
];
|
|
1357
|
-
var cursorColor = cursorColors[
|
|
1956
|
+
var cursorColor = cursorColors[random2.uint32() % cursorColors.length];
|
|
1358
1957
|
|
|
1359
1958
|
// packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts
|
|
1360
1959
|
import * as decoding from "lib0/decoding";
|
|
@@ -1362,7 +1961,7 @@ import * as encoding from "lib0/encoding";
|
|
|
1362
1961
|
import { Observable } from "lib0/observable";
|
|
1363
1962
|
import * as awarenessProtocol from "y-protocols/awareness";
|
|
1364
1963
|
import { log } from "@dxos/log";
|
|
1365
|
-
var
|
|
1964
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts";
|
|
1366
1965
|
var messageAwareness = 1;
|
|
1367
1966
|
var messageQueryAwareness = 3;
|
|
1368
1967
|
var SpaceAwarenessProvider = class extends Observable {
|
|
@@ -1399,7 +1998,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1399
1998
|
removed,
|
|
1400
1999
|
origin
|
|
1401
2000
|
}, {
|
|
1402
|
-
F:
|
|
2001
|
+
F: __dxlog_file3,
|
|
1403
2002
|
L: 67,
|
|
1404
2003
|
S: this,
|
|
1405
2004
|
C: (f, a) => f(...a)
|
|
@@ -1412,7 +2011,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1412
2011
|
}
|
|
1413
2012
|
_handleSpaceMessage({ payload }) {
|
|
1414
2013
|
log("space message", payload, {
|
|
1415
|
-
F:
|
|
2014
|
+
F: __dxlog_file3,
|
|
1416
2015
|
L: 79,
|
|
1417
2016
|
S: this,
|
|
1418
2017
|
C: (f, a) => f(...a)
|
|
@@ -1457,7 +2056,7 @@ var SpaceAwarenessProvider = class extends Observable {
|
|
|
1457
2056
|
};
|
|
1458
2057
|
|
|
1459
2058
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
1460
|
-
var
|
|
2059
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
1461
2060
|
var useTextModel = ({ identity, space, text }) => {
|
|
1462
2061
|
const [model, setModel] = useState2(() => createModel({
|
|
1463
2062
|
identity,
|
|
@@ -1489,8 +2088,8 @@ var createModel = (options) => {
|
|
|
1489
2088
|
}
|
|
1490
2089
|
};
|
|
1491
2090
|
var createYjsModel = ({ identity, space, text }) => {
|
|
1492
|
-
|
|
1493
|
-
F:
|
|
2091
|
+
invariant3(text?.doc && text?.content, void 0, {
|
|
2092
|
+
F: __dxlog_file4,
|
|
1494
2093
|
L: 74,
|
|
1495
2094
|
S: void 0,
|
|
1496
2095
|
A: [
|
|
@@ -1543,21 +2142,26 @@ export {
|
|
|
1543
2142
|
YXmlFragment,
|
|
1544
2143
|
autocomplete,
|
|
1545
2144
|
basicBundle,
|
|
2145
|
+
blast,
|
|
1546
2146
|
codeTheme,
|
|
1547
2147
|
comments,
|
|
1548
2148
|
cursorColor,
|
|
1549
2149
|
defaultMarkdownSlots,
|
|
2150
|
+
defaultOptions,
|
|
1550
2151
|
defaultSlots,
|
|
1551
2152
|
defaultTextSlots,
|
|
1552
2153
|
defaultTheme,
|
|
1553
2154
|
demo,
|
|
2155
|
+
image,
|
|
1554
2156
|
link,
|
|
1555
2157
|
listener,
|
|
1556
2158
|
markdownBundle,
|
|
1557
2159
|
markdownHighlightStyle,
|
|
1558
2160
|
markdownTags,
|
|
1559
|
-
|
|
2161
|
+
markdownTagsExtensions,
|
|
1560
2162
|
markdownTheme,
|
|
2163
|
+
mention,
|
|
2164
|
+
table,
|
|
1561
2165
|
tags2 as tags,
|
|
1562
2166
|
tasklist,
|
|
1563
2167
|
textTheme,
|