@dxos/react-ui-editor 0.6.9 → 0.6.10-main.e92b5eb
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 +35 -26
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/InputMode.stories.d.ts +1 -1
- package/dist/types/src/InputMode.stories.d.ts.map +1 -1
- package/dist/types/src/TextEditor.stories.d.ts +1 -1
- package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/styles/tokens.d.ts +1 -2
- package/dist/types/src/styles/tokens.d.ts.map +1 -1
- package/package.json +27 -27
- package/src/InputMode.stories.tsx +1 -1
- package/src/TextEditor.stories.tsx +2 -2
- package/src/extensions/automerge/automerge.stories.tsx +1 -1
- package/src/extensions/factories.ts +4 -4
- package/src/extensions/markdown/bundle.ts +3 -0
- package/src/extensions/markdown/decorate.ts +31 -25
- package/src/extensions/markdown/parser.test.ts +29 -0
- package/src/styles/tokens.ts +2 -2
|
@@ -145,7 +145,7 @@ const autoHideTags = new Set([
|
|
|
145
145
|
type NumberingLevel = { type: string; from: number; to: number; level: number; number: number };
|
|
146
146
|
|
|
147
147
|
const bulletListIndentationWidth = 24;
|
|
148
|
-
const orderedListIndentationWidth =
|
|
148
|
+
const orderedListIndentationWidth = 36; // TODO(burdon): Make variable length based on number of digits.
|
|
149
149
|
|
|
150
150
|
const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boolean) => {
|
|
151
151
|
const deco = new RangeSetBuilder<Decoration>();
|
|
@@ -182,8 +182,9 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
182
182
|
return listLevels[listLevels.length - 1];
|
|
183
183
|
};
|
|
184
184
|
|
|
185
|
+
// const count = 0;
|
|
185
186
|
const enterNode = (node: SyntaxNodeRef) => {
|
|
186
|
-
// console.log(
|
|
187
|
+
// console.log(`[${count++}]`, { node: node.name, from: node.from, to: node.to });
|
|
187
188
|
switch (node.name) {
|
|
188
189
|
// ATXHeading > HeaderMark > Paragraph
|
|
189
190
|
// NOTE: Numbering requires processing the entire document since otherwise only the visible range will be
|
|
@@ -253,50 +254,55 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
253
254
|
const list = getCurrentList();
|
|
254
255
|
const width = list.type === 'OrderedList' ? orderedListIndentationWidth : bulletListIndentationWidth;
|
|
255
256
|
const offset = ((list.level ?? 0) + 1) * width;
|
|
256
|
-
const
|
|
257
|
+
const line = state.doc.lineAt(node.from);
|
|
258
|
+
if (node.from === line.to - 1) {
|
|
259
|
+
// Abort if only the hyphen is typed.
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
257
262
|
|
|
263
|
+
// Add line decoration to indent.
|
|
258
264
|
deco.add(
|
|
259
|
-
|
|
260
|
-
|
|
265
|
+
line.from,
|
|
266
|
+
line.from,
|
|
261
267
|
Decoration.line({
|
|
262
268
|
class: 'cm-list-item',
|
|
263
269
|
attributes: {
|
|
264
|
-
|
|
265
|
-
// Note: This makes the cursor appear to be left of the margin.
|
|
266
|
-
style: `padding-left: ${offset}px; text-indent: calc(-${width}px - 0.25em);`,
|
|
270
|
+
style: `padding-left: ${offset}px; text-indent: -${width}px;`,
|
|
267
271
|
},
|
|
268
272
|
}),
|
|
269
273
|
);
|
|
270
274
|
|
|
271
275
|
// Remove indentation spaces.
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
const whitespace = line.match(/^ */)?.[0].length ?? 0;
|
|
276
|
+
const text = state.doc.sliceString(line.from, node.to);
|
|
277
|
+
const whitespace = text.match(/^ */)?.[0].length ?? 0;
|
|
275
278
|
if (whitespace) {
|
|
276
|
-
atomicDeco.add(
|
|
279
|
+
atomicDeco.add(line.from, line.from + whitespace, hide);
|
|
277
280
|
}
|
|
278
281
|
|
|
279
|
-
// const mark = node.node.firstChild!;
|
|
280
|
-
// console.log(mark?.name);
|
|
281
|
-
// if (mark?.name === 'ListMark') {}
|
|
282
282
|
break;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
case 'ListMark': {
|
|
286
286
|
// Look-ahead for task marker.
|
|
287
|
-
const
|
|
288
|
-
if (
|
|
289
|
-
atomicDeco.add(node.from, node.to, hide);
|
|
287
|
+
const next = tree.resolve(node.to + 1, 1);
|
|
288
|
+
if (next?.name === 'TaskMarker') {
|
|
289
|
+
atomicDeco.add(node.from, node.to + 1, hide);
|
|
290
290
|
break;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
// TODO(burdon): Cursor stops for 1 character when moving back into number (but not dashes).
|
|
294
|
-
// TODO(burdon): Option to make hierarchical; or a, b, c. etc.
|
|
295
293
|
const list = getCurrentList();
|
|
296
|
-
|
|
294
|
+
|
|
295
|
+
// Abort unless followed by space.
|
|
296
|
+
const text = state.doc.sliceString(node.from, node.to + 1);
|
|
297
|
+
if (list.type === 'BulletList' && text[1] !== ' ') {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// TODO(burdon): Option to make hierarchical; or a), i), etc.
|
|
302
|
+
const label = list.type === 'OrderedList' ? `${++list.number}.` : '•';
|
|
297
303
|
atomicDeco.add(
|
|
298
304
|
node.from,
|
|
299
|
-
node.to,
|
|
305
|
+
node.to + 1,
|
|
300
306
|
Decoration.replace({
|
|
301
307
|
widget: new TextWidget(
|
|
302
308
|
label,
|
|
@@ -310,8 +316,7 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
310
316
|
case 'TaskMarker': {
|
|
311
317
|
if (!editingRange(state, node, focus)) {
|
|
312
318
|
const checked = state.doc.sliceString(node.from + 1, node.to - 1) === 'x';
|
|
313
|
-
atomicDeco.add(node.from
|
|
314
|
-
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
319
|
+
atomicDeco.add(node.from, node.to + 1, checked ? checkedTask : uncheckedTask);
|
|
315
320
|
}
|
|
316
321
|
break;
|
|
317
322
|
}
|
|
@@ -574,7 +579,7 @@ const formattingStyles = EditorView.baseTheme({
|
|
|
574
579
|
|
|
575
580
|
'& .cm-task': {
|
|
576
581
|
display: 'inline-block',
|
|
577
|
-
width:
|
|
582
|
+
width: `${bulletListIndentationWidth}px`,
|
|
578
583
|
color: getToken('extend.colors.blue.500'),
|
|
579
584
|
},
|
|
580
585
|
'& .cm-task-checkbox': {
|
|
@@ -587,6 +592,7 @@ const formattingStyles = EditorView.baseTheme({
|
|
|
587
592
|
'& .cm-list-mark': {
|
|
588
593
|
display: 'inline-block',
|
|
589
594
|
textAlign: 'right',
|
|
595
|
+
paddingRight: '0.5em',
|
|
590
596
|
fontVariant: 'tabular-nums',
|
|
591
597
|
},
|
|
592
598
|
'& .cm-list-mark-bullet': {
|
|
@@ -9,6 +9,34 @@ import { parser } from '@lezer/markdown';
|
|
|
9
9
|
import { describe, test } from '@dxos/test';
|
|
10
10
|
|
|
11
11
|
describe('parser', () => {
|
|
12
|
+
// test.only('list-mark', () => {
|
|
13
|
+
// const newParser = parser.configure({
|
|
14
|
+
// parseBlock: [
|
|
15
|
+
// {
|
|
16
|
+
// name: 'ListItem',
|
|
17
|
+
// parse: (cx, line) => {
|
|
18
|
+
// console.log(`[${line.text}]`, cx.lineStart, line.text.length);
|
|
19
|
+
// // line.skipSpace(1);
|
|
20
|
+
// return true;
|
|
21
|
+
// },
|
|
22
|
+
// },
|
|
23
|
+
// ],
|
|
24
|
+
// });
|
|
25
|
+
//
|
|
26
|
+
// {
|
|
27
|
+
// const result = newParser.parse(' - ');
|
|
28
|
+
// testTree(result, 'Document(BulletList(ListItem(ListMark)))');
|
|
29
|
+
// }
|
|
30
|
+
// {
|
|
31
|
+
// const result = newParser.parse('-x');
|
|
32
|
+
// testTree(result, 'Document(Paragraph)');
|
|
33
|
+
// }
|
|
34
|
+
// {
|
|
35
|
+
// const result = newParser.parse('- x');
|
|
36
|
+
// testTree(result, 'Document(BulletList(ListItem(ListMark,Paragraph)))');
|
|
37
|
+
// }
|
|
38
|
+
// });
|
|
39
|
+
|
|
12
40
|
// https://www.markdownguide.org/basic-syntax/#lists-1
|
|
13
41
|
test('lists', () => {
|
|
14
42
|
// Indented list must have 4 spaces.
|
|
@@ -25,6 +53,7 @@ describe('parser', () => {
|
|
|
25
53
|
'1. one',
|
|
26
54
|
].join('\n'),
|
|
27
55
|
);
|
|
56
|
+
|
|
28
57
|
testTree(
|
|
29
58
|
result,
|
|
30
59
|
[
|
package/src/styles/tokens.ts
CHANGED
|
@@ -9,9 +9,9 @@ import { tailwindConfig, type TailwindConfig } from '@dxos/react-ui-theme';
|
|
|
9
9
|
const tokens: TailwindConfig['theme'] = tailwindConfig({}).theme;
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
* Replace with CSS vars.
|
|
12
|
+
* Returns the tailwind token value.
|
|
14
13
|
*/
|
|
14
|
+
// TODO(burdon): Replace with CSS vars.
|
|
15
15
|
export const getToken = (path: string, defaultValue?: string | string[]): string => {
|
|
16
16
|
const value = get(tokens, path, defaultValue);
|
|
17
17
|
return value?.toString() ?? '';
|