@dxos/react-ui-editor 0.6.13-staging.1e988a3 → 0.6.14-main.2b6a0f3
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/chunk-CIQSMP7K.mjs +148 -0
- package/dist/lib/browser/chunk-CIQSMP7K.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +248 -355
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/state/index.mjs +17 -0
- package/dist/lib/browser/state/index.mjs.map +7 -0
- package/dist/lib/node/chunk-GZWIENFM.cjs +169 -0
- package/dist/lib/node/chunk-GZWIENFM.cjs.map +7 -0
- package/dist/lib/node/index.cjs +5491 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/state/index.cjs +39 -0
- package/dist/lib/node/state/index.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs +150 -0
- package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +5482 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/state/index.mjs +18 -0
- package/dist/lib/node-esm/state/index.mjs.map +7 -0
- package/dist/types/src/InputMode.stories.d.ts +11 -11
- package/dist/types/src/InputMode.stories.d.ts.map +1 -1
- package/dist/types/src/TextEditor.stories.d.ts +4 -1
- package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts +2 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts +2 -2
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/command/state.d.ts +2 -2
- package/dist/types/src/extensions/command/state.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts +2 -2
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -4
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/listener.d.ts +1 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +3 -3
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/util/overlap.d.ts +1 -1
- package/dist/types/src/extensions/util/overlap.d.ts.map +1 -1
- package/dist/types/src/extensions/util/react.d.ts +1 -1
- package/dist/types/src/extensions/util/react.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/{extensions → state}/cursor.d.ts +2 -2
- package/dist/types/src/state/cursor.d.ts.map +1 -0
- package/dist/types/src/state/doc.d.ts +5 -0
- package/dist/types/src/state/doc.d.ts.map +1 -0
- package/dist/types/src/state/index.d.ts +6 -0
- package/dist/types/src/state/index.d.ts.map +1 -0
- package/dist/types/src/{extensions → state}/state.d.ts +2 -2
- package/dist/types/src/state/state.d.ts.map +1 -0
- package/dist/types/src/state/types.d.ts.map +1 -0
- package/dist/types/src/state/util.d.ts +3 -0
- package/dist/types/src/state/util.d.ts.map +1 -0
- package/dist/types/src/styles/markdown.d.ts +1 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +6 -0
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +61 -41
- package/src/InputMode.stories.tsx +8 -8
- package/src/TextEditor.stories.tsx +93 -70
- package/src/components/Toolbar/Toolbar.tsx +8 -11
- package/src/defaults.ts +0 -2
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/autocomplete.ts +9 -8
- package/src/extensions/automerge/automerge.stories.tsx +2 -2
- package/src/extensions/automerge/{automerge.spec.tsx → automerge.test.tsx} +1 -0
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/cursor.ts +1 -1
- package/src/extensions/awareness/awareness.ts +3 -5
- package/src/extensions/command/hint.ts +1 -1
- package/src/extensions/command/state.ts +3 -4
- package/src/extensions/comments.ts +44 -45
- package/src/extensions/debug.ts +2 -2
- package/src/extensions/folding.tsx +6 -4
- package/src/extensions/index.ts +0 -4
- package/src/extensions/listener.ts +1 -0
- package/src/extensions/markdown/changes.test.ts +1 -3
- package/src/extensions/markdown/decorate.ts +49 -6
- package/src/extensions/markdown/formatting.test.ts +1 -3
- package/src/extensions/markdown/highlight.ts +0 -5
- package/src/extensions/markdown/link.ts +3 -2
- package/src/extensions/markdown/parser.test.ts +1 -2
- package/src/extensions/markdown/styles.ts +10 -0
- package/src/extensions/markdown/table.ts +3 -3
- package/src/extensions/modes.ts +6 -5
- package/src/extensions/util/overlap.ts +1 -1
- package/src/extensions/util/react.tsx +6 -1
- package/src/hooks/useTextEditor.ts +36 -32
- package/src/index.ts +1 -0
- package/src/{extensions → state}/cursor.ts +3 -6
- package/src/state/doc.ts +10 -0
- package/src/state/index.ts +11 -0
- package/src/{extensions → state}/state.ts +7 -3
- package/src/state/util.ts +13 -0
- package/src/styles/markdown.ts +1 -3
- package/src/styles/theme.ts +3 -1
- package/src/util.ts +10 -0
- package/dist/types/src/extensions/automerge/automerge.spec.d.ts +0 -2
- package/dist/types/src/extensions/automerge/automerge.spec.d.ts.map +0 -1
- package/dist/types/src/extensions/cursor.d.ts.map +0 -1
- package/dist/types/src/extensions/doc.d.ts +0 -6
- package/dist/types/src/extensions/doc.d.ts.map +0 -1
- package/dist/types/src/extensions/state.d.ts.map +0 -1
- package/dist/types/src/extensions/types.d.ts.map +0 -1
- package/src/extensions/automerge/automerge.test.ts +0 -13
- package/src/extensions/doc.ts +0 -17
- /package/dist/types/src/{extensions → state}/types.d.ts +0 -0
- /package/src/{extensions → state}/types.ts +0 -0
@@ -3,6 +3,7 @@
|
|
3
3
|
//
|
4
4
|
|
5
5
|
import '@dxos-theme';
|
6
|
+
|
6
7
|
import { javascript } from '@codemirror/lang-javascript';
|
7
8
|
import { markdown } from '@codemirror/lang-markdown';
|
8
9
|
import { openSearchPanel } from '@codemirror/search';
|
@@ -19,8 +20,8 @@ import { keySymbols, parseShortcut } from '@dxos/keyboard';
|
|
19
20
|
import { PublicKey } from '@dxos/keys';
|
20
21
|
import { log } from '@dxos/log';
|
21
22
|
import { faker } from '@dxos/random';
|
22
|
-
import { createDocAccessor,
|
23
|
-
import { Button,
|
23
|
+
import { createDocAccessor, createObject } from '@dxos/react-client/echo';
|
24
|
+
import { Button, Input, useThemeContext } from '@dxos/react-ui';
|
24
25
|
import { baseSurface, mx, getSize } from '@dxos/react-ui-theme';
|
25
26
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
26
27
|
|
@@ -37,6 +38,7 @@ import {
|
|
37
38
|
createExternalCommentSync,
|
38
39
|
createMarkdownExtensions,
|
39
40
|
createThemeExtensions,
|
41
|
+
debugTree,
|
40
42
|
decorateMarkdown,
|
41
43
|
defaultOptions,
|
42
44
|
dropFile,
|
@@ -46,18 +48,15 @@ import {
|
|
46
48
|
linkTooltip,
|
47
49
|
listener,
|
48
50
|
mention,
|
49
|
-
state,
|
50
51
|
table,
|
51
52
|
typewriter,
|
52
53
|
type CommandAction,
|
53
|
-
type Comment,
|
54
54
|
type CommentsOptions,
|
55
|
-
type EditorSelectionState,
|
56
|
-
debugTree,
|
57
55
|
type DebugNode,
|
58
56
|
} from './extensions';
|
59
57
|
import { renderRoot } from './extensions/util';
|
60
58
|
import { useTextEditor, type UseTextEditorProps } from './hooks';
|
59
|
+
import { type Comment, type EditorSelectionState, state } from './state';
|
61
60
|
import translations from './translations';
|
62
61
|
|
63
62
|
faker.seed(101);
|
@@ -164,8 +163,8 @@ const content = {
|
|
164
163
|
'> This is a long wrapping block quote. Neque reiciendis ullam quae error labore sit, at, et, nulla, aut at nostrum omnis quas nostrum, at consectetur vitae eos asperiores non omnis ullam in beatae at vitae deserunt asperiores sapiente.',
|
165
164
|
'',
|
166
165
|
'> This is ...',
|
167
|
-
'
|
168
|
-
'
|
166
|
+
'... a multi-line ...',
|
167
|
+
'block quote.',
|
169
168
|
'',
|
170
169
|
),
|
171
170
|
|
@@ -254,7 +253,7 @@ const renderLinkButton = (el: Element, url: string) => {
|
|
254
253
|
// Story
|
255
254
|
//
|
256
255
|
|
257
|
-
type DebugMode = '
|
256
|
+
type DebugMode = 'raw' | 'tree' | 'raw+tree';
|
258
257
|
|
259
258
|
type StoryProps = {
|
260
259
|
id?: string;
|
@@ -266,7 +265,7 @@ type StoryProps = {
|
|
266
265
|
onReady?: (view: EditorView) => void;
|
267
266
|
} & Pick<UseTextEditorProps, 'scrollTo' | 'selection' | 'extensions'>;
|
268
267
|
|
269
|
-
const
|
268
|
+
const DefaultStory = ({
|
270
269
|
id = 'editor-' + PublicKey.random().toHex().slice(0, 8),
|
271
270
|
debug,
|
272
271
|
text,
|
@@ -278,7 +277,7 @@ const Story = ({
|
|
278
277
|
lineNumbers,
|
279
278
|
onReady,
|
280
279
|
}: StoryProps) => {
|
281
|
-
const [object] = useState(
|
280
|
+
const [object] = useState(createObject(create(Expando, { content: text ?? '' })));
|
282
281
|
const { themeMode } = useThemeContext();
|
283
282
|
const [tree, setTree] = useState<DebugNode>();
|
284
283
|
const { parentRef, focusAttributes, view } = useTextEditor(
|
@@ -317,16 +316,16 @@ const Story = ({
|
|
317
316
|
return (
|
318
317
|
<div className='flex w-full'>
|
319
318
|
<div role='none' className='flex w-full overflow-hidden' ref={parentRef} {...focusAttributes} />
|
320
|
-
{debug
|
321
|
-
<div className='w-[800px] border-l border-separator overflow-auto'>
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
319
|
+
{debug && (
|
320
|
+
<div className='flex flex-col w-[800px] border-l border-separator divide-y divide-separator overflow-auto'>
|
321
|
+
{(debug === 'raw' || debug === 'raw+tree') && (
|
322
|
+
<pre className='p-1 font-mono text-xs text-green-800 dark:text-green-200'>{view?.state.doc.toString()}</pre>
|
323
|
+
)}
|
324
|
+
{(debug === 'tree' || debug === 'raw+tree') && (
|
325
|
+
<pre className='p-1 font-mono text-xs text-green-800 dark:text-green-200'>
|
326
|
+
{JSON.stringify(tree, null, 2)}
|
327
|
+
</pre>
|
328
|
+
)}
|
330
329
|
</div>
|
331
330
|
)}
|
332
331
|
</div>
|
@@ -334,9 +333,9 @@ const Story = ({
|
|
334
333
|
};
|
335
334
|
|
336
335
|
export default {
|
337
|
-
title: 'react-ui-editor/TextEditor',
|
336
|
+
title: 'ui/react-ui-editor/TextEditor',
|
338
337
|
decorators: [withTheme, withLayout({ fullscreen: true })],
|
339
|
-
render:
|
338
|
+
render: DefaultStory,
|
340
339
|
parameters: { translations, layout: 'fullscreen' },
|
341
340
|
};
|
342
341
|
|
@@ -362,28 +361,28 @@ const allExtensions: Extension[] = [
|
|
362
361
|
];
|
363
362
|
|
364
363
|
export const Default = {
|
365
|
-
render: () => <
|
364
|
+
render: () => <DefaultStory text={text} extensions={defaultExtensions} />,
|
366
365
|
};
|
367
366
|
|
368
367
|
export const Everything = {
|
369
|
-
render: () => <
|
368
|
+
render: () => <DefaultStory text={text} extensions={allExtensions} selection={{ anchor: 99, head: 110 }} />,
|
370
369
|
};
|
371
370
|
|
372
371
|
export const Empty = {
|
373
|
-
render: () => <
|
372
|
+
render: () => <DefaultStory extensions={defaultExtensions} />,
|
374
373
|
};
|
375
374
|
|
376
375
|
export const Readonly = {
|
377
|
-
render: () => <
|
376
|
+
render: () => <DefaultStory text={text} extensions={defaultExtensions} readonly />,
|
378
377
|
};
|
379
378
|
|
380
379
|
export const NoExtensions = {
|
381
|
-
render: () => <
|
380
|
+
render: () => <DefaultStory text={text} />,
|
382
381
|
};
|
383
382
|
|
384
383
|
export const Vim = {
|
385
384
|
render: () => (
|
386
|
-
<
|
385
|
+
<DefaultStory
|
387
386
|
text={str('# Vim Mode', '', 'The distant future. The year 2000.', '', content.paragraphs)}
|
388
387
|
extensions={[defaultExtensions, InputModeExtensions.vim]}
|
389
388
|
/>
|
@@ -410,12 +409,12 @@ const headings = str(
|
|
410
409
|
const global = new Map<string, EditorSelectionState>();
|
411
410
|
|
412
411
|
export const Folding = {
|
413
|
-
render: () => <
|
412
|
+
render: () => <DefaultStory text={text} extensions={[folding()]} />,
|
414
413
|
};
|
415
414
|
|
416
415
|
export const Scrolling = {
|
417
416
|
render: () => (
|
418
|
-
<
|
417
|
+
<DefaultStory
|
419
418
|
text={str('# Large Document', '', longText)}
|
420
419
|
extensions={state({
|
421
420
|
setState: (id, state) => global.set(id, state),
|
@@ -427,7 +426,7 @@ export const Scrolling = {
|
|
427
426
|
|
428
427
|
export const ScrollingWithImages = {
|
429
428
|
render: () => (
|
430
|
-
<
|
429
|
+
<DefaultStory text={str('# Large Document', '', largeWithImages)} extensions={[decorateMarkdown(), image()]} />
|
431
430
|
),
|
432
431
|
};
|
433
432
|
|
@@ -438,7 +437,7 @@ export const ScrollTo = {
|
|
438
437
|
const text = str('# Scroll To', longText, '', word, '', longText);
|
439
438
|
const idx = text.indexOf(word);
|
440
439
|
return (
|
441
|
-
<
|
440
|
+
<DefaultStory
|
442
441
|
text={text}
|
443
442
|
extensions={defaultExtensions}
|
444
443
|
scrollTo={idx}
|
@@ -452,25 +451,39 @@ export const ScrollTo = {
|
|
452
451
|
// Markdown
|
453
452
|
//
|
454
453
|
|
454
|
+
export const Blockquote = {
|
455
|
+
render: () => (
|
456
|
+
<DefaultStory
|
457
|
+
text={str('> Blockquote', 'continuation', content.footer)}
|
458
|
+
extensions={decorateMarkdown()}
|
459
|
+
debug='raw'
|
460
|
+
/>
|
461
|
+
),
|
462
|
+
};
|
463
|
+
|
455
464
|
export const Headings = {
|
456
|
-
render: () =>
|
465
|
+
render: () => (
|
466
|
+
<DefaultStory text={headings} extensions={decorateMarkdown({ numberedHeadings: { from: 2, to: 4 } })} />
|
467
|
+
),
|
457
468
|
};
|
458
469
|
|
459
470
|
export const Links = {
|
460
|
-
render: () =>
|
471
|
+
render: () => (
|
472
|
+
<DefaultStory text={str(content.links, content.footer)} extensions={[linkTooltip(renderLinkTooltip)]} />
|
473
|
+
),
|
461
474
|
};
|
462
475
|
|
463
476
|
export const Image = {
|
464
|
-
render: () => <
|
477
|
+
render: () => <DefaultStory text={str(content.image, content.footer)} extensions={[image()]} />,
|
465
478
|
};
|
466
479
|
|
467
480
|
export const Code = {
|
468
|
-
render: () => <
|
481
|
+
render: () => <DefaultStory text={str(content.codeblocks, content.footer)} extensions={[decorateMarkdown()]} />,
|
469
482
|
};
|
470
483
|
|
471
484
|
export const Lists = {
|
472
485
|
render: () => (
|
473
|
-
<
|
486
|
+
<DefaultStory
|
474
487
|
text={str(content.tasks, '', content.bullets, '', content.numbered, content.footer)}
|
475
488
|
extensions={[decorateMarkdown()]}
|
476
489
|
/>
|
@@ -478,24 +491,26 @@ export const Lists = {
|
|
478
491
|
};
|
479
492
|
|
480
493
|
export const BulletList = {
|
481
|
-
render: () => <
|
494
|
+
render: () => <DefaultStory text={str(content.bullets, content.footer)} extensions={[decorateMarkdown()]} />,
|
482
495
|
};
|
483
496
|
|
484
497
|
export const OrderedList = {
|
485
|
-
render: () => <
|
498
|
+
render: () => <DefaultStory text={str(content.numbered, content.footer)} extensions={[decorateMarkdown()]} />,
|
486
499
|
};
|
487
500
|
|
488
501
|
export const TaskList = {
|
489
|
-
render: () =>
|
502
|
+
render: () => (
|
503
|
+
<DefaultStory text={str(content.tasks, content.footer)} extensions={[decorateMarkdown()]} debug='raw+tree' />
|
504
|
+
),
|
490
505
|
};
|
491
506
|
|
492
507
|
export const Table = {
|
493
|
-
render: () => <
|
508
|
+
render: () => <DefaultStory text={str(content.table, content.footer)} extensions={[decorateMarkdown(), table()]} />,
|
494
509
|
};
|
495
510
|
|
496
511
|
export const CommentedOut = {
|
497
512
|
render: () => (
|
498
|
-
<
|
513
|
+
<DefaultStory
|
499
514
|
text={str('# Commented out', '', content.comment, content.footer)}
|
500
515
|
extensions={[
|
501
516
|
decorateMarkdown(),
|
@@ -508,7 +523,11 @@ export const CommentedOut = {
|
|
508
523
|
|
509
524
|
export const Typescript = {
|
510
525
|
render: () => (
|
511
|
-
<
|
526
|
+
<DefaultStory
|
527
|
+
text={content.typescript}
|
528
|
+
lineNumbers
|
529
|
+
extensions={[editorMonospace, javascript({ typescript: true })]}
|
530
|
+
/>
|
512
531
|
),
|
513
532
|
};
|
514
533
|
|
@@ -518,7 +537,7 @@ export const Typescript = {
|
|
518
537
|
|
519
538
|
export const Autocomplete = {
|
520
539
|
render: () => (
|
521
|
-
<
|
540
|
+
<DefaultStory
|
522
541
|
text={str('# Autocomplete', '', 'Press Ctrl-Space...', content.footer)}
|
523
542
|
extensions={[
|
524
543
|
decorateMarkdown({ renderLinkButton }),
|
@@ -532,7 +551,7 @@ export const Autocomplete = {
|
|
532
551
|
|
533
552
|
export const Mention = {
|
534
553
|
render: () => (
|
535
|
-
<
|
554
|
+
<DefaultStory
|
536
555
|
text={str('# Mention', '', 'Type @...', content.footer)}
|
537
556
|
extensions={[
|
538
557
|
mention({
|
@@ -545,7 +564,11 @@ export const Mention = {
|
|
545
564
|
|
546
565
|
export const Search = {
|
547
566
|
render: () => (
|
548
|
-
<
|
567
|
+
<DefaultStory
|
568
|
+
text={str('# Search', text)}
|
569
|
+
extensions={defaultExtensions}
|
570
|
+
onReady={(view) => openSearchPanel(view)}
|
571
|
+
/>
|
549
572
|
),
|
550
573
|
};
|
551
574
|
|
@@ -569,28 +592,26 @@ const CommandDialog = ({ onClose }: { onClose: (action?: CommandAction) => void
|
|
569
592
|
};
|
570
593
|
|
571
594
|
return (
|
572
|
-
<
|
573
|
-
<
|
574
|
-
<Input.
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
<
|
584
|
-
|
585
|
-
|
586
|
-
</div>
|
587
|
-
</DensityProvider>
|
595
|
+
<div className={mx('flex items-center p-2 gap-2 border rounded-md', baseSurface)}>
|
596
|
+
<Input.Root>
|
597
|
+
<Input.TextInput
|
598
|
+
autoFocus={true}
|
599
|
+
placeholder='Enter command.'
|
600
|
+
value={text}
|
601
|
+
onChange={({ target: { value } }) => setText(value)}
|
602
|
+
onKeyDown={handleKeyDown}
|
603
|
+
/>
|
604
|
+
</Input.Root>
|
605
|
+
<Button variant='ghost' classNames='pli-0' onClick={() => onClose()}>
|
606
|
+
<X className={getSize(5)} />
|
607
|
+
</Button>
|
608
|
+
</div>
|
588
609
|
);
|
589
610
|
};
|
590
611
|
|
591
612
|
export const Command = {
|
592
613
|
render: () => (
|
593
|
-
<
|
614
|
+
<DefaultStory
|
594
615
|
text={str('# Command', '')}
|
595
616
|
extensions={[
|
596
617
|
command({
|
@@ -608,7 +629,7 @@ export const Comments = {
|
|
608
629
|
render: () => {
|
609
630
|
const _comments = useSignal<Comment[]>([]);
|
610
631
|
return (
|
611
|
-
<
|
632
|
+
<DefaultStory
|
612
633
|
text={str('# Comments', '', content.paragraphs, content.footer)}
|
613
634
|
extensions={[
|
614
635
|
createExternalCommentSync(
|
@@ -645,12 +666,14 @@ export const Comments = {
|
|
645
666
|
};
|
646
667
|
|
647
668
|
export const Annotations = {
|
648
|
-
render: () =>
|
669
|
+
render: () => (
|
670
|
+
<DefaultStory text={str('# Annotations', '', longText)} extensions={[annotations({ match: /volup/gi })]} />
|
671
|
+
),
|
649
672
|
};
|
650
673
|
|
651
674
|
export const DND = {
|
652
675
|
render: () => (
|
653
|
-
<
|
676
|
+
<DefaultStory
|
654
677
|
text={str('# DND', '')}
|
655
678
|
extensions={[
|
656
679
|
dropFile({
|
@@ -665,7 +688,7 @@ export const DND = {
|
|
665
688
|
|
666
689
|
export const Listener = {
|
667
690
|
render: () => (
|
668
|
-
<
|
691
|
+
<DefaultStory
|
669
692
|
text={str('# Listener', '', content.footer)}
|
670
693
|
extensions={[
|
671
694
|
listener({
|
@@ -685,7 +708,7 @@ const typewriterItems = localStorage.getItem('dxos.org/plugin/markdown/typewrite
|
|
685
708
|
|
686
709
|
export const Typewriter = {
|
687
710
|
render: () => (
|
688
|
-
<
|
711
|
+
<DefaultStory
|
689
712
|
text={str('# Typewriter', '', content.paragraphs, content.footer)}
|
690
713
|
extensions={[typewriter({ items: typewriterItems })]}
|
691
714
|
/>
|
@@ -694,7 +717,7 @@ export const Typewriter = {
|
|
694
717
|
|
695
718
|
export const Blast = {
|
696
719
|
render: () => (
|
697
|
-
<
|
720
|
+
<DefaultStory
|
698
721
|
text={str('# Blast', '', content.paragraphs, content.codeblocks, content.paragraphs)}
|
699
722
|
extensions={[
|
700
723
|
typewriter({ items: typewriterItems }),
|
@@ -37,7 +37,6 @@ import { useDropzone } from 'react-dropzone';
|
|
37
37
|
|
38
38
|
import {
|
39
39
|
Button,
|
40
|
-
DensityProvider,
|
41
40
|
DropdownMenu,
|
42
41
|
ElevationProvider,
|
43
42
|
Toolbar as NaturalToolbar,
|
@@ -74,16 +73,14 @@ export type ToolbarProps = ThemedClassName<
|
|
74
73
|
const ToolbarRoot = ({ children, onAction, classNames, state }: ToolbarProps) => {
|
75
74
|
return (
|
76
75
|
<ToolbarContextProvider onAction={onAction} state={state}>
|
77
|
-
<
|
78
|
-
<
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
</ElevationProvider>
|
86
|
-
</DensityProvider>
|
76
|
+
<ElevationProvider elevation='chrome'>
|
77
|
+
<NaturalToolbar.Root
|
78
|
+
classNames={['p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden', classNames]}
|
79
|
+
style={{ contain: 'layout' }}
|
80
|
+
>
|
81
|
+
{children}
|
82
|
+
</NaturalToolbar.Root>
|
83
|
+
</ElevationProvider>
|
87
84
|
</ToolbarContextProvider>
|
88
85
|
);
|
89
86
|
};
|
package/src/defaults.ts
CHANGED
@@ -2,10 +2,6 @@
|
|
2
2
|
// Copyright 2023 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
// https://codemirror.net/examples/autocompletion
|
6
|
-
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
7
|
-
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
8
|
-
|
9
5
|
import {
|
10
6
|
autocompletion,
|
11
7
|
completionKeymap,
|
@@ -15,6 +11,7 @@ import {
|
|
15
11
|
type CompletionResult,
|
16
12
|
} from '@codemirror/autocomplete';
|
17
13
|
import { markdownLanguage } from '@codemirror/lang-markdown';
|
14
|
+
import { type Extension } from '@codemirror/state';
|
18
15
|
import { keymap } from '@codemirror/view';
|
19
16
|
|
20
17
|
export type AutocompleteResult = Completion;
|
@@ -25,11 +22,15 @@ export type AutocompleteOptions = {
|
|
25
22
|
onSearch?: (text: string) => Completion[];
|
26
23
|
};
|
27
24
|
|
25
|
+
// https://codemirror.net/examples/autocompletion
|
26
|
+
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
27
|
+
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
28
|
+
|
28
29
|
/**
|
29
30
|
* Autocomplete extension.
|
30
31
|
*/
|
31
|
-
export const autocomplete = ({ activateOnTyping, override, onSearch }: AutocompleteOptions = {}) => {
|
32
|
-
const
|
32
|
+
export const autocomplete = ({ activateOnTyping, override, onSearch }: AutocompleteOptions = {}): Extension => {
|
33
|
+
const extensions: Extension[] = [
|
33
34
|
// https://codemirror.net/docs/ref/#view.keymap
|
34
35
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
35
36
|
// TODO(burdon): Set custom keymap.
|
@@ -50,7 +51,7 @@ export const autocomplete = ({ activateOnTyping, override, onSearch }: Autocompl
|
|
50
51
|
];
|
51
52
|
|
52
53
|
if (onSearch) {
|
53
|
-
|
54
|
+
extensions.push(
|
54
55
|
// TODO(burdon): Optional decoration via addToOptions
|
55
56
|
markdownLanguage.data.of({
|
56
57
|
autocomplete: (context: CompletionContext): CompletionResult | null => {
|
@@ -68,5 +69,5 @@ export const autocomplete = ({ activateOnTyping, override, onSearch }: Autocompl
|
|
68
69
|
);
|
69
70
|
}
|
70
71
|
|
71
|
-
return
|
72
|
+
return extensions;
|
72
73
|
};
|
@@ -92,7 +92,7 @@ const Story = () => {
|
|
92
92
|
};
|
93
93
|
|
94
94
|
export default {
|
95
|
-
title: 'react-ui-editor/Automerge',
|
95
|
+
title: 'ui/react-ui-editor/Automerge',
|
96
96
|
component: Editor,
|
97
97
|
decorators: [withTheme, withLayout({ fullscreen: true })],
|
98
98
|
render: () => <Story />,
|
@@ -129,7 +129,7 @@ export const WithEcho = {
|
|
129
129
|
count={2}
|
130
130
|
component={EchoStory}
|
131
131
|
createSpace
|
132
|
-
|
132
|
+
onSpaceCreated={async ({ space }) => {
|
133
133
|
space.db.add(
|
134
134
|
create({
|
135
135
|
type: 'test',
|
@@ -5,6 +5,7 @@
|
|
5
5
|
import { EditorState } from '@codemirror/state';
|
6
6
|
import { EditorView } from '@codemirror/view';
|
7
7
|
import { render, screen } from '@testing-library/react';
|
8
|
+
// TODO(wittjosiah): Move to vitest expect (and remove from package.json).
|
8
9
|
import chai, { expect } from 'chai';
|
9
10
|
import chaiDom from 'chai-dom';
|
10
11
|
import get from 'lodash.get';
|
@@ -1,5 +1,5 @@
|
|
1
1
|
//
|
2
|
-
// Copyright
|
2
|
+
// Copyright 2024 DXOS.org
|
3
3
|
// Copyright 2024 Automerge
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
5
5
|
//
|
@@ -13,7 +13,7 @@ import { type DocAccessor } from '@dxos/react-client/echo';
|
|
13
13
|
import { cursorConverter } from './cursor';
|
14
14
|
import { updateHeadsEffect, isReconcile, type State } from './defs';
|
15
15
|
import { Syncer } from './sync';
|
16
|
-
import { Cursor } from '
|
16
|
+
import { Cursor } from '../../state';
|
17
17
|
|
18
18
|
export const automerge = (accessor: DocAccessor): Extension => {
|
19
19
|
const syncState = StateField.define<State>({
|
@@ -5,7 +5,7 @@
|
|
5
5
|
import { log } from '@dxos/log';
|
6
6
|
import { type DocAccessor, fromCursor, toCursor } from '@dxos/react-client/echo';
|
7
7
|
|
8
|
-
import { type CursorConverter } from '
|
8
|
+
import { type CursorConverter } from '../../state';
|
9
9
|
|
10
10
|
export const cursorConverter = (accessor: DocAccessor): CursorConverter => ({
|
11
11
|
toCursor: (pos, assoc) => {
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import { Annotation,
|
5
|
+
import { Annotation, type Extension, RangeSet, type Range } from '@codemirror/state';
|
6
6
|
import {
|
7
7
|
Decoration,
|
8
8
|
type DecorationSet,
|
@@ -16,7 +16,7 @@ import {
|
|
16
16
|
import { Event } from '@dxos/async';
|
17
17
|
import { Context } from '@dxos/context';
|
18
18
|
|
19
|
-
import { Cursor, type CursorConverter } from '
|
19
|
+
import { singleValueFacet, Cursor, type CursorConverter } from '../../state';
|
20
20
|
|
21
21
|
export interface AwarenessProvider {
|
22
22
|
remoteStateChange: Event<void>;
|
@@ -38,9 +38,7 @@ const dummyProvider: AwarenessProvider = {
|
|
38
38
|
update: () => {},
|
39
39
|
};
|
40
40
|
|
41
|
-
export const awarenessProvider =
|
42
|
-
combine: (providers) => providers[0] ?? dummyProvider,
|
43
|
-
});
|
41
|
+
export const awarenessProvider = singleValueFacet<AwarenessProvider>(dummyProvider);
|
44
42
|
|
45
43
|
// TODO(dmaretskyi): Specify the users that actually changed. Currently, we recalculate positions for every user.
|
46
44
|
const RemoteSelectionChangedAnnotation = Annotation.define();
|
@@ -7,7 +7,7 @@ import { Decoration, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from
|
|
7
7
|
|
8
8
|
import { type CommandOptions } from './command';
|
9
9
|
import { commandState } from './state';
|
10
|
-
import { clientRectsFor, flattenRect } from '../util
|
10
|
+
import { clientRectsFor, flattenRect } from '../util';
|
11
11
|
|
12
12
|
class CommandHint extends WidgetType {
|
13
13
|
constructor(readonly content: string | HTMLElement) {
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import {
|
5
|
+
import { StateEffect, StateField } from '@codemirror/state';
|
6
6
|
import {
|
7
7
|
type Command,
|
8
8
|
type EditorView,
|
@@ -13,14 +13,13 @@ import {
|
|
13
13
|
} from '@codemirror/view';
|
14
14
|
|
15
15
|
import { type CommandOptions } from './command';
|
16
|
+
import { singleValueFacet } from '../../state';
|
16
17
|
|
17
18
|
type CommandState = {
|
18
19
|
tooltip?: Tooltip | null;
|
19
20
|
};
|
20
21
|
|
21
|
-
export const commandConfig =
|
22
|
-
combine: (providers) => providers[0],
|
23
|
-
});
|
22
|
+
export const commandConfig = singleValueFacet<CommandOptions>();
|
24
23
|
|
25
24
|
export const commandState = StateField.define<CommandState>({
|
26
25
|
create: () => ({}),
|