@dxos/react-ui-editor 0.6.13 → 0.6.14-main.69511f5
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 +769 -705
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +5672 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node-esm/index.mjs +5654 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -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/factories.d.ts +1 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/focus.d.ts +7 -0
- package/dist/types/src/extensions/focus.d.ts.map +1 -0
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -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/image.d.ts +3 -6
- package/dist/types/src/extensions/markdown/image.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/{state.d.ts → selection.d.ts} +8 -4
- package/dist/types/src/extensions/selection.d.ts.map +1 -0
- 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/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/types.d.ts.map +1 -0
- package/dist/types/src/{extensions → util}/cursor.d.ts +9 -3
- package/dist/types/src/util/cursor.d.ts.map +1 -0
- package/dist/types/src/util/debug.d.ts +17 -0
- package/dist/types/src/util/debug.d.ts.map +1 -0
- package/dist/types/src/util/dom.d.ts.map +1 -0
- package/dist/types/src/util/facet.d.ts +3 -0
- package/dist/types/src/util/facet.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +6 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/{extensions/util → util}/react.d.ts +1 -1
- package/dist/types/src/util/react.d.ts.map +1 -0
- package/package.json +46 -41
- package/src/InputMode.stories.tsx +8 -8
- package/src/TextEditor.stories.tsx +100 -75
- 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 +45 -47
- package/src/extensions/debug.ts +2 -2
- package/src/extensions/factories.ts +5 -1
- package/src/extensions/focus.ts +35 -0
- package/src/extensions/folding.tsx +7 -5
- package/src/extensions/index.ts +2 -4
- package/src/extensions/listener.ts +1 -0
- package/src/extensions/markdown/changes.test.ts +1 -3
- package/src/extensions/markdown/decorate.ts +50 -7
- package/src/extensions/markdown/formatting.test.ts +1 -3
- package/src/extensions/markdown/highlight.ts +0 -5
- package/src/extensions/markdown/image.ts +53 -42
- 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/{state.ts → selection.ts} +20 -16
- package/src/hooks/useTextEditor.ts +35 -32
- package/src/index.ts +1 -0
- package/src/styles/markdown.ts +1 -3
- package/src/styles/theme.ts +3 -1
- package/src/{extensions → util}/cursor.ts +11 -8
- package/src/{util.ts → util/debug.ts} +25 -2
- package/src/util/facet.ts +13 -0
- package/src/{extensions/util → util}/index.ts +3 -2
- package/src/{extensions/util → util}/react.tsx +6 -1
- 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/dist/types/src/extensions/util/dom.d.ts.map +0 -1
- package/dist/types/src/extensions/util/error.d.ts +0 -2
- package/dist/types/src/extensions/util/error.d.ts.map +0 -1
- package/dist/types/src/extensions/util/index.d.ts +0 -5
- package/dist/types/src/extensions/util/index.d.ts.map +0 -1
- package/dist/types/src/extensions/util/overlap.d.ts +0 -8
- package/dist/types/src/extensions/util/overlap.d.ts.map +0 -1
- package/dist/types/src/extensions/util/react.d.ts.map +0 -1
- package/dist/types/src/util.d.ts +0 -7
- package/dist/types/src/util.d.ts.map +0 -1
- package/src/extensions/automerge/automerge.test.ts +0 -13
- package/src/extensions/doc.ts +0 -17
- package/src/extensions/util/error.ts +0 -15
- package/src/extensions/util/overlap.ts +0 -12
- /package/dist/types/src/{extensions/types.d.ts → types.d.ts} +0 -0
- /package/dist/types/src/{extensions/util → util}/dom.d.ts +0 -0
- /package/src/{extensions/types.ts → types.ts} +0 -0
- /package/src/{extensions/util → util}/dom.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';
|
@@ -11,7 +12,7 @@ import { type EditorView } from '@codemirror/view';
|
|
11
12
|
import { ArrowSquareOut, X } from '@phosphor-icons/react';
|
12
13
|
import { effect, useSignal } from '@preact/signals-react';
|
13
14
|
import defaultsDeep from 'lodash.defaultsdeep';
|
14
|
-
import React, { type FC, type KeyboardEvent
|
15
|
+
import React, { useEffect, useState, type FC, type KeyboardEvent } from 'react';
|
15
16
|
import { createRoot } from 'react-dom/client';
|
16
17
|
|
17
18
|
import { create, Expando } from '@dxos/echo-schema';
|
@@ -19,14 +20,13 @@ 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,
|
24
|
-
import { baseSurface,
|
23
|
+
import { createDocAccessor, createObject } from '@dxos/react-client/echo';
|
24
|
+
import { Button, Input, useThemeContext } from '@dxos/react-ui';
|
25
|
+
import { baseSurface, getSize, mx } from '@dxos/react-ui-theme';
|
25
26
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
26
27
|
|
27
28
|
import { editorContent, editorGutter, editorMonospace } from './defaults';
|
28
29
|
import {
|
29
|
-
InputModeExtensions,
|
30
30
|
annotations,
|
31
31
|
autocomplete,
|
32
32
|
blast,
|
@@ -37,28 +37,29 @@ import {
|
|
37
37
|
createExternalCommentSync,
|
38
38
|
createMarkdownExtensions,
|
39
39
|
createThemeExtensions,
|
40
|
+
debugTree,
|
40
41
|
decorateMarkdown,
|
41
42
|
defaultOptions,
|
42
43
|
dropFile,
|
43
44
|
folding,
|
44
45
|
formattingKeymap,
|
45
46
|
image,
|
47
|
+
InputModeExtensions,
|
46
48
|
linkTooltip,
|
47
49
|
listener,
|
48
50
|
mention,
|
49
|
-
|
51
|
+
selectionState,
|
50
52
|
table,
|
51
53
|
typewriter,
|
52
54
|
type CommandAction,
|
53
|
-
type Comment,
|
54
55
|
type CommentsOptions,
|
55
|
-
type EditorSelectionState,
|
56
|
-
debugTree,
|
57
56
|
type DebugNode,
|
57
|
+
type EditorSelectionState,
|
58
58
|
} from './extensions';
|
59
|
-
import { renderRoot } from './extensions/util';
|
60
59
|
import { useTextEditor, type UseTextEditorProps } from './hooks';
|
61
60
|
import translations from './translations';
|
61
|
+
import { type Comment } from './types';
|
62
|
+
import { renderRoot } from './util';
|
62
63
|
|
63
64
|
faker.seed(101);
|
64
65
|
|
@@ -164,8 +165,8 @@ const content = {
|
|
164
165
|
'> 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
166
|
'',
|
166
167
|
'> This is ...',
|
167
|
-
'
|
168
|
-
'
|
168
|
+
'... a multi-line ...',
|
169
|
+
'block quote.',
|
169
170
|
'',
|
170
171
|
),
|
171
172
|
|
@@ -254,7 +255,7 @@ const renderLinkButton = (el: Element, url: string) => {
|
|
254
255
|
// Story
|
255
256
|
//
|
256
257
|
|
257
|
-
type DebugMode = '
|
258
|
+
type DebugMode = 'raw' | 'tree' | 'raw+tree';
|
258
259
|
|
259
260
|
type StoryProps = {
|
260
261
|
id?: string;
|
@@ -266,7 +267,7 @@ type StoryProps = {
|
|
266
267
|
onReady?: (view: EditorView) => void;
|
267
268
|
} & Pick<UseTextEditorProps, 'scrollTo' | 'selection' | 'extensions'>;
|
268
269
|
|
269
|
-
const
|
270
|
+
const DefaultStory = ({
|
270
271
|
id = 'editor-' + PublicKey.random().toHex().slice(0, 8),
|
271
272
|
debug,
|
272
273
|
text,
|
@@ -278,7 +279,7 @@ const Story = ({
|
|
278
279
|
lineNumbers,
|
279
280
|
onReady,
|
280
281
|
}: StoryProps) => {
|
281
|
-
const [object] = useState(
|
282
|
+
const [object] = useState(createObject(create(Expando, { content: text ?? '' })));
|
282
283
|
const { themeMode } = useThemeContext();
|
283
284
|
const [tree, setTree] = useState<DebugNode>();
|
284
285
|
const { parentRef, focusAttributes, view } = useTextEditor(
|
@@ -317,16 +318,16 @@ const Story = ({
|
|
317
318
|
return (
|
318
319
|
<div className='flex w-full'>
|
319
320
|
<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
|
-
|
321
|
+
{debug && (
|
322
|
+
<div className='flex flex-col w-[800px] border-l border-separator divide-y divide-separator overflow-auto'>
|
323
|
+
{(debug === 'raw' || debug === 'raw+tree') && (
|
324
|
+
<pre className='p-1 font-mono text-xs text-green-800 dark:text-green-200'>{view?.state.doc.toString()}</pre>
|
325
|
+
)}
|
326
|
+
{(debug === 'tree' || debug === 'raw+tree') && (
|
327
|
+
<pre className='p-1 font-mono text-xs text-green-800 dark:text-green-200'>
|
328
|
+
{JSON.stringify(tree, null, 2)}
|
329
|
+
</pre>
|
330
|
+
)}
|
330
331
|
</div>
|
331
332
|
)}
|
332
333
|
</div>
|
@@ -334,9 +335,9 @@ const Story = ({
|
|
334
335
|
};
|
335
336
|
|
336
337
|
export default {
|
337
|
-
title: 'react-ui-editor/TextEditor',
|
338
|
+
title: 'ui/react-ui-editor/TextEditor',
|
338
339
|
decorators: [withTheme, withLayout({ fullscreen: true })],
|
339
|
-
render:
|
340
|
+
render: DefaultStory,
|
340
341
|
parameters: { translations, layout: 'fullscreen' },
|
341
342
|
};
|
342
343
|
|
@@ -362,28 +363,28 @@ const allExtensions: Extension[] = [
|
|
362
363
|
];
|
363
364
|
|
364
365
|
export const Default = {
|
365
|
-
render: () => <
|
366
|
+
render: () => <DefaultStory text={text} extensions={defaultExtensions} />,
|
366
367
|
};
|
367
368
|
|
368
369
|
export const Everything = {
|
369
|
-
render: () => <
|
370
|
+
render: () => <DefaultStory text={text} extensions={allExtensions} selection={{ anchor: 99, head: 110 }} />,
|
370
371
|
};
|
371
372
|
|
372
373
|
export const Empty = {
|
373
|
-
render: () => <
|
374
|
+
render: () => <DefaultStory extensions={defaultExtensions} />,
|
374
375
|
};
|
375
376
|
|
376
377
|
export const Readonly = {
|
377
|
-
render: () => <
|
378
|
+
render: () => <DefaultStory text={text} extensions={defaultExtensions} readonly />,
|
378
379
|
};
|
379
380
|
|
380
381
|
export const NoExtensions = {
|
381
|
-
render: () => <
|
382
|
+
render: () => <DefaultStory text={text} />,
|
382
383
|
};
|
383
384
|
|
384
385
|
export const Vim = {
|
385
386
|
render: () => (
|
386
|
-
<
|
387
|
+
<DefaultStory
|
387
388
|
text={str('# Vim Mode', '', 'The distant future. The year 2000.', '', content.paragraphs)}
|
388
389
|
extensions={[defaultExtensions, InputModeExtensions.vim]}
|
389
390
|
/>
|
@@ -410,14 +411,14 @@ const headings = str(
|
|
410
411
|
const global = new Map<string, EditorSelectionState>();
|
411
412
|
|
412
413
|
export const Folding = {
|
413
|
-
render: () => <
|
414
|
+
render: () => <DefaultStory text={text} extensions={[folding()]} />,
|
414
415
|
};
|
415
416
|
|
416
417
|
export const Scrolling = {
|
417
418
|
render: () => (
|
418
|
-
<
|
419
|
+
<DefaultStory
|
419
420
|
text={str('# Large Document', '', longText)}
|
420
|
-
extensions={
|
421
|
+
extensions={selectionState({
|
421
422
|
setState: (id, state) => global.set(id, state),
|
422
423
|
getState: (id) => global.get(id),
|
423
424
|
})}
|
@@ -427,7 +428,7 @@ export const Scrolling = {
|
|
427
428
|
|
428
429
|
export const ScrollingWithImages = {
|
429
430
|
render: () => (
|
430
|
-
<
|
431
|
+
<DefaultStory text={str('# Large Document', '', largeWithImages)} extensions={[decorateMarkdown(), image()]} />
|
431
432
|
),
|
432
433
|
};
|
433
434
|
|
@@ -438,7 +439,7 @@ export const ScrollTo = {
|
|
438
439
|
const text = str('# Scroll To', longText, '', word, '', longText);
|
439
440
|
const idx = text.indexOf(word);
|
440
441
|
return (
|
441
|
-
<
|
442
|
+
<DefaultStory
|
442
443
|
text={text}
|
443
444
|
extensions={defaultExtensions}
|
444
445
|
scrollTo={idx}
|
@@ -452,25 +453,39 @@ export const ScrollTo = {
|
|
452
453
|
// Markdown
|
453
454
|
//
|
454
455
|
|
456
|
+
export const Blockquote = {
|
457
|
+
render: () => (
|
458
|
+
<DefaultStory
|
459
|
+
text={str('> Blockquote', 'continuation', content.footer)}
|
460
|
+
extensions={decorateMarkdown()}
|
461
|
+
debug='raw'
|
462
|
+
/>
|
463
|
+
),
|
464
|
+
};
|
465
|
+
|
455
466
|
export const Headings = {
|
456
|
-
render: () =>
|
467
|
+
render: () => (
|
468
|
+
<DefaultStory text={headings} extensions={decorateMarkdown({ numberedHeadings: { from: 2, to: 4 } })} />
|
469
|
+
),
|
457
470
|
};
|
458
471
|
|
459
472
|
export const Links = {
|
460
|
-
render: () =>
|
473
|
+
render: () => (
|
474
|
+
<DefaultStory text={str(content.links, content.footer)} extensions={[linkTooltip(renderLinkTooltip)]} />
|
475
|
+
),
|
461
476
|
};
|
462
477
|
|
463
478
|
export const Image = {
|
464
|
-
render: () => <
|
479
|
+
render: () => <DefaultStory text={str(content.image, content.footer)} extensions={[image()]} />,
|
465
480
|
};
|
466
481
|
|
467
482
|
export const Code = {
|
468
|
-
render: () => <
|
483
|
+
render: () => <DefaultStory text={str(content.codeblocks, content.footer)} extensions={[decorateMarkdown()]} />,
|
469
484
|
};
|
470
485
|
|
471
486
|
export const Lists = {
|
472
487
|
render: () => (
|
473
|
-
<
|
488
|
+
<DefaultStory
|
474
489
|
text={str(content.tasks, '', content.bullets, '', content.numbered, content.footer)}
|
475
490
|
extensions={[decorateMarkdown()]}
|
476
491
|
/>
|
@@ -478,24 +493,26 @@ export const Lists = {
|
|
478
493
|
};
|
479
494
|
|
480
495
|
export const BulletList = {
|
481
|
-
render: () => <
|
496
|
+
render: () => <DefaultStory text={str(content.bullets, content.footer)} extensions={[decorateMarkdown()]} />,
|
482
497
|
};
|
483
498
|
|
484
499
|
export const OrderedList = {
|
485
|
-
render: () => <
|
500
|
+
render: () => <DefaultStory text={str(content.numbered, content.footer)} extensions={[decorateMarkdown()]} />,
|
486
501
|
};
|
487
502
|
|
488
503
|
export const TaskList = {
|
489
|
-
render: () =>
|
504
|
+
render: () => (
|
505
|
+
<DefaultStory text={str(content.tasks, content.footer)} extensions={[decorateMarkdown()]} debug='raw+tree' />
|
506
|
+
),
|
490
507
|
};
|
491
508
|
|
492
509
|
export const Table = {
|
493
|
-
render: () => <
|
510
|
+
render: () => <DefaultStory text={str(content.table, content.footer)} extensions={[decorateMarkdown(), table()]} />,
|
494
511
|
};
|
495
512
|
|
496
513
|
export const CommentedOut = {
|
497
514
|
render: () => (
|
498
|
-
<
|
515
|
+
<DefaultStory
|
499
516
|
text={str('# Commented out', '', content.comment, content.footer)}
|
500
517
|
extensions={[
|
501
518
|
decorateMarkdown(),
|
@@ -508,7 +525,11 @@ export const CommentedOut = {
|
|
508
525
|
|
509
526
|
export const Typescript = {
|
510
527
|
render: () => (
|
511
|
-
<
|
528
|
+
<DefaultStory
|
529
|
+
text={content.typescript}
|
530
|
+
lineNumbers
|
531
|
+
extensions={[editorMonospace, javascript({ typescript: true })]}
|
532
|
+
/>
|
512
533
|
),
|
513
534
|
};
|
514
535
|
|
@@ -518,7 +539,7 @@ export const Typescript = {
|
|
518
539
|
|
519
540
|
export const Autocomplete = {
|
520
541
|
render: () => (
|
521
|
-
<
|
542
|
+
<DefaultStory
|
522
543
|
text={str('# Autocomplete', '', 'Press Ctrl-Space...', content.footer)}
|
523
544
|
extensions={[
|
524
545
|
decorateMarkdown({ renderLinkButton }),
|
@@ -532,7 +553,7 @@ export const Autocomplete = {
|
|
532
553
|
|
533
554
|
export const Mention = {
|
534
555
|
render: () => (
|
535
|
-
<
|
556
|
+
<DefaultStory
|
536
557
|
text={str('# Mention', '', 'Type @...', content.footer)}
|
537
558
|
extensions={[
|
538
559
|
mention({
|
@@ -545,7 +566,11 @@ export const Mention = {
|
|
545
566
|
|
546
567
|
export const Search = {
|
547
568
|
render: () => (
|
548
|
-
<
|
569
|
+
<DefaultStory
|
570
|
+
text={str('# Search', text)}
|
571
|
+
extensions={defaultExtensions}
|
572
|
+
onReady={(view) => openSearchPanel(view)}
|
573
|
+
/>
|
549
574
|
),
|
550
575
|
};
|
551
576
|
|
@@ -569,28 +594,26 @@ const CommandDialog = ({ onClose }: { onClose: (action?: CommandAction) => void
|
|
569
594
|
};
|
570
595
|
|
571
596
|
return (
|
572
|
-
<
|
573
|
-
<
|
574
|
-
<Input.
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
<
|
584
|
-
|
585
|
-
|
586
|
-
</div>
|
587
|
-
</DensityProvider>
|
597
|
+
<div className={mx('flex items-center p-2 gap-2 border rounded-md', baseSurface)}>
|
598
|
+
<Input.Root>
|
599
|
+
<Input.TextInput
|
600
|
+
autoFocus={true}
|
601
|
+
placeholder='Enter command.'
|
602
|
+
value={text}
|
603
|
+
onChange={({ target: { value } }) => setText(value)}
|
604
|
+
onKeyDown={handleKeyDown}
|
605
|
+
/>
|
606
|
+
</Input.Root>
|
607
|
+
<Button variant='ghost' classNames='pli-0' onClick={() => onClose()}>
|
608
|
+
<X className={getSize(5)} />
|
609
|
+
</Button>
|
610
|
+
</div>
|
588
611
|
);
|
589
612
|
};
|
590
613
|
|
591
614
|
export const Command = {
|
592
615
|
render: () => (
|
593
|
-
<
|
616
|
+
<DefaultStory
|
594
617
|
text={str('# Command', '')}
|
595
618
|
extensions={[
|
596
619
|
command({
|
@@ -608,7 +631,7 @@ export const Comments = {
|
|
608
631
|
render: () => {
|
609
632
|
const _comments = useSignal<Comment[]>([]);
|
610
633
|
return (
|
611
|
-
<
|
634
|
+
<DefaultStory
|
612
635
|
text={str('# Comments', '', content.paragraphs, content.footer)}
|
613
636
|
extensions={[
|
614
637
|
createExternalCommentSync(
|
@@ -645,12 +668,14 @@ export const Comments = {
|
|
645
668
|
};
|
646
669
|
|
647
670
|
export const Annotations = {
|
648
|
-
render: () =>
|
671
|
+
render: () => (
|
672
|
+
<DefaultStory text={str('# Annotations', '', longText)} extensions={[annotations({ match: /volup/gi })]} />
|
673
|
+
),
|
649
674
|
};
|
650
675
|
|
651
676
|
export const DND = {
|
652
677
|
render: () => (
|
653
|
-
<
|
678
|
+
<DefaultStory
|
654
679
|
text={str('# DND', '')}
|
655
680
|
extensions={[
|
656
681
|
dropFile({
|
@@ -665,7 +690,7 @@ export const DND = {
|
|
665
690
|
|
666
691
|
export const Listener = {
|
667
692
|
render: () => (
|
668
|
-
<
|
693
|
+
<DefaultStory
|
669
694
|
text={str('# Listener', '', content.footer)}
|
670
695
|
extensions={[
|
671
696
|
listener({
|
@@ -685,7 +710,7 @@ const typewriterItems = localStorage.getItem('dxos.org/plugin/markdown/typewrite
|
|
685
710
|
|
686
711
|
export const Typewriter = {
|
687
712
|
render: () => (
|
688
|
-
<
|
713
|
+
<DefaultStory
|
689
714
|
text={str('# Typewriter', '', content.paragraphs, content.footer)}
|
690
715
|
extensions={[typewriter({ items: typewriterItems })]}
|
691
716
|
/>
|
@@ -694,7 +719,7 @@ export const Typewriter = {
|
|
694
719
|
|
695
720
|
export const Blast = {
|
696
721
|
render: () => (
|
697
|
-
<
|
722
|
+
<DefaultStory
|
698
723
|
text={str('# Blast', '', content.paragraphs, content.codeblocks, content.paragraphs)}
|
699
724
|
extensions={[
|
700
725
|
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 '../../util';
|
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 '../../util';
|
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 '../../util';
|
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 '
|
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 '../../util';
|
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: () => ({}),
|