@dxos/ui-editor 0.0.0 → 0.8.4-main.05e74ebcff
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/index.mjs +8657 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/types/index.mjs +33 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +8659 -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/types/index.mjs +35 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/defaults.d.ts +6 -0
- package/dist/types/src/defaults.d.ts.map +1 -0
- package/dist/types/src/extensions/annotations.d.ts +9 -0
- package/dist/types/src/extensions/annotations.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts +17 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +23 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts +4 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts +4 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/defs.d.ts +17 -0
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts +2 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/sync.d.ts +17 -0
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +6 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts +5 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts +31 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts +46 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/index.d.ts +3 -0
- package/dist/types/src/extensions/awareness/index.d.ts.map +1 -0
- package/dist/types/src/extensions/blast.d.ts +25 -0
- package/dist/types/src/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/extensions/blocks.d.ts +2 -0
- package/dist/types/src/extensions/blocks.d.ts.map +1 -0
- package/dist/types/src/extensions/bookmarks.d.ts +12 -0
- package/dist/types/src/extensions/bookmarks.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts +90 -0
- package/dist/types/src/extensions/comments.d.ts.map +1 -0
- package/dist/types/src/extensions/debug.d.ts +3 -0
- package/dist/types/src/extensions/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/dnd.d.ts +9 -0
- package/dist/types/src/extensions/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.d.ts +88 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- 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 +6 -0
- package/dist/types/src/extensions/folding.d.ts.map +1 -0
- package/dist/types/src/extensions/hashtag.d.ts +3 -0
- package/dist/types/src/extensions/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +30 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/extensions/json.d.ts +7 -0
- package/dist/types/src/extensions/json.d.ts.map +1 -0
- package/dist/types/src/extensions/listener.d.ts +13 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/action.d.ts +12 -0
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts +25 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.d.ts +10 -0
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/debug.d.ts +11 -0
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts +25 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +63 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts +37 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts +7 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +10 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/link.d.ts +7 -0
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/styles.d.ts +4 -0
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts +8 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/mention.d.ts +7 -0
- package/dist/types/src/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/extensions/modal.d.ts +7 -0
- package/dist/types/src/extensions/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/modes.d.ts +10 -0
- package/dist/types/src/extensions/modes.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
- package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
- package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/index.d.ts +4 -0
- package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts +11 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/index.d.ts +2 -0
- package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +34 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.d.ts +21 -0
- package/dist/types/src/extensions/replacer.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.test.d.ts +2 -0
- package/dist/types/src/extensions/replacer.test.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts +75 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +5 -0
- package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts +24 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/state.d.ts +2 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts +10 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +7 -0
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +117 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +8 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/styles/index.d.ts +2 -0
- package/dist/types/src/styles/index.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts +58 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +21 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/src/util/cursor.d.ts +31 -0
- 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/decorations.d.ts +4 -0
- package/dist/types/src/util/decorations.d.ts.map +1 -0
- package/dist/types/src/util/dom.d.ts +10 -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 +7 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/util.d.ts +8 -0
- package/dist/types/src/util/util.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +43 -44
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +37 -11
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/blocks.ts +5 -5
- package/src/extensions/comments.ts +5 -6
- package/src/extensions/dnd.ts +2 -2
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +32 -15
- package/src/extensions/folding.ts +5 -22
- package/src/extensions/index.ts +2 -3
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +15 -12
- package/src/extensions/markdown/formatting.ts +5 -10
- package/src/extensions/markdown/highlight.ts +15 -7
- package/src/extensions/markdown/link.ts +27 -33
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +42 -9
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +3 -4
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +62 -15
- package/src/extensions/scrolling/auto-scroll.ts +244 -0
- package/src/extensions/scrolling/crawler.ts +263 -0
- package/src/extensions/scrolling/index.ts +8 -0
- package/src/extensions/scrolling/scroll-past-end.ts +32 -0
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +186 -35
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/index.ts +0 -2
- package/src/styles/theme.ts +125 -33
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/src/extensions/autoscroll.ts +0 -165
- package/src/extensions/scrolling.ts +0 -189
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
keymap,
|
|
18
18
|
lineNumbers,
|
|
19
19
|
placeholder,
|
|
20
|
-
scrollPastEnd,
|
|
21
20
|
} from '@codemirror/view';
|
|
22
21
|
import { vscodeDarkStyle, vscodeLightStyle } from '@uiw/codemirror-theme-vscode';
|
|
23
22
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
@@ -27,15 +26,14 @@ import { type DocAccessor } from '@dxos/echo-db';
|
|
|
27
26
|
import { log } from '@dxos/log';
|
|
28
27
|
import { type Messenger } from '@dxos/protocols';
|
|
29
28
|
import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
|
|
30
|
-
import { type
|
|
31
|
-
import { type ThemeMode } from '@dxos/ui-types';
|
|
29
|
+
import { type ChromaticPalette, type ThemeMode } from '@dxos/ui-types';
|
|
32
30
|
import { hexToHue, isTruthy } from '@dxos/util';
|
|
33
31
|
|
|
34
32
|
import { baseTheme, createFontTheme, editorGutter } from '../styles';
|
|
35
|
-
|
|
36
33
|
import { automerge } from './automerge';
|
|
37
34
|
import { SpaceAwarenessProvider, awareness } from './awareness';
|
|
38
35
|
import { focus } from './focus';
|
|
36
|
+
import { scrollPastEnd } from './scrolling';
|
|
39
37
|
|
|
40
38
|
//
|
|
41
39
|
// Basic
|
|
@@ -145,6 +143,19 @@ export const createBasicExtensions = (propsProp?: BasicExtensionsOptions): Exten
|
|
|
145
143
|
props.lineWrapping && EditorView.lineWrapping,
|
|
146
144
|
props.placeholder && placeholder(props.placeholder),
|
|
147
145
|
props.readOnly !== undefined && EditorState.readOnly.of(props.readOnly),
|
|
146
|
+
// `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing
|
|
147
|
+
// transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that
|
|
148
|
+
// continues a list) dispatch programmatic edits regardless. Drop user-initiated edits
|
|
149
|
+
// (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)
|
|
150
|
+
// but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers
|
|
151
|
+
// depend on being able to populate the doc themselves.
|
|
152
|
+
props.readOnly &&
|
|
153
|
+
EditorState.transactionFilter.of((tr) =>
|
|
154
|
+
tr.docChanged &&
|
|
155
|
+
(tr.isUserEvent('input') || tr.isUserEvent('delete') || tr.isUserEvent('undo') || tr.isUserEvent('redo'))
|
|
156
|
+
? []
|
|
157
|
+
: tr,
|
|
158
|
+
),
|
|
148
159
|
props.scrollPastEnd && scrollPastEnd(),
|
|
149
160
|
props.tabbable && tabbable,
|
|
150
161
|
props.tabSize && EditorState.tabSize.of(props.tabSize),
|
|
@@ -181,12 +192,12 @@ export const createBasicExtensions = (propsProp?: BasicExtensionsOptions): Exten
|
|
|
181
192
|
export type ThemeExtensionsOptions = {
|
|
182
193
|
monospace?: boolean;
|
|
183
194
|
themeMode?: ThemeMode;
|
|
195
|
+
scrollbarThin?: boolean;
|
|
184
196
|
slots?: {
|
|
185
197
|
editor?: {
|
|
186
198
|
className?: string;
|
|
187
199
|
};
|
|
188
|
-
|
|
189
|
-
// NOTE: Do not apply vertical padding to scroll container.
|
|
200
|
+
scroller?: {
|
|
190
201
|
className?: string;
|
|
191
202
|
};
|
|
192
203
|
content?: {
|
|
@@ -198,13 +209,13 @@ export type ThemeExtensionsOptions = {
|
|
|
198
209
|
|
|
199
210
|
export const grow: ThemeExtensionsOptions['slots'] = {
|
|
200
211
|
editor: {
|
|
201
|
-
className: '
|
|
212
|
+
className: 'h-full w-full',
|
|
202
213
|
},
|
|
203
214
|
} as const;
|
|
204
215
|
|
|
205
216
|
export const fullWidth: ThemeExtensionsOptions['slots'] = {
|
|
206
217
|
editor: {
|
|
207
|
-
className: '
|
|
218
|
+
className: 'w-full',
|
|
208
219
|
},
|
|
209
220
|
} as const;
|
|
210
221
|
|
|
@@ -220,11 +231,12 @@ export const defaultStyles = {
|
|
|
220
231
|
*/
|
|
221
232
|
export const createThemeExtensions = ({
|
|
222
233
|
monospace,
|
|
223
|
-
|
|
234
|
+
scrollbarThin,
|
|
224
235
|
slots: slotsProp,
|
|
225
236
|
syntaxHighlighting: syntaxHighlightingProp,
|
|
237
|
+
themeMode,
|
|
226
238
|
}: ThemeExtensionsOptions = {}): Extension => {
|
|
227
|
-
const slots = defaultsDeep({}, slotsProp, defaultThemeSlots);
|
|
239
|
+
const slots: NonNullable<ThemeExtensionsOptions['slots']> = defaultsDeep({}, slotsProp, defaultThemeSlots);
|
|
228
240
|
return [
|
|
229
241
|
baseTheme,
|
|
230
242
|
EditorView.darkTheme.of(themeMode === 'dark'),
|
|
@@ -233,11 +245,16 @@ export const createThemeExtensions = ({
|
|
|
233
245
|
syntaxHighlighting(HighlightStyle.define(themeMode === 'dark' ? defaultStyles.dark : defaultStyles.light)),
|
|
234
246
|
slots.editor?.className && EditorView.editorAttributes.of({ class: slots.editor.className }),
|
|
235
247
|
slots.content?.className && EditorView.contentAttributes.of({ class: slots.content.className }),
|
|
236
|
-
slots.
|
|
248
|
+
(slots.scroller?.className || scrollbarThin) &&
|
|
237
249
|
ViewPlugin.fromClass(
|
|
238
250
|
class {
|
|
239
251
|
constructor(view: EditorView) {
|
|
240
|
-
|
|
252
|
+
if (slots.scroller?.className) {
|
|
253
|
+
view.scrollDOM.classList.add(...slots.scroller.className.split(/\s+/));
|
|
254
|
+
}
|
|
255
|
+
if (scrollbarThin) {
|
|
256
|
+
view.scrollDOM.style.setProperty('--scrollbar-size', '4px');
|
|
257
|
+
}
|
|
241
258
|
}
|
|
242
259
|
},
|
|
243
260
|
),
|
|
@@ -263,7 +280,7 @@ export const createDataExtensions = <T>({ id, text, messenger, identity }: DataE
|
|
|
263
280
|
|
|
264
281
|
if (messenger && identity) {
|
|
265
282
|
const peerId = identity?.identityKey.toHex();
|
|
266
|
-
const hue = (identity?.profile?.data?.hue as
|
|
283
|
+
const hue = (identity?.profile?.data?.hue as ChromaticPalette | undefined) ?? hexToHue(peerId ?? '0');
|
|
267
284
|
extensions.push(
|
|
268
285
|
awareness(
|
|
269
286
|
new SpaceAwarenessProvider({
|
|
@@ -271,8 +288,8 @@ export const createDataExtensions = <T>({ id, text, messenger, identity }: DataE
|
|
|
271
288
|
channel: `awareness.${id}`,
|
|
272
289
|
peerId: identity.identityKey.toHex(),
|
|
273
290
|
info: {
|
|
274
|
-
darkColor: `var(--
|
|
275
|
-
lightColor: `var(--
|
|
291
|
+
darkColor: `var(--color-${hue}-border)`,
|
|
292
|
+
lightColor: `var(--color-${hue}-border)`,
|
|
276
293
|
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
277
294
|
},
|
|
278
295
|
}),
|
|
@@ -17,37 +17,20 @@ export const folding = (): Extension => {
|
|
|
17
17
|
placeholderDOM: () => Domino.of('span').root,
|
|
18
18
|
}),
|
|
19
19
|
foldGutter({
|
|
20
|
+
// NOTE: We can't animate since the element is remounted on state change.
|
|
20
21
|
markerDOM: (open) => {
|
|
21
22
|
return Domino.of('div')
|
|
22
|
-
.classNames('flex
|
|
23
|
-
.
|
|
23
|
+
.classNames('flex h-full justify-center items-center')
|
|
24
|
+
.append(
|
|
24
25
|
Domino.of('svg', Domino.SVG)
|
|
25
|
-
.classNames(mx('
|
|
26
|
-
.
|
|
26
|
+
.classNames(mx('w-4 h-4 cursor-pointer', open && 'rotate-90'))
|
|
27
|
+
.append(
|
|
27
28
|
Domino.of('use', Domino.SVG).attributes({
|
|
28
29
|
href: Domino.icon('ph--caret-right--regular'),
|
|
29
30
|
}),
|
|
30
31
|
),
|
|
31
32
|
).root;
|
|
32
33
|
},
|
|
33
|
-
// TODO(burdon): markerDOM is called either way, defeating the animation: transition-transform duration-200
|
|
34
|
-
// domEventHandlers: {
|
|
35
|
-
// click: (view, line: BlockInfo, event) => {
|
|
36
|
-
// event.preventDefault();
|
|
37
|
-
// event.stopPropagation();
|
|
38
|
-
// const range = foldable(view.state, line.from, line.to);
|
|
39
|
-
// if (range) {
|
|
40
|
-
// view.dispatch({ effects: foldEffect.of(range) });
|
|
41
|
-
// (event.target as HTMLElement)?.classList.add('rotate-90');
|
|
42
|
-
// } else {
|
|
43
|
-
// foldedRanges(view.state).between(line.from, line.to, (from, to) => {
|
|
44
|
-
// view.dispatch({ effects: unfoldEffect.of({ from, to }) });
|
|
45
|
-
// (event.target as HTMLElement)?.classList.remove('rotate-90');
|
|
46
|
-
// });
|
|
47
|
-
// }
|
|
48
|
-
// return true;
|
|
49
|
-
// },
|
|
50
|
-
// },
|
|
51
34
|
}),
|
|
52
35
|
EditorView.theme({
|
|
53
36
|
'.cm-foldGutter': {
|
package/src/extensions/index.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
export * from './annotations';
|
|
6
6
|
export * from './autocomplete';
|
|
7
|
-
export * from './autoscroll';
|
|
8
7
|
export * from './automerge';
|
|
9
8
|
export * from './awareness';
|
|
10
9
|
export * from './blast';
|
|
@@ -26,9 +25,9 @@ export * from './modes';
|
|
|
26
25
|
export * from './outliner';
|
|
27
26
|
export * from './preview';
|
|
28
27
|
export * from './replacer';
|
|
29
|
-
export * from './selection';
|
|
30
28
|
export * from './scrolling';
|
|
29
|
+
export * from './selection';
|
|
30
|
+
export * from './snippets';
|
|
31
31
|
export * from './state';
|
|
32
32
|
export * from './submit';
|
|
33
33
|
export * from './tags';
|
|
34
|
-
export * from './typewriter';
|
|
@@ -6,8 +6,7 @@ import { completionKeymap } from '@codemirror/autocomplete';
|
|
|
6
6
|
import { defaultKeymap, indentWithTab } from '@codemirror/commands';
|
|
7
7
|
import { jsonLanguage } from '@codemirror/lang-json';
|
|
8
8
|
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
|
9
|
-
import {
|
|
10
|
-
import { LanguageDescription, syntaxHighlighting } from '@codemirror/language';
|
|
9
|
+
import { type LanguageDescription, foldNodeProp, syntaxHighlighting } from '@codemirror/language';
|
|
11
10
|
import { languages } from '@codemirror/language-data';
|
|
12
11
|
import { type Extension } from '@codemirror/state';
|
|
13
12
|
import { keymap } from '@codemirror/view';
|
|
@@ -18,6 +17,8 @@ import { isTruthy } from '@dxos/util';
|
|
|
18
17
|
import { markdownHighlightStyle, markdownTagsExtensions } from './highlight';
|
|
19
18
|
|
|
20
19
|
export type MarkdownBundleOptions = {
|
|
20
|
+
/** Additional fenced-code languages prepended to the standard language-data list. */
|
|
21
|
+
codeLanguages?: LanguageDescription[];
|
|
21
22
|
extensions?: MarkdownConfig[];
|
|
22
23
|
indentWithTab?: boolean;
|
|
23
24
|
setextHeading?: boolean;
|
|
@@ -45,8 +46,9 @@ export const createMarkdownExtensions = (options: MarkdownBundleOptions = {}): E
|
|
|
45
46
|
base: markdownLanguage,
|
|
46
47
|
|
|
47
48
|
// Languages for syntax highlighting fenced code blocks.
|
|
49
|
+
// Caller-supplied languages are checked first so they can override defaults.
|
|
48
50
|
defaultCodeLanguage: jsonLanguage,
|
|
49
|
-
codeLanguages: languages,
|
|
51
|
+
codeLanguages: [...(options.codeLanguages ?? []), ...languages],
|
|
50
52
|
|
|
51
53
|
// Don't complete HTML tags.
|
|
52
54
|
completeHTMLTags: false,
|
|
@@ -56,6 +58,10 @@ export const createMarkdownExtensions = (options: MarkdownBundleOptions = {}): E
|
|
|
56
58
|
// GFM provided by default.
|
|
57
59
|
markdownTagsExtensions,
|
|
58
60
|
...(options.extensions ?? defaultExtensions()),
|
|
61
|
+
// Disable folding for fenced code blocks by overriding foldNodeProp.
|
|
62
|
+
// Note: returning null from foldService does not prevent syntaxFolding fallback,
|
|
63
|
+
// so we must override the node prop directly on the FencedCode node type.
|
|
64
|
+
noFencedCodeFolding,
|
|
59
65
|
],
|
|
60
66
|
}),
|
|
61
67
|
|
|
@@ -77,12 +83,20 @@ export const createMarkdownExtensions = (options: MarkdownBundleOptions = {}): E
|
|
|
77
83
|
];
|
|
78
84
|
};
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Disables folding for fenced code blocks.
|
|
88
|
+
*
|
|
89
|
+
* foldService cannot block folding because returning null just defers to the next service,
|
|
90
|
+
* and CodeMirror always falls back to syntaxFolding (which reads foldNodeProp).
|
|
91
|
+
* The only reliable fix is to override foldNodeProp on FencedCode to return null.
|
|
92
|
+
*/
|
|
93
|
+
const noFencedCodeFolding: MarkdownConfig = {
|
|
94
|
+
props: [
|
|
95
|
+
foldNodeProp.add({
|
|
96
|
+
FencedCode: () => null,
|
|
97
|
+
}),
|
|
98
|
+
],
|
|
99
|
+
};
|
|
86
100
|
|
|
87
101
|
/**
|
|
88
102
|
* Default customizations.
|
|
@@ -8,12 +8,10 @@ import { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate
|
|
|
8
8
|
import { type SyntaxNodeRef } from '@lezer/common';
|
|
9
9
|
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import { mx } from '@dxos/ui-theme';
|
|
12
11
|
|
|
13
12
|
import { type HeadingLevel, markdownTheme } from '../../styles';
|
|
14
13
|
import { type RenderCallback } from '../../types';
|
|
15
14
|
import { wrapWithCatch } from '../../util';
|
|
16
|
-
|
|
17
15
|
import { adjustChanges } from './changes';
|
|
18
16
|
import { image } from './image';
|
|
19
17
|
import { bulletListIndentationWidth, formattingStyles, orderedListIndentationWidth } from './styles';
|
|
@@ -56,7 +54,6 @@ class LinkButton extends WidgetType {
|
|
|
56
54
|
return this.url === other.url;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
// TODO(burdon): Create icon and link directly without react?
|
|
60
57
|
override toDOM(view: EditorView) {
|
|
61
58
|
const el = document.createElement('span');
|
|
62
59
|
this.render(el, { url: this.url }, view);
|
|
@@ -132,8 +129,8 @@ class TextWidget extends WidgetType {
|
|
|
132
129
|
const hide = Decoration.replace({});
|
|
133
130
|
const blockQuote = Decoration.line({ class: 'cm-blockquote' });
|
|
134
131
|
const fencedCodeLine = Decoration.line({ class: 'cm-code cm-codeblock-line' });
|
|
135
|
-
const fencedCodeLineFirst = Decoration.line({ class:
|
|
136
|
-
const fencedCodeLineLast = Decoration.line({ class:
|
|
132
|
+
const fencedCodeLineFirst = Decoration.line({ class: 'cm-code cm-codeblock-line cm-codeblock-start' });
|
|
133
|
+
const fencedCodeLineLast = Decoration.line({ class: 'cm-code cm-codeblock-line cm-codeblock-end' });
|
|
137
134
|
const commentBlockLine = fencedCodeLine;
|
|
138
135
|
const commentBlockLineFirst = fencedCodeLineFirst;
|
|
139
136
|
const commentBlockLineLast = fencedCodeLineLast;
|
|
@@ -244,14 +241,14 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
244
241
|
headers
|
|
245
242
|
.slice(from - 1)
|
|
246
243
|
.map((level) => level?.number ?? 0)
|
|
247
|
-
.join('.') + ' ';
|
|
244
|
+
.join('.') + '). ';
|
|
248
245
|
|
|
249
246
|
if (num.length) {
|
|
250
247
|
atomicDecoRanges.push({
|
|
251
248
|
from: mark.from,
|
|
252
249
|
to: mark.from + len,
|
|
253
250
|
deco: Decoration.replace({
|
|
254
|
-
widget: new TextWidget(num, markdownTheme.heading(level)),
|
|
251
|
+
widget: new TextWidget(num, markdownTheme.heading(level).className),
|
|
255
252
|
}),
|
|
256
253
|
});
|
|
257
254
|
}
|
|
@@ -440,11 +437,11 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
440
437
|
|
|
441
438
|
decoRanges.push({
|
|
442
439
|
from: marks[0].to,
|
|
443
|
-
to: marks[1].from,
|
|
440
|
+
to: !editing && options.renderLinkButton ? node.to : marks[1].from,
|
|
444
441
|
deco: Decoration.mark({
|
|
445
442
|
tagName: 'a',
|
|
446
443
|
attributes: {
|
|
447
|
-
class: 'cm-link',
|
|
444
|
+
class: options.renderLinkButton ? 'cm-link cm-link-with-button' : 'cm-link',
|
|
448
445
|
href: url,
|
|
449
446
|
rel: 'noreferrer',
|
|
450
447
|
target: '_blank',
|
|
@@ -457,7 +454,9 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
457
454
|
from: marks[1].from,
|
|
458
455
|
to: node.to,
|
|
459
456
|
deco: options.renderLinkButton
|
|
460
|
-
? Decoration.replace({
|
|
457
|
+
? Decoration.replace({
|
|
458
|
+
widget: new LinkButton(url, options.renderLinkButton),
|
|
459
|
+
})
|
|
461
460
|
: hide,
|
|
462
461
|
});
|
|
463
462
|
}
|
|
@@ -527,8 +526,12 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
|
527
526
|
}
|
|
528
527
|
|
|
529
528
|
const atomicDeco = new RangeSetBuilder<Decoration>();
|
|
530
|
-
for (const { from, to, deco
|
|
531
|
-
|
|
529
|
+
for (const { from, to, deco } of atomicDecoRanges) {
|
|
530
|
+
// Skip replace decorations that span line breaks (not allowed by CodeMirror plugins).
|
|
531
|
+
if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
atomicDeco.add(from, to, deco);
|
|
532
535
|
}
|
|
533
536
|
|
|
534
537
|
return {
|
|
@@ -1245,20 +1245,15 @@ export const getFormatting = (state: EditorState): Formatting => {
|
|
|
1245
1245
|
};
|
|
1246
1246
|
|
|
1247
1247
|
/**
|
|
1248
|
-
*
|
|
1248
|
+
* Extension to compute and publish the current formatting state.
|
|
1249
|
+
* @param onStateChange - Callback invoked with the current formatting state when the editor state changes.
|
|
1250
|
+
* @param delay - Debounce/throttle delay in ms.
|
|
1249
1251
|
*/
|
|
1250
|
-
export const formattingListener = (
|
|
1252
|
+
export const formattingListener = (onStateChange: (state: Formatting) => void, delay = 100): Extension => {
|
|
1251
1253
|
return EditorView.updateListener.of(
|
|
1252
1254
|
debounceAndThrottle((update: ViewUpdate) => {
|
|
1253
1255
|
if (update.docChanged || update.selectionSet) {
|
|
1254
|
-
|
|
1255
|
-
if (!state) {
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
Object.entries(getFormatting(update.state)).forEach(([key, active]) => {
|
|
1260
|
-
state[key as keyof Formatting] = active as any;
|
|
1261
|
-
});
|
|
1256
|
+
onStateChange(getFormatting(update.state));
|
|
1262
1257
|
}
|
|
1263
1258
|
}, delay),
|
|
1264
1259
|
);
|
|
@@ -145,13 +145,21 @@ export const markdownHighlightStyle = (_options: HighlightOptions = {}) => {
|
|
|
145
145
|
class: 'font-mono',
|
|
146
146
|
},
|
|
147
147
|
|
|
148
|
-
// Headings
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
// Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via
|
|
149
|
+
// StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,
|
|
150
|
+
// HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).
|
|
151
|
+
// Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.
|
|
152
|
+
{
|
|
153
|
+
tag: tags.heading,
|
|
154
|
+
color: 'var(--color-cm-heading) !important',
|
|
155
|
+
fontWeight: '300',
|
|
156
|
+
},
|
|
157
|
+
{ tag: tags.heading1, ...markdownTheme.heading(1) },
|
|
158
|
+
{ tag: tags.heading2, ...markdownTheme.heading(2) },
|
|
159
|
+
{ tag: tags.heading3, ...markdownTheme.heading(3) },
|
|
160
|
+
{ tag: tags.heading4, ...markdownTheme.heading(4) },
|
|
161
|
+
{ tag: tags.heading5, ...markdownTheme.heading(5) },
|
|
162
|
+
{ tag: tags.heading6, ...markdownTheme.heading(6) },
|
|
155
163
|
|
|
156
164
|
// Emphasis.
|
|
157
165
|
{ tag: tags.emphasis, class: 'italic' },
|
|
@@ -12,39 +12,33 @@ import { tooltipContent } from '@dxos/ui-theme';
|
|
|
12
12
|
import { type RenderCallback } from '../../types';
|
|
13
13
|
|
|
14
14
|
export const linkTooltip = (renderTooltip: RenderCallback<{ url: string }>) => {
|
|
15
|
-
return hoverTooltip(
|
|
16
|
-
(view
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
15
|
+
return hoverTooltip((view, pos, side) => {
|
|
16
|
+
const syntax = syntaxTree(view.state).resolveInner(pos, side);
|
|
17
|
+
let link = null;
|
|
18
|
+
for (let i = 0, node: SyntaxNode | null = syntax; !link && node && i < 5; node = node.parent, i++) {
|
|
19
|
+
link = node.name === 'Link' ? node : null;
|
|
20
|
+
}
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const url = link && link.getChild('URL');
|
|
23
|
+
if (!url || !link) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
// NOTE: 0 = default of 300ms.
|
|
47
|
-
hoverTime: 1,
|
|
48
|
-
},
|
|
49
|
-
);
|
|
27
|
+
const urlText = view.state.sliceDoc(url.from, url.to);
|
|
28
|
+
if (urlText.startsWith('dxn')) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
pos: link.from,
|
|
34
|
+
end: link.to,
|
|
35
|
+
above: true,
|
|
36
|
+
create: () => {
|
|
37
|
+
const el = document.createElement('div');
|
|
38
|
+
el.className = tooltipContent({});
|
|
39
|
+
renderTooltip(el, { url: urlText }, view);
|
|
40
|
+
return { dom: el, offset: { x: 0, y: 4 } };
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
});
|
|
50
44
|
};
|
|
@@ -18,7 +18,7 @@ export const formattingStyles = EditorView.theme({
|
|
|
18
18
|
width: '100%',
|
|
19
19
|
height: '0',
|
|
20
20
|
verticalAlign: 'middle',
|
|
21
|
-
borderTop: '1px solid var(--
|
|
21
|
+
borderTop: '1px solid var(--color-cm-separator)',
|
|
22
22
|
opacity: 0.5,
|
|
23
23
|
},
|
|
24
24
|
|
|
@@ -43,20 +43,45 @@ export const formattingStyles = EditorView.theme({
|
|
|
43
43
|
* Blockquote.
|
|
44
44
|
*/
|
|
45
45
|
'& .cm-blockquote': {
|
|
46
|
-
background: 'var(--
|
|
47
|
-
borderLeft: '2px solid var(--
|
|
46
|
+
background: 'var(--color-cm-codeblock)',
|
|
47
|
+
borderLeft: '2px solid var(--color-cm-separator)',
|
|
48
48
|
paddingLeft: '1rem',
|
|
49
|
-
margin:
|
|
49
|
+
margin: 0,
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* Code and codeblocks.
|
|
54
54
|
*/
|
|
55
|
+
'& code': {
|
|
56
|
+
fontFamily: fontMono,
|
|
57
|
+
color: 'var(--color-cm-code)',
|
|
58
|
+
whiteSpace: 'nowrap',
|
|
59
|
+
},
|
|
55
60
|
'& .cm-code': {
|
|
56
61
|
fontFamily: fontMono,
|
|
62
|
+
color: 'var(--color-cm-code)',
|
|
63
|
+
},
|
|
64
|
+
// Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.
|
|
65
|
+
// Different monospace font metrics can slightly overflow the fixed CodeMirror line box,
|
|
66
|
+
// so constrain them to the target 24px height.
|
|
67
|
+
'& .cm-code-inline': {
|
|
68
|
+
fontFamily: fontMono,
|
|
69
|
+
height: '24px',
|
|
70
|
+
// display: 'inline-flex',
|
|
71
|
+
alignItems: 'center',
|
|
72
|
+
overflow: 'hidden',
|
|
73
|
+
whiteSpace: 'nowrap',
|
|
74
|
+
color: 'var(--color-cm-code-inline)',
|
|
75
|
+
},
|
|
76
|
+
'& .cm-code-mark': {
|
|
77
|
+
fontFamily: fontMono,
|
|
78
|
+
height: '24px',
|
|
79
|
+
display: 'inline-flex',
|
|
80
|
+
alignItems: 'center',
|
|
81
|
+
overflow: 'hidden',
|
|
57
82
|
},
|
|
58
83
|
'& .cm-codeblock-line': {
|
|
59
|
-
background: 'var(--
|
|
84
|
+
background: 'var(--color-cm-codeblock)',
|
|
60
85
|
paddingInline: '1rem !important',
|
|
61
86
|
},
|
|
62
87
|
'& .cm-codeblock-start': {
|
|
@@ -87,16 +112,24 @@ export const formattingStyles = EditorView.theme({
|
|
|
87
112
|
*/
|
|
88
113
|
'.cm-table *': {
|
|
89
114
|
fontFamily: fontMono,
|
|
115
|
+
lineHeight: 1.5,
|
|
90
116
|
textDecoration: 'none !important',
|
|
91
117
|
},
|
|
92
118
|
'.cm-table-head': {
|
|
93
119
|
padding: '2px 16px 2px 0px',
|
|
120
|
+
overflowWrap: 'break-word',
|
|
121
|
+
whiteSpace: 'pre-wrap',
|
|
122
|
+
wordBreak: 'keep-all',
|
|
94
123
|
textAlign: 'left',
|
|
95
|
-
|
|
96
|
-
|
|
124
|
+
color: 'var(--color-subdued)',
|
|
125
|
+
borderBottom: '1px solid var(--color-cm-separator)',
|
|
97
126
|
},
|
|
98
127
|
'.cm-table-cell': {
|
|
99
128
|
padding: '2px 16px 2px 0px',
|
|
129
|
+
overflowWrap: 'break-word',
|
|
130
|
+
whiteSpace: 'pre-wrap',
|
|
131
|
+
wordBreak: 'keep-all',
|
|
132
|
+
verticalAlign: 'top',
|
|
100
133
|
},
|
|
101
134
|
|
|
102
135
|
/**
|
|
@@ -113,12 +146,12 @@ export const formattingStyles = EditorView.theme({
|
|
|
113
146
|
},
|
|
114
147
|
'.cm-image-with-loader': {
|
|
115
148
|
display: 'block',
|
|
116
|
-
opacity:
|
|
149
|
+
opacity: 0,
|
|
117
150
|
transitionDuration: '350ms',
|
|
118
151
|
transitionProperty: 'opacity',
|
|
119
152
|
},
|
|
120
153
|
'.cm-image-with-loader.cm-loaded-image': {
|
|
121
|
-
opacity:
|
|
154
|
+
opacity: 1,
|
|
122
155
|
},
|
|
123
156
|
'.cm-image-wrapper': {
|
|
124
157
|
'grid-template-columns': '1fr',
|
|
@@ -107,6 +107,28 @@ const update = (state: EditorState, _options: TableOptions) => {
|
|
|
107
107
|
return builder.finish();
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
/** Renders cell text into el, processing inline markdown (bold, italic, code). */
|
|
111
|
+
const renderCellContent = (el: HTMLElement, text: string): void => {
|
|
112
|
+
const parts = text.split(/(`[^`\n]+`|\*\*[^*\n]+\*\*|__[^_\n]+__|\*[^*\n]+\*|_[^_\n]+_)/);
|
|
113
|
+
for (const part of parts) {
|
|
114
|
+
if (part.length > 2 && part.startsWith('`') && part.endsWith('`')) {
|
|
115
|
+
const code = document.createElement('code');
|
|
116
|
+
code.textContent = part.slice(1, -1);
|
|
117
|
+
el.appendChild(code);
|
|
118
|
+
} else if ((part.startsWith('**') && part.endsWith('**')) || (part.startsWith('__') && part.endsWith('__'))) {
|
|
119
|
+
const strong = document.createElement('strong');
|
|
120
|
+
strong.textContent = part.slice(2, -2);
|
|
121
|
+
el.appendChild(strong);
|
|
122
|
+
} else if ((part.startsWith('*') && part.endsWith('*')) || (part.startsWith('_') && part.endsWith('_'))) {
|
|
123
|
+
const em = document.createElement('em');
|
|
124
|
+
em.textContent = part.slice(1, -1);
|
|
125
|
+
el.appendChild(em);
|
|
126
|
+
} else {
|
|
127
|
+
el.appendChild(document.createTextNode(part));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
110
132
|
class TableWidget extends WidgetType {
|
|
111
133
|
constructor(readonly _table: Table) {
|
|
112
134
|
super();
|
|
@@ -132,7 +154,7 @@ class TableWidget extends WidgetType {
|
|
|
132
154
|
this._table.header?.forEach((cell) => {
|
|
133
155
|
const th = document.createElement('th');
|
|
134
156
|
th.setAttribute('class', 'cm-table-head');
|
|
135
|
-
tr.appendChild(th)
|
|
157
|
+
renderCellContent(tr.appendChild(th), cell);
|
|
136
158
|
});
|
|
137
159
|
|
|
138
160
|
const body = table.appendChild(document.createElement('tbody'));
|
|
@@ -141,7 +163,7 @@ class TableWidget extends WidgetType {
|
|
|
141
163
|
row.forEach((cell) => {
|
|
142
164
|
const td = document.createElement('td');
|
|
143
165
|
td.setAttribute('class', 'cm-table-cell');
|
|
144
|
-
tr.appendChild(td)
|
|
166
|
+
renderCellContent(tr.appendChild(td), cell);
|
|
145
167
|
});
|
|
146
168
|
});
|
|
147
169
|
|
|
@@ -8,7 +8,6 @@ import { describe, test } from 'vitest';
|
|
|
8
8
|
|
|
9
9
|
import { join } from '../../util';
|
|
10
10
|
import { createMarkdownExtensions } from '../markdown';
|
|
11
|
-
|
|
12
11
|
import { indentItemLess, indentItemMore, moveItemDown, moveItemUp } from './commands';
|
|
13
12
|
import { listItemToString, outlinerTree, treeFacet } from './tree';
|
|
14
13
|
|