@dxos/react-ui-editor 0.4.8-main.05fda5d → 0.4.8-main.06fa7e4

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.
Files changed (137) hide show
  1. package/dist/lib/browser/index.mjs +1938 -1920
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/TextEditor.d.ts +18 -34
  5. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +80 -5
  7. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  8. package/dist/types/src/components/Toolbar/Toolbar.d.ts +12 -11
  9. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  10. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +4 -2
  11. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  12. package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
  13. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  14. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +2 -1
  15. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  16. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  17. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  18. package/dist/types/src/extensions/automerge/defs.d.ts +1 -15
  19. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  20. package/dist/types/src/extensions/automerge/index.d.ts +0 -1
  21. package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
  22. package/dist/types/src/extensions/automerge/sync.d.ts +2 -1
  23. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  24. package/dist/types/src/extensions/automerge/update-automerge.d.ts +2 -1
  25. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  26. package/dist/types/src/{hooks → extensions/awareness}/awareness-provider.d.ts +1 -1
  27. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -0
  28. package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -0
  29. package/dist/types/src/extensions/awareness/index.d.ts +3 -0
  30. package/dist/types/src/extensions/awareness/index.d.ts.map +1 -0
  31. package/dist/types/src/extensions/comments.d.ts +2 -2
  32. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  33. package/dist/types/src/extensions/cursor.d.ts +1 -1
  34. package/dist/types/src/extensions/cursor.d.ts.map +1 -1
  35. package/dist/types/src/extensions/dnd.d.ts +7 -1
  36. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  37. package/dist/types/src/extensions/doc.d.ts +3 -0
  38. package/dist/types/src/extensions/doc.d.ts.map +1 -0
  39. package/dist/types/src/extensions/factories.d.ts +53 -0
  40. package/dist/types/src/extensions/factories.d.ts.map +1 -0
  41. package/dist/types/src/extensions/index.d.ts +4 -2
  42. package/dist/types/src/extensions/index.d.ts.map +1 -1
  43. package/dist/types/src/extensions/markdown/action.d.ts +9 -0
  44. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
  45. package/dist/types/src/extensions/markdown/bundle.d.ts +5 -4
  46. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  47. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  48. package/dist/types/src/extensions/markdown/formatting.d.ts +8 -5
  49. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  50. package/dist/types/src/extensions/markdown/image.d.ts +6 -0
  51. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  52. package/dist/types/src/extensions/markdown/index.d.ts +1 -0
  53. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  54. package/dist/types/src/extensions/markdown/table.d.ts +2 -2
  55. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
  56. package/dist/types/src/extensions/modes.d.ts +2 -1
  57. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  58. package/dist/types/src/extensions/state.d.ts +20 -0
  59. package/dist/types/src/extensions/state.d.ts.map +1 -0
  60. package/dist/types/src/extensions/types.d.ts +9 -0
  61. package/dist/types/src/extensions/types.d.ts.map +1 -0
  62. package/dist/types/src/hooks/index.d.ts +1 -4
  63. package/dist/types/src/hooks/index.d.ts.map +1 -1
  64. package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
  65. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  66. package/dist/types/src/hooks/useDocAccessor.d.ts +9 -0
  67. package/dist/types/src/hooks/useDocAccessor.d.ts.map +1 -0
  68. package/dist/types/src/hooks/useTextEditor.d.ts +3 -44
  69. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  70. package/dist/types/src/hooks/useTextEditor.stories.d.ts +7 -0
  71. package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -1
  72. package/dist/types/src/themes/default.d.ts +0 -3
  73. package/dist/types/src/themes/default.d.ts.map +1 -1
  74. package/dist/types/src/translations.d.ts +1 -0
  75. package/dist/types/src/translations.d.ts.map +1 -1
  76. package/package.json +26 -27
  77. package/src/components/TextEditor/TextEditor.stories.tsx +532 -23
  78. package/src/components/TextEditor/TextEditor.tsx +45 -156
  79. package/src/components/Toolbar/Toolbar.stories.tsx +54 -55
  80. package/src/components/Toolbar/Toolbar.tsx +102 -60
  81. package/src/extensions/automerge/automerge.stories.tsx +16 -17
  82. package/src/extensions/automerge/automerge.ts +6 -5
  83. package/src/extensions/automerge/cursor.ts +1 -1
  84. package/src/extensions/automerge/defs.ts +1 -22
  85. package/src/extensions/automerge/index.ts +0 -1
  86. package/src/extensions/automerge/sync.ts +2 -9
  87. package/src/extensions/automerge/update-automerge.ts +2 -1
  88. package/src/{hooks → extensions/awareness}/awareness-provider.ts +1 -1
  89. package/src/extensions/{awareness.ts → awareness/awareness.ts} +1 -1
  90. package/src/extensions/awareness/index.ts +6 -0
  91. package/src/extensions/command/state.ts +3 -3
  92. package/src/extensions/comments.ts +9 -5
  93. package/src/extensions/cursor.ts +1 -1
  94. package/src/extensions/dnd.ts +31 -9
  95. package/src/extensions/doc.ts +14 -0
  96. package/src/extensions/factories.ts +193 -0
  97. package/src/extensions/index.ts +4 -2
  98. package/src/extensions/markdown/action.ts +112 -0
  99. package/src/extensions/markdown/bundle.ts +17 -37
  100. package/src/extensions/markdown/decorate.ts +2 -4
  101. package/src/extensions/markdown/formatting.test.ts +13 -13
  102. package/src/extensions/markdown/formatting.ts +110 -97
  103. package/src/extensions/markdown/image.ts +7 -0
  104. package/src/extensions/markdown/index.ts +1 -0
  105. package/src/extensions/markdown/table.ts +11 -3
  106. package/src/extensions/modes.ts +11 -2
  107. package/src/extensions/state.ts +90 -0
  108. package/src/extensions/types.ts +16 -0
  109. package/src/hooks/index.ts +1 -5
  110. package/src/hooks/useActionHandler.ts +4 -85
  111. package/src/hooks/useDocAccessor.ts +27 -0
  112. package/src/hooks/useTextEditor.stories.tsx +40 -35
  113. package/src/hooks/useTextEditor.ts +14 -120
  114. package/src/index.ts +1 -1
  115. package/src/themes/default.ts +25 -36
  116. package/src/translations.ts +1 -0
  117. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +0 -103
  118. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +0 -1
  119. package/dist/types/src/extensions/awareness.d.ts.map +0 -1
  120. package/dist/types/src/extensions/cursor-line-margin.d.ts +0 -8
  121. package/dist/types/src/extensions/cursor-line-margin.d.ts.map +0 -1
  122. package/dist/types/src/extensions/outliner.d.ts +0 -4
  123. package/dist/types/src/extensions/outliner.d.ts.map +0 -1
  124. package/dist/types/src/hooks/awareness-provider.d.ts.map +0 -1
  125. package/dist/types/src/hooks/defs.d.ts +0 -20
  126. package/dist/types/src/hooks/defs.d.ts.map +0 -1
  127. package/dist/types/src/hooks/useEditorView.d.ts +0 -20
  128. package/dist/types/src/hooks/useEditorView.d.ts.map +0 -1
  129. package/dist/types/src/hooks/useTextModel.d.ts +0 -33
  130. package/dist/types/src/hooks/useTextModel.d.ts.map +0 -1
  131. package/src/components/TextEditor/MarkdownEditor.stories.tsx +0 -524
  132. package/src/extensions/cursor-line-margin.ts +0 -95
  133. package/src/extensions/outliner.ts +0 -12
  134. package/src/hooks/defs.ts +0 -30
  135. package/src/hooks/useEditorView.ts +0 -32
  136. package/src/hooks/useTextModel.ts +0 -121
  137. /package/dist/types/src/extensions/{awareness.d.ts → awareness/awareness.d.ts} +0 -0
@@ -0,0 +1,193 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
6
+ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from '@codemirror/commands';
7
+ import { bracketMatching } from '@codemirror/language';
8
+ import { searchKeymap } from '@codemirror/search';
9
+ import { EditorState, type Extension } from '@codemirror/state';
10
+ import {
11
+ EditorView,
12
+ type KeyBinding,
13
+ drawSelection,
14
+ dropCursor,
15
+ highlightActiveLine,
16
+ keymap,
17
+ lineNumbers,
18
+ placeholder,
19
+ scrollPastEnd,
20
+ } from '@codemirror/view';
21
+ import defaultsDeep from 'lodash.defaultsdeep';
22
+
23
+ import { generateName } from '@dxos/display-name';
24
+ import { type DocAccessor } from '@dxos/echo-schema';
25
+ import { log } from '@dxos/log';
26
+ import { type Space } from '@dxos/react-client/echo';
27
+ import { type Identity } from '@dxos/react-client/halo';
28
+ import { type ThemeMode } from '@dxos/react-ui';
29
+ import { type HuePalette, hueTokens } from '@dxos/react-ui-theme';
30
+ import { hexToHue, isNotFalsy } from '@dxos/util';
31
+
32
+ import { automerge } from './automerge';
33
+ import { awareness, SpaceAwarenessProvider } from './awareness';
34
+ import { type ThemeStyles } from '../styles';
35
+ import { defaultTheme } from '../themes';
36
+
37
+ //
38
+ // Basic
39
+ //
40
+
41
+ /**
42
+ * https://codemirror.net/docs/extensions
43
+ * https://github.com/codemirror/basic-setup
44
+ * https://github.com/codemirror/basic-setup/blob/main/src/codemirror.ts
45
+ */
46
+ export type BasicExtensionsOptions = {
47
+ allowMultipleSelections?: boolean;
48
+ bracketMatching?: boolean;
49
+ closeBrackets?: boolean;
50
+ dropCursor?: boolean;
51
+ drawSelection?: boolean;
52
+ editable?: boolean;
53
+ highlightActiveLine?: boolean;
54
+ history?: boolean;
55
+ indentWithTab?: boolean;
56
+ keymap?: null | 'default' | 'standard';
57
+ lineNumbers?: boolean;
58
+ lineWrapping?: boolean;
59
+ placeholder?: string;
60
+ readonly?: boolean;
61
+ search?: boolean;
62
+ scrollPastEnd?: boolean;
63
+ standardKeymap?: boolean;
64
+ tabSize?: number;
65
+ };
66
+
67
+ const defaultBasicOptions: BasicExtensionsOptions = {
68
+ allowMultipleSelections: true,
69
+ bracketMatching: true,
70
+ closeBrackets: true,
71
+ drawSelection: true,
72
+ editable: true,
73
+ history: true,
74
+ keymap: 'standard',
75
+ lineWrapping: true,
76
+ search: true,
77
+ };
78
+
79
+ const keymaps: { [key: string]: readonly KeyBinding[] } = {
80
+ // https://codemirror.net/docs/ref/#commands.standardKeymap
81
+ standard: standardKeymap,
82
+ // https://codemirror.net/docs/ref/#commands.defaultKeymap
83
+ default: defaultKeymap,
84
+ };
85
+
86
+ export const createBasicExtensions = (_props?: BasicExtensionsOptions): Extension => {
87
+ const props: BasicExtensionsOptions = defaultsDeep({}, _props, defaultBasicOptions);
88
+ return [
89
+ // NOTE: Doesn't catch errors in keymap functions.
90
+ EditorView.exceptionSink.of((err) => {
91
+ log.catch(err);
92
+ }),
93
+
94
+ props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),
95
+ props.bracketMatching && bracketMatching(),
96
+ props.closeBrackets && closeBrackets(),
97
+ props.dropCursor && dropCursor(),
98
+ props.drawSelection && drawSelection(),
99
+ props.highlightActiveLine && highlightActiveLine(),
100
+ props.history && history(),
101
+ props.lineNumbers && lineNumbers(),
102
+ props.lineWrapping && EditorView.lineWrapping,
103
+ props.placeholder && placeholder(props.placeholder),
104
+ props.readonly && [EditorState.readOnly.of(true), EditorView.editable.of(false)],
105
+ props.scrollPastEnd && scrollPastEnd(),
106
+ props.tabSize && EditorState.tabSize.of(props.tabSize),
107
+
108
+ // https://codemirror.net/docs/ref/#view.KeyBinding
109
+ keymap.of(
110
+ [
111
+ ...((props.keymap && keymaps[props.keymap]) ?? []),
112
+ // https://codemirror.net/docs/ref/#commands.indentWithTab
113
+ ...(props.indentWithTab ? [indentWithTab] : []),
114
+ // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
115
+ ...(props.closeBrackets ? closeBracketsKeymap : []),
116
+ // https://codemirror.net/docs/ref/#commands.historyKeymap
117
+ ...(props.history ? historyKeymap : []),
118
+ // https://codemirror.net/docs/ref/#search.searchKeymap
119
+ ...(props.search ? searchKeymap : []),
120
+ ].filter(isNotFalsy),
121
+ ),
122
+ ].filter(isNotFalsy);
123
+ };
124
+
125
+ //
126
+ // Theme
127
+ //
128
+
129
+ export type ThemeExtensionsOptions = {
130
+ theme?: ThemeStyles;
131
+ themeMode?: ThemeMode;
132
+ slots?: {
133
+ editor?: {
134
+ className?: string;
135
+ };
136
+ content?: {
137
+ className?: string;
138
+ };
139
+ };
140
+ };
141
+
142
+ const defaultThemeSlots = {
143
+ editor: {
144
+ className: 'w-full bs-full',
145
+ },
146
+ };
147
+
148
+ export const createThemeExtensions = ({ theme, themeMode, slots: _slots }: ThemeExtensionsOptions = {}): Extension => {
149
+ const slots = defaultsDeep({}, _slots, defaultThemeSlots);
150
+ return [
151
+ EditorView.baseTheme(defaultTheme),
152
+ EditorView.darkTheme.of(themeMode === 'dark'),
153
+ theme && EditorView.theme(theme),
154
+ slots.editor?.className && EditorView.editorAttributes.of({ class: slots.editor.className }),
155
+ slots.content?.className && EditorView.contentAttributes.of({ class: slots.content.className }),
156
+ ].filter(isNotFalsy);
157
+ };
158
+
159
+ //
160
+ // Data
161
+ //
162
+
163
+ export type DataExtensionsProps = {
164
+ id: string;
165
+ text: DocAccessor;
166
+ space?: Space;
167
+ identity?: Identity | null;
168
+ };
169
+
170
+ // TODO(burdon): Move out of react-ui-editor (remove echo deps).
171
+ export const createDataExtensions = ({ id, text, space, identity }: DataExtensionsProps): Extension[] => {
172
+ const extensions: Extension[] = [automerge(text)];
173
+
174
+ if (space && identity) {
175
+ const peerId = identity?.identityKey.toHex();
176
+ const { cursorLightValue, cursorDarkValue } =
177
+ hueTokens[(identity?.profile?.data?.hue as HuePalette | undefined) ?? hexToHue(peerId ?? '0')];
178
+ const awarenessProvider = new SpaceAwarenessProvider({
179
+ space,
180
+ channel: `awareness.${id}`,
181
+ peerId: identity.identityKey.toHex(),
182
+ info: {
183
+ displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
184
+ color: cursorDarkValue,
185
+ lightColor: cursorLightValue,
186
+ },
187
+ });
188
+
189
+ extensions.push(awareness(awarenessProvider));
190
+ }
191
+
192
+ return extensions;
193
+ };
@@ -10,11 +10,13 @@ export * from './blast';
10
10
  export * from './command';
11
11
  export * from './comments';
12
12
  export * from './cursor';
13
- export * from './cursor-line-margin';
13
+ export * from './doc';
14
14
  export * from './dnd';
15
+ export * from './factories';
15
16
  export * from './listener';
16
17
  export * from './markdown';
17
18
  export * from './mention';
18
19
  export * from './modes';
19
- export * from './outliner';
20
+ export * from './state';
21
+ export * from './types';
20
22
  export * from './typewriter';
@@ -0,0 +1,112 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type EditorView } from '@codemirror/view';
6
+
7
+ import {
8
+ Inline,
9
+ List,
10
+ addBlockquote,
11
+ addCodeblock,
12
+ addLink,
13
+ addList,
14
+ insertTable,
15
+ removeBlockquote,
16
+ removeCodeblock,
17
+ removeLink,
18
+ removeList,
19
+ setHeading,
20
+ setStyle,
21
+ toggleBlockquote,
22
+ toggleList,
23
+ toggleStyle,
24
+ } from './formatting';
25
+ import { createComment } from '../comments';
26
+
27
+ export type ActionType =
28
+ | 'blockquote'
29
+ | 'strong'
30
+ | 'codeblock'
31
+ | 'comment'
32
+ | 'heading'
33
+ | 'image'
34
+ | 'emphasis'
35
+ | 'code'
36
+ | 'link'
37
+ | 'list-bullet'
38
+ | 'list-ordered'
39
+ | 'list-task'
40
+ | 'mention'
41
+ | 'prompt'
42
+ | 'strikethrough'
43
+ | 'table';
44
+
45
+ export type Action = {
46
+ type: ActionType;
47
+ data?: any;
48
+ };
49
+
50
+ export type ActionHandler = (view: EditorView, action: Action) => void;
51
+
52
+ export const processAction: ActionHandler = (view, action) => {
53
+ let inlineType, listType;
54
+ switch (action.type) {
55
+ case 'heading':
56
+ setHeading(parseInt(action.data))(view);
57
+ break;
58
+
59
+ case 'strong':
60
+ case 'emphasis':
61
+ case 'strikethrough':
62
+ case 'code':
63
+ inlineType =
64
+ action.type === 'strong'
65
+ ? Inline.Strong
66
+ : action.type === 'emphasis'
67
+ ? Inline.Emphasis
68
+ : action.type === 'strikethrough'
69
+ ? Inline.Strikethrough
70
+ : Inline.Code;
71
+ (typeof action.data === 'boolean' ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
72
+ break;
73
+
74
+ case 'list-ordered':
75
+ case 'list-bullet':
76
+ case 'list-task':
77
+ listType =
78
+ action.type === 'list-ordered' ? List.Ordered : action.type === 'list-bullet' ? List.Bullet : List.Task;
79
+ (action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(
80
+ view,
81
+ );
82
+ break;
83
+
84
+ case 'blockquote':
85
+ (action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
86
+ break;
87
+ case 'codeblock':
88
+ (action.data === false ? removeCodeblock : addCodeblock)(view);
89
+ break;
90
+ case 'table':
91
+ insertTable(view);
92
+ break;
93
+
94
+ case 'link':
95
+ (action.data === false ? removeLink : addLink())(view);
96
+ break;
97
+
98
+ case 'image':
99
+ addLink({ url: action.data, image: true })(view);
100
+ break;
101
+
102
+ case 'comment':
103
+ createComment(view);
104
+ break;
105
+ }
106
+
107
+ requestAnimationFrame(() => {
108
+ if (!view.hasFocus) {
109
+ view.focus();
110
+ }
111
+ });
112
+ };
@@ -2,51 +2,34 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
6
- import { history, historyKeymap, indentWithTab, standardKeymap } from '@codemirror/commands';
5
+ import { completionKeymap } from '@codemirror/autocomplete';
6
+ import { defaultKeymap, indentWithTab } from '@codemirror/commands';
7
7
  import { markdownLanguage, markdown } from '@codemirror/lang-markdown';
8
- import { bracketMatching, defaultHighlightStyle, indentOnInput, syntaxHighlighting } from '@codemirror/language';
8
+ import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
9
9
  import { languages } from '@codemirror/language-data';
10
- import { searchKeymap } from '@codemirror/search';
11
- import { EditorState, type Extension } from '@codemirror/state';
10
+ import { lintKeymap } from '@codemirror/lint';
11
+ import { type Extension } from '@codemirror/state';
12
12
  import { oneDarkHighlightStyle } from '@codemirror/theme-one-dark';
13
- import { EditorView, drawSelection, dropCursor, keymap, placeholder } from '@codemirror/view';
13
+ import { keymap } from '@codemirror/view';
14
14
 
15
15
  import { type ThemeMode } from '@dxos/react-ui';
16
- import { isNotFalsy } from '@dxos/util';
17
16
 
18
17
  import { markdownHighlightStyle, markdownTagsExtensions } from './highlight';
19
- import { type TextEditorProps } from '../../components';
20
18
 
21
19
  export type MarkdownBundleOptions = {
22
20
  themeMode?: ThemeMode;
23
- } & Pick<TextEditorProps, 'lineWrapping' | 'placeholder'>;
21
+ };
24
22
 
25
23
  /**
26
- * Markdown bundle.
24
+ * Creates markdown extensions.
25
+ * To be used in conjunction with createBasicExtensions.
26
+ *
27
27
  * Refs:
28
28
  * https://codemirror.net/docs/community
29
29
  * https://codemirror.net/docs/ref/#codemirror.basicSetup
30
30
  */
31
- export const createMarkdownExtensions = ({
32
- themeMode,
33
- placeholder: _placeholder,
34
- lineWrapping = true,
35
- }: MarkdownBundleOptions = {}): Extension[] => {
31
+ export const createMarkdownExtensions = ({ themeMode }: MarkdownBundleOptions = {}): Extension[] => {
36
32
  return [
37
- // TODO(burdon): Reconcile with createBasicExtensions.
38
- lineWrapping && EditorView.lineWrapping,
39
- EditorState.allowMultipleSelections.of(true),
40
- EditorState.tabSize.of(2),
41
-
42
- bracketMatching(),
43
- closeBrackets(),
44
- dropCursor(),
45
- drawSelection(),
46
- history(),
47
- indentOnInput(),
48
- _placeholder && placeholder(_placeholder),
49
-
50
33
  // Main extension.
51
34
  // https://github.com/codemirror/lang-markdown
52
35
  // https://codemirror.net/5/mode/markdown/index.html (demo).
@@ -77,14 +60,11 @@ export const createMarkdownExtensions = ({
77
60
  keymap.of([
78
61
  // https://codemirror.net/docs/ref/#commands.indentWithTab
79
62
  indentWithTab,
80
- // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
81
- ...closeBracketsKeymap,
82
- // https://codemirror.net/docs/ref/#commands.historyKeymap
83
- ...historyKeymap,
84
- // https://codemirror.net/docs/ref/#search.searchKeymap
85
- ...searchKeymap,
86
- // https://codemirror.net/docs/ref/#commands.standardKeymap
87
- ...standardKeymap,
63
+
64
+ // https://codemirror.net/docs/ref/#commands.defaultKeymap
65
+ ...defaultKeymap,
66
+ ...completionKeymap,
67
+ ...lintKeymap,
88
68
  ]),
89
- ].filter(isNotFalsy);
69
+ ];
90
70
  };
@@ -48,7 +48,7 @@ class CheckboxWidget extends WidgetType {
48
48
 
49
49
  override toDOM(view: EditorView) {
50
50
  const input = document.createElement('input');
51
- input.className = 'cm-task-checkbox';
51
+ input.className = 'cm-task-checkbox ch-checkbox ch-focus-ring -mbs-0.5';
52
52
  input.type = 'checkbox';
53
53
  input.checked = this._checked;
54
54
  if (view.state.readOnly) {
@@ -148,9 +148,7 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
148
148
  marks[1].from,
149
149
  node.to,
150
150
  options.renderLinkButton
151
- ? Decoration.replace({
152
- widget: new LinkButton(url, options.renderLinkButton),
153
- })
151
+ ? Decoration.replace({ widget: new LinkButton(url, options.renderLinkButton) })
154
152
  : hide,
155
153
  );
156
154
  }
@@ -9,20 +9,20 @@ import { expect } from 'chai';
9
9
  import { describe, test } from '@dxos/test';
10
10
 
11
11
  import {
12
- setHeading,
12
+ addBlockquote,
13
+ addCodeblock,
14
+ addLink,
15
+ addList,
13
16
  addStyle,
17
+ getFormatting,
14
18
  removeStyle,
15
- addLink,
16
19
  removeLink,
17
- addList,
18
20
  removeList,
19
- addBlockquote,
20
21
  removeBlockquote,
21
- addCodeblock,
22
22
  removeCodeblock,
23
+ setHeading,
23
24
  Inline,
24
25
  List,
25
- getFormatting,
26
26
  type Formatting,
27
27
  } from './formatting';
28
28
 
@@ -204,22 +204,22 @@ describe('removeStyle', () => {
204
204
  });
205
205
 
206
206
  describe('addLink', () => {
207
- testCommand('adds a link', '{}', addLink, '[]({})');
207
+ testCommand('adds a link', '{}', addLink(), '[]({})');
208
208
 
209
- testCommand('adds a link around text', 'hello {world}', addLink, 'hello [world]({})');
209
+ testCommand('adds a link around text', 'hello {world}', addLink(), 'hello [world]({})');
210
210
 
211
- testCommand('clears existing links', '[hello {world}](foo)', addLink, 'hello [world]({})');
211
+ testCommand('clears existing links', '[hello {world}](foo)', addLink(), 'hello [world]({})');
212
212
 
213
- testCommand('does nothing across blocks', '{one\n\ntwo}', addLink, null);
213
+ testCommand('does nothing across blocks', '{one\n\ntwo}', addLink(), null);
214
214
 
215
- testCommand('does nothing in code blocks', '```\n{one}\n```', addLink, null);
215
+ testCommand('does nothing in code blocks', '```\n{one}\n```', addLink(), null);
216
216
 
217
- testCommand('patches up overlapping styles before', '*foo {bar* baz}', addLink, '*foo* [*bar* baz]({})');
217
+ testCommand('patches up overlapping styles before', '*foo {bar* baz}', addLink(), '*foo* [*bar* baz]({})');
218
218
 
219
219
  testCommand(
220
220
  'patches up overlapping styles after',
221
221
  'one {two ~~three} four~~',
222
- addLink,
222
+ addLink(),
223
223
  'one [two ~~three~~]({}) ~~four~~',
224
224
  );
225
225
  });