@dxos/ui-editor 0.8.4-main.bc674ce → 0.8.4-main.c85a9c8dae

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 (61) hide show
  1. package/dist/lib/browser/index.mjs +483 -417
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +483 -417
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/defaults.d.ts +1 -1
  8. package/dist/types/src/defaults.d.ts.map +1 -1
  9. package/dist/types/src/extensions/auto-scroll.d.ts +6 -0
  10. package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -0
  11. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  12. package/dist/types/src/extensions/index.d.ts +2 -2
  13. package/dist/types/src/extensions/index.d.ts.map +1 -1
  14. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  15. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  16. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  17. package/dist/types/src/extensions/preview/preview.d.ts +1 -1
  18. package/dist/types/src/extensions/scroller.d.ts +66 -0
  19. package/dist/types/src/extensions/scroller.d.ts.map +1 -0
  20. package/dist/types/src/styles/index.d.ts +0 -2
  21. package/dist/types/src/styles/index.d.ts.map +1 -1
  22. package/dist/types/src/styles/theme.d.ts +15 -0
  23. package/dist/types/src/styles/theme.d.ts.map +1 -1
  24. package/dist/types/src/util/cursor.d.ts +1 -1
  25. package/dist/types/src/util/cursor.d.ts.map +1 -1
  26. package/dist/types/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +32 -32
  28. package/src/defaults.ts +4 -4
  29. package/src/extensions/annotations.ts +1 -1
  30. package/src/extensions/auto-scroll.ts +126 -0
  31. package/src/extensions/automerge/automerge.test.tsx +2 -2
  32. package/src/extensions/blocks.ts +5 -5
  33. package/src/extensions/comments.ts +5 -5
  34. package/src/extensions/dnd.ts +2 -2
  35. package/src/extensions/factories.ts +6 -7
  36. package/src/extensions/folding.ts +2 -2
  37. package/src/extensions/index.ts +2 -2
  38. package/src/extensions/markdown/decorate.ts +4 -3
  39. package/src/extensions/markdown/highlight.ts +25 -11
  40. package/src/extensions/markdown/link.ts +27 -33
  41. package/src/extensions/markdown/styles.ts +6 -6
  42. package/src/extensions/outliner/outliner.ts +3 -3
  43. package/src/extensions/preview/preview.ts +8 -8
  44. package/src/extensions/scroller.ts +232 -0
  45. package/src/extensions/tags/streamer.ts +1 -1
  46. package/src/extensions/tags/xml-tags.ts +7 -4
  47. package/src/styles/index.ts +0 -2
  48. package/src/styles/theme.ts +106 -29
  49. package/src/util/cursor.ts +1 -1
  50. package/dist/types/src/extensions/autoscroll.d.ts +0 -20
  51. package/dist/types/src/extensions/autoscroll.d.ts.map +0 -1
  52. package/dist/types/src/extensions/scrolling.d.ts +0 -78
  53. package/dist/types/src/extensions/scrolling.d.ts.map +0 -1
  54. package/dist/types/src/styles/markdown.d.ts +0 -8
  55. package/dist/types/src/styles/markdown.d.ts.map +0 -1
  56. package/dist/types/src/styles/tokens.d.ts +0 -3
  57. package/dist/types/src/styles/tokens.d.ts.map +0 -1
  58. package/src/extensions/autoscroll.ts +0 -165
  59. package/src/extensions/scrolling.ts +0 -189
  60. package/src/styles/markdown.ts +0 -26
  61. package/src/styles/tokens.ts +0 -17
@@ -61,7 +61,7 @@ export const outliner = (_options: OutlinerProps = {}): Extension => [
61
61
  decorateMarkdown({ listPaddingLeft: 8 }),
62
62
 
63
63
  // Researve space for menu.
64
- EditorView.contentAttributes.of({ class: 'is-full !mr-[3rem]' }),
64
+ EditorView.contentAttributes.of({ class: 'w-full !mr-[3rem]' }),
65
65
  ];
66
66
 
67
67
  /**
@@ -157,10 +157,10 @@ const decorations = () => [
157
157
  },
158
158
 
159
159
  '.cm-list-item-focused': {
160
- borderColor: 'var(--dx-neutralFocusIndicator)',
160
+ borderColor: 'var(--color-neutral-focus-indicator)',
161
161
  },
162
162
  '&:focus-within .cm-list-item-selected': {
163
- borderColor: 'var(--dx-separator)',
163
+ borderColor: 'var(--color-separator)',
164
164
  },
165
165
  }),
166
166
  ),
@@ -16,7 +16,7 @@ export type PreviewLinkRef = {
16
16
  suggest?: boolean;
17
17
  block?: boolean;
18
18
  label: string;
19
- ref: string;
19
+ dxn: string;
20
20
  };
21
21
 
22
22
  export type PreviewLinkTarget = {
@@ -119,13 +119,13 @@ export const getLinkRef = (state: EditorState, node: SyntaxNode): PreviewLinkRef
119
119
  const mark = node.getChildren('LinkMark');
120
120
  const urlNode = node.getChild('URL');
121
121
  if (mark && urlNode) {
122
- const url = state.sliceDoc(urlNode.from, urlNode.to);
123
- if (url.startsWith('dxn:')) {
122
+ const dxn = state.sliceDoc(urlNode.from, urlNode.to);
123
+ if (dxn.startsWith('dxn:')) {
124
124
  const label = state.sliceDoc(mark[0].to, mark[1].from);
125
125
  return {
126
126
  block: state.sliceDoc(mark[0].from, mark[0].from + 1) === '!',
127
127
  label,
128
- ref: url,
128
+ dxn,
129
129
  };
130
130
  }
131
131
  }
@@ -148,14 +148,14 @@ class PreviewInlineWidget extends WidgetType {
148
148
  // }
149
149
 
150
150
  override eq(other: this) {
151
- return this._link.ref === other._link.ref && this._link.label === other._link.label;
151
+ return this._link.dxn === other._link.dxn && this._link.label === other._link.label;
152
152
  }
153
153
 
154
154
  override toDOM(_view: EditorView) {
155
155
  const root = document.createElement('dx-anchor');
156
156
  root.classList.add('dx-tag--anchor');
157
157
  root.textContent = this._link.label;
158
- root.setAttribute('refId', this._link.ref);
158
+ root.setAttribute('dxn', this._link.dxn);
159
159
  return root;
160
160
  }
161
161
  }
@@ -177,12 +177,12 @@ class PreviewBlockWidget extends WidgetType {
177
177
  // }
178
178
 
179
179
  override eq(other: this) {
180
- return this._link.ref === other._link.ref;
180
+ return this._link.dxn === other._link.dxn;
181
181
  }
182
182
 
183
183
  override toDOM(_view: EditorView) {
184
184
  const root = document.createElement('div');
185
- root.classList.add('cm-preview-block', 'density-fine');
185
+ root.classList.add('cm-preview-block', 'dx-density-fine');
186
186
  this._options.addBlockContainer?.({ link: this._link, el: root });
187
187
  return root;
188
188
  }
@@ -0,0 +1,232 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { StateEffect } from '@codemirror/state';
6
+ import { EditorView, ViewPlugin } from '@codemirror/view';
7
+
8
+ import { log } from '@dxos/log';
9
+
10
+ /**
11
+ * Parameters for the scroll to line effect.
12
+ */
13
+ export type ScrollToProps = {
14
+ /**
15
+ * Zero-based line number; -1 for end of document.
16
+ * NOTE: view.state.doc.lineAt() uses 1-based line numbers.
17
+ */
18
+ line: number;
19
+
20
+ /**
21
+ * Additional offset from the target line in pixels.
22
+ * Positive values scroll past the line, negative values stop before it.
23
+ * @default 0
24
+ */
25
+ offset?: number;
26
+
27
+ /**
28
+ * Position of the target line in the viewport.
29
+ * - 'start': Line appears at the start (top) of the screen
30
+ * - 'end': Line appears at the end (bottom) of the screen
31
+ * @default 'start'
32
+ */
33
+ position?: 'start' | 'end';
34
+
35
+ /**
36
+ * Whether to use smooth scrolling.
37
+ * @default 'instant'
38
+ */
39
+ behavior?: ScrollBehavior;
40
+ };
41
+
42
+ /** Scroll to a specific line. */
43
+ export const scrollerLineEffect = StateEffect.define<ScrollToProps>();
44
+
45
+ /** Start/stop crawling the end of the document. */
46
+ export const scrollerCrawlEffect = StateEffect.define<boolean>();
47
+
48
+ /**
49
+ * Helper function to scroll to a specific line.
50
+ * This is a convenience function that can be used directly with an EditorView.
51
+ */
52
+ export const scrollToLine = (view: EditorView, options: ScrollToProps) => {
53
+ view.dispatch({
54
+ effects: scrollerLineEffect.of(options),
55
+ });
56
+ };
57
+
58
+ export type ScrollerOptions = {
59
+ /** Threshold in px to trigger scroll from bottom. */
60
+ overScroll?: number;
61
+ };
62
+
63
+ /**
64
+ * Extension that provides smooth scrolling to specific lines in the editor.
65
+ */
66
+ export const scroller = ({ overScroll = 0 }: ScrollerOptions = {}) => {
67
+ // ViewPlugin to manage scroll animations.
68
+ const scrollPlugin = ViewPlugin.fromClass(
69
+ class ScrollerPlugin {
70
+ private readonly crawler: ReturnType<typeof createCrawler>;
71
+ constructor(private readonly view: EditorView) {
72
+ this.crawler = createCrawler(this.view);
73
+ }
74
+
75
+ // No-op.
76
+ destroy() {
77
+ this.crawler.cancel();
78
+ }
79
+
80
+ cancel() {
81
+ this.crawler.cancel();
82
+ }
83
+
84
+ crawl(start = false) {
85
+ if (start) {
86
+ this.crawler.scroll();
87
+ } else {
88
+ this.crawler.cancel();
89
+ }
90
+ }
91
+
92
+ scroll({ line, offset = 0, position, behavior = 'instant' }: ScrollToProps) {
93
+ const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;
94
+ const scrollerRect = this.view.scrollDOM.getBoundingClientRect();
95
+ const doc = this.view.state.doc;
96
+
97
+ let targetScrollTop = scrollHeight - clientHeight + offset;
98
+ if (line >= 0 && line <= doc.lines - 1) {
99
+ const lineStart = doc.line(line + 1).from;
100
+ const coords = this.view.coordsAtPos(lineStart);
101
+ if (coords) {
102
+ // Calculate target scroll position based on position option.
103
+ const currentScrollTop = scrollTop;
104
+ const maxScrollTop = scrollHeight - clientHeight;
105
+
106
+ if (position === 'end') {
107
+ // Position line at end (bottom) of viewport.
108
+ // Calculate how far down we need to scroll so the line's bottom aligns with viewport bottom.
109
+ targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;
110
+ } else {
111
+ // Default: position line at start (top) of viewport.
112
+ targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;
113
+ }
114
+
115
+ // Clamp to valid scroll range.
116
+ targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
117
+ }
118
+ }
119
+
120
+ requestAnimationFrame(() => {
121
+ this.view.scrollDOM.scrollTo({ top: targetScrollTop, behavior });
122
+ });
123
+ }
124
+ },
125
+ );
126
+
127
+ return [
128
+ scrollPlugin,
129
+
130
+ // Listen for effect.s
131
+ EditorView.updateListener.of((update) => {
132
+ update.transactions.forEach((transaction) => {
133
+ try {
134
+ const plugin = update.view.plugin(scrollPlugin);
135
+ if (plugin) {
136
+ for (const effect of transaction.effects) {
137
+ if (effect.is(scrollerCrawlEffect)) {
138
+ plugin.crawl(effect.value);
139
+ } else if (effect.is(scrollerLineEffect)) {
140
+ plugin.scroll(effect.value);
141
+ }
142
+ }
143
+ }
144
+ } catch (err) {
145
+ log.catch(err);
146
+ }
147
+ });
148
+ }),
149
+
150
+ // Styles.
151
+ EditorView.theme({
152
+ '.cm-content': {
153
+ paddingBottom: `${overScroll}px`,
154
+ },
155
+ '.cm-scroller': {
156
+ overflowAnchor: 'none',
157
+ paddingBottom: '0',
158
+ },
159
+ '.cm-scroller.cm-hide-scrollbar::-webkit-scrollbar': {
160
+ display: 'none',
161
+ },
162
+ '.cm-scroller::-webkit-scrollbar-thumb': {
163
+ background: 'transparent',
164
+ transition: 'background 0.15s',
165
+ },
166
+ '&:hover .cm-scroller::-webkit-scrollbar-thumb': {
167
+ background: 'var(--color-scrollbar-thumb)',
168
+ },
169
+ '.cm-scroll-button': {
170
+ position: 'absolute',
171
+ bottom: '0.5rem',
172
+ right: '1rem',
173
+ },
174
+ }),
175
+ ];
176
+ };
177
+
178
+ /**
179
+ * Creates a smooth crawler that follows the live bottom of a CodeMirror 6 EditorView.
180
+ *
181
+ * Each animation frame the step is:
182
+ * step = clamp(|delta| * k, minStep, maxStep) -- but never more than |delta|
183
+ *
184
+ * Capping at |delta| is critical: it prevents overshoot, which would otherwise cause
185
+ * oscillation when the proportional step (or minStep) exceeds the remaining distance.
186
+ * The crawler settles exactly at the target with no bounce.
187
+ *
188
+ * @param k Fraction of remaining distance moved each frame (0 < k < 1).
189
+ * @param minStep Min step size in px; prevents stalling on large distances.
190
+ * @param maxStep Max step size in px.
191
+ * @param targetDelta Snap-to-target threshold in px.
192
+ */
193
+ export function createCrawler(view: EditorView, k = 0.3, maxStep = 2, targetDelta = 0.5) {
194
+ const el = view.scrollDOM;
195
+
196
+ let currentTop = 0; // Float-precision position; avoids browser integer-rounding of scrollTop.
197
+ let rafId: number | null = null;
198
+
199
+ function frame() {
200
+ // Recompute each frame so the animation chases a live-updating document's bottom.
201
+ const targetTop = el.scrollHeight - el.clientHeight;
202
+ const delta = targetTop - currentTop;
203
+ const absDelta = Math.abs(delta);
204
+ if (absDelta < targetDelta) {
205
+ el.scrollTop = targetTop;
206
+ currentTop = targetTop;
207
+ rafId = null;
208
+ return;
209
+ }
210
+
211
+ // Clamp step to [minStep, maxStep], then cap at absDelta to prevent overshoot.
212
+ const step = Math.sign(delta) * Math.min(absDelta, Math.max(1, Math.min(absDelta * k, maxStep)));
213
+ currentTop += step;
214
+ el.scrollTop = currentTop;
215
+ rafId = requestAnimationFrame(frame);
216
+ }
217
+
218
+ return {
219
+ scroll: () => {
220
+ if (rafId === null) {
221
+ currentTop = el.scrollTop;
222
+ rafId = requestAnimationFrame(frame);
223
+ }
224
+ },
225
+ cancel: () => {
226
+ if (rafId !== null) {
227
+ cancelAnimationFrame(rafId);
228
+ rafId = null;
229
+ }
230
+ },
231
+ };
232
+ }
@@ -114,7 +114,7 @@ class CursorWidget extends WidgetType {
114
114
  */
115
115
  const fadeIn = (options: { removalDelay?: number } = {}): Extension => {
116
116
  const FADE_IN_DURATION = 1_000; // ms.
117
- const DEFAULT_REMOVAL_DELAY = 5_000; // ms.
117
+ const DEFAULT_REMOVAL_DELAY = 3_000; // ms.
118
118
  const removalDelay = options.removalDelay ?? DEFAULT_REMOVAL_DELAY;
119
119
 
120
120
  // Effect to remove a specific decoration by range.
@@ -21,7 +21,7 @@ import { log } from '@dxos/log';
21
21
 
22
22
  import { type Range } from '../../types';
23
23
  import { decorationSetToArray } from '../../util';
24
- import { scrollToLineEffect } from '../scrolling';
24
+ import { scrollerLineEffect } from '../scroller';
25
25
 
26
26
  import { nodeToJson } from './xml-util';
27
27
 
@@ -268,7 +268,7 @@ const createNavigationEffectPlugin = (
268
268
  const line = view.state.doc.lineAt(widget?.from ?? 0);
269
269
  view.dispatch({
270
270
  selection: { anchor: line.from, head: line.from },
271
- effects: scrollToLineEffect.of({ line: line.number, options: { offset: -16 } }),
271
+ effects: scrollerLineEffect.of({ line: line.number - 1, offset: -16 }),
272
272
  });
273
273
 
274
274
  continue;
@@ -294,13 +294,13 @@ const createNavigationEffectPlugin = (
294
294
  const line = view.state.doc.lineAt(widget?.from);
295
295
  view.dispatch({
296
296
  selection: { anchor: line.to, head: line.to },
297
- effects: scrollToLineEffect.of({ line: line.number, options: { offset: -16 } }),
297
+ effects: scrollerLineEffect.of({ line: line.number - 1, offset: -16 }),
298
298
  });
299
299
  } else {
300
300
  const line = view.state.doc.lineAt(view.state.doc.length);
301
301
  view.dispatch({
302
302
  selection: { anchor: line.to, head: line.to },
303
- effects: scrollToLineEffect.of({ line: line.number, options: { position: 'end' } }),
303
+ effects: scrollerLineEffect.of({ line: line.number - 1, position: 'end' }),
304
304
  });
305
305
  }
306
306
 
@@ -359,6 +359,9 @@ const createWidgetDecorationsField = (registry: XmlWidgetRegistry = {}, notifier
359
359
  // Check for reset effect.
360
360
  for (const effect of tr.effects) {
361
361
  if (effect.is(xmlTagResetEffect)) {
362
+ if (tr.docChanged) {
363
+ return buildDecorations(tr.state, { from: 0, to: tr.state.doc.length }, registry, notifier);
364
+ }
362
365
  return { from: 0, decorations: Decoration.none };
363
366
  }
364
367
  }
@@ -2,6 +2,4 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './markdown';
6
5
  export * from './theme';
7
- export * from './tokens';
@@ -5,7 +5,60 @@
5
5
  import { type Extension } from '@codemirror/state';
6
6
  import { EditorView } from '@codemirror/view';
7
7
 
8
- import { fontBody, fontMono } from './tokens';
8
+ import { mx } from '@dxos/ui-theme';
9
+
10
+ export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
11
+
12
+ // https://tailwindcss.com/docs/font-weight
13
+ const headings: Record<HeadingLevel, { className: string; fontSize: string; lineHeight: string }> = {
14
+ 1: {
15
+ className: 'text-4xl',
16
+ fontSize: 'var(--text-4xl)',
17
+ lineHeight: 'var(--text-4xl--line-height)',
18
+ },
19
+ 2: {
20
+ className: 'text-3xl',
21
+ fontSize: 'var(--text-3xl)',
22
+ lineHeight: 'var(--text-3xl--line-height)',
23
+ },
24
+ 3: {
25
+ className: 'text-2xl',
26
+ fontSize: 'var(--text-2xl)',
27
+ lineHeight: 'var(--text-2xl--line-height)',
28
+ },
29
+ 4: {
30
+ className: 'text-xl',
31
+ fontSize: 'var(--text-xl)',
32
+ lineHeight: 'var(--text-xl--line-height)',
33
+ },
34
+ 5: {
35
+ className: 'text-lg',
36
+ fontSize: 'var(--text-lg)',
37
+ lineHeight: 'var(--text-lg--line-height)',
38
+ },
39
+ 6: {
40
+ className: 'text-base',
41
+ fontSize: 'var(--text-base)',
42
+ lineHeight: 'var(--text-base--line-height)',
43
+ },
44
+ };
45
+
46
+ export const markdownTheme = {
47
+ code: 'font-mono no-underline! text-cm-code',
48
+ codeMark: 'font-mono text-cm-code-mark',
49
+ mark: 'opacity-50',
50
+ heading: (level: HeadingLevel) => ({
51
+ className: mx(headings[level].className, 'font-light text-cm-heading'),
52
+ color: 'var(--color-cm-heading) !important',
53
+ lineHeight: headings[level].lineHeight,
54
+ fontSize: headings[level].fontSize,
55
+ fontWeight: '100 !important',
56
+ }),
57
+ };
58
+
59
+ // Font families matching --font-body and --font-mono in theme.css.
60
+ export const fontBody = 'Inter Variable, ui-sans-serif, system-ui, sans-serif';
61
+ export const fontMono = 'JetBrains Mono Variable, ui-monospace, Cascadia Code, Source Code Pro, monospace';
9
62
 
10
63
  /**
11
64
  * Global base theme.
@@ -43,6 +96,9 @@ import { fontBody, fontMono } from './tokens';
43
96
  * </div>
44
97
  */
45
98
  export const baseTheme = EditorView.baseTheme({
99
+ /**
100
+ * Outer frame.
101
+ */
46
102
  '&': {},
47
103
  '&.cm-focused': {
48
104
  outline: 'none',
@@ -52,7 +108,18 @@ export const baseTheme = EditorView.baseTheme({
52
108
  * Scroller
53
109
  */
54
110
  '.cm-scroller': {
55
- overflowY: 'auto',
111
+ overflowAnchor: 'none',
112
+ },
113
+ '.cm-scroller::-webkit-scrollbar': {
114
+ width: '8px',
115
+ },
116
+ '.cm-scroller::-webkit-scrollbar-track': {},
117
+ '.cm-scroller::-webkit-scrollbar-thumb': {
118
+ background: 'transparent',
119
+ transition: 'background 0.15s',
120
+ },
121
+ '&:hover .cm-scroller::-webkit-scrollbar-thumb': {
122
+ background: 'var(--color-scrollbar-thumb)',
56
123
  },
57
124
 
58
125
  /**
@@ -76,8 +143,8 @@ export const baseTheme = EditorView.baseTheme({
76
143
  '.cm-gutter': {},
77
144
  '.cm-gutter.cm-lineNumbers': {
78
145
  paddingRight: '4px',
79
- borderRight: '1px solid var(--dx-subduedSeparator)',
80
- color: 'var(--dx-subduedText)',
146
+ borderRight: '1px solid var(--color-subdued-separator)',
147
+ color: 'var(--color-subdued)',
81
148
  },
82
149
  '.cm-gutter.cm-lineNumbers .cm-gutterElement': {
83
150
  minWidth: '40px',
@@ -98,27 +165,27 @@ export const baseTheme = EditorView.baseTheme({
98
165
  paddingInline: 0,
99
166
  },
100
167
  '.cm-activeLine': {
101
- background: 'var(--dx-cmActiveLine)',
168
+ background: 'var(--color-cm-active-line)',
102
169
  },
103
170
 
104
171
  /**
105
172
  * Cursor (layer).
106
173
  */
107
174
  '.cm-cursor, .cm-dropCursor': {
108
- borderLeft: '2px solid var(--dx-cmCursor)',
175
+ borderLeft: '2px solid var(--color-cm-cursor)',
109
176
  },
110
177
  '.cm-placeholder': {
111
- color: 'var(--dx-placeholder)',
178
+ color: 'var(--color-placeholder)',
112
179
  },
113
180
 
114
181
  /**
115
182
  * Selection (layer).
116
183
  */
117
184
  '.cm-selectionBackground': {
118
- background: 'var(--dx-cmSelection)',
185
+ background: 'var(--color-cm-selection)',
119
186
  },
120
187
  '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
121
- background: 'var(--dx-cmFocusedSelection)',
188
+ background: 'var(--color-cm-focused-selection)',
122
189
  },
123
190
 
124
191
  /**
@@ -129,8 +196,8 @@ export const baseTheme = EditorView.baseTheme({
129
196
  margin: '0 -3px',
130
197
  padding: '3px',
131
198
  borderRadius: '3px',
132
- background: 'var(--dx-cmHighlightSurface)',
133
- color: 'var(--dx-cmHighlight)',
199
+ background: 'var(--color-cm-highlight-surface)',
200
+ color: 'var(--color-cm-highlight)',
134
201
  },
135
202
  '.cm-searchMatch-selected': {
136
203
  textDecoration: 'underline',
@@ -142,21 +209,30 @@ export const baseTheme = EditorView.baseTheme({
142
209
  '.cm-link': {
143
210
  textDecorationLine: 'underline',
144
211
  textDecorationThickness: '1px',
145
- textDecorationColor: 'var(--dx-separator)',
212
+ textDecorationColor: 'var(--color-separator)',
146
213
  textUnderlineOffset: '2px',
147
214
  borderRadius: '.125rem',
148
215
  },
149
216
  '.cm-link > span': {
150
- color: 'var(--dx-accentText)',
217
+ color: 'var(--color-accent-text)',
218
+ },
219
+ '.cm-link > span:hover': {
220
+ color: 'var(--color-accent-text-hover)',
151
221
  },
152
222
 
153
223
  /**
154
224
  * Tooltip.
155
225
  */
156
226
  '.cm-tooltip': {
157
- background: 'var(--dx-baseSurface)',
227
+ background: 'var(--color-modal-surface)',
158
228
  },
159
229
  '.cm-tooltip-below': {},
230
+ '.cm-tooltip-hover': {
231
+ background: 'var(--color-modal-surface)',
232
+ border: '1px solid var(--color-separator)',
233
+ borderRadius: '4px',
234
+ overflow: 'hidden',
235
+ },
160
236
 
161
237
  /**
162
238
  * Autocomplete.
@@ -165,7 +241,7 @@ export const baseTheme = EditorView.baseTheme({
165
241
  '.cm-tooltip.cm-tooltip-autocomplete': {
166
242
  marginTop: '6px',
167
243
  marginLeft: '-10px',
168
- border: '2px solid var(--dx-separator)',
244
+ border: '2px solid var(--color-separator)',
169
245
  borderRadius: '4px',
170
246
  },
171
247
  '.cm-tooltip.cm-tooltip-autocomplete > ul': {
@@ -175,12 +251,12 @@ export const baseTheme = EditorView.baseTheme({
175
251
  padding: '4px',
176
252
  },
177
253
  '.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]': {
178
- background: 'var(--dx-activeSurface)',
179
- color: 'var(--dx-activeSurfaceText)',
254
+ background: 'var(--color-active-surface)',
255
+ color: 'var(--color-base-surface-text)',
180
256
  },
181
257
  '.cm-tooltip.cm-tooltip-autocomplete > ul > completion-section': {
182
258
  paddingLeft: '4px !important',
183
- color: 'var(--dx-hoverSurfaceText)',
259
+ color: 'var(--color-base-surface-text)',
184
260
  },
185
261
 
186
262
  /**
@@ -190,17 +266,17 @@ export const baseTheme = EditorView.baseTheme({
190
266
  width: '360px !important',
191
267
  margin: '-10px 1px 0 1px',
192
268
  padding: '8px !important',
193
- borderColor: 'var(--dx-separator)',
269
+ borderColor: 'var(--color-separator)',
194
270
  },
195
271
  '.cm-completionIcon': {
196
272
  display: 'none',
197
273
  },
198
274
  '.cm-completionLabel': {
199
- color: 'var(--dx-description)',
275
+ color: 'var(--color-description)',
200
276
  padding: '0 4px',
201
277
  },
202
278
  '.cm-completionMatchedText': {
203
- color: 'var(--dx-baseText)',
279
+ color: 'var(--color-base-surface-text)',
204
280
  textDecoration: 'none !important',
205
281
  },
206
282
 
@@ -225,7 +301,7 @@ export const baseTheme = EditorView.baseTheme({
225
301
  backgroundColor: 'var(--surface-bg)',
226
302
  },
227
303
  '.cm-panel input, .cm-panel button, .cm-panel label': {
228
- color: 'var(--dx-subdued)',
304
+ color: 'var(--color-subdued)',
229
305
  fontSize: '14px',
230
306
  all: 'unset',
231
307
  margin: '3px !important',
@@ -233,10 +309,10 @@ export const baseTheme = EditorView.baseTheme({
233
309
  outline: '1px solid transparent',
234
310
  },
235
311
  '.cm-panel input, .cm-panel button': {
236
- backgroundColor: 'var(--dx-inputSurface)',
312
+ backgroundColor: 'var(--color-input-surface)',
237
313
  },
238
314
  '.cm-panel input:focus, .cm-panel button:focus': {
239
- outline: '1px solid var(--dx-neutralFocusIndicator)',
315
+ outline: '1px solid var(--color-neutral-focus-indicator)',
240
316
  },
241
317
  '.cm-panel label': {
242
318
  display: 'inline-flex',
@@ -249,26 +325,27 @@ export const baseTheme = EditorView.baseTheme({
249
325
  height: '8px',
250
326
  marginRight: '6px !important',
251
327
  padding: '2px !important',
252
- color: 'var(--dx-neutralFocusIndicator)',
328
+ color: 'var(--color-neutral-focus-indicator)',
253
329
  },
254
330
  '.cm-panel button': {
255
331
  '&:hover': {
256
- backgroundColor: 'var(--dx-accentSurfaceHover) !important',
332
+ // TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
333
+ backgroundColor: 'var(--color-accent-surface-hover) !important',
257
334
  },
258
335
  '&:active': {
259
- backgroundColor: 'var(--dx-accentSurfaceHover)',
336
+ backgroundColor: 'var(--color-accent-surface-hover)',
260
337
  },
261
338
  },
262
339
  '.cm-panel.cm-search': {
263
340
  padding: '4px',
264
- borderTop: '1px solid var(--dx-separator)',
341
+ borderTop: '1px solid var(--color-separator)',
265
342
  },
266
343
  });
267
344
 
268
345
  export const editorGutter: Extension = EditorView.theme({
269
346
  '.cm-gutters': {
270
347
  // NOTE: Non-transparent background required to cover content if scrolling horizontally.
271
- background: 'var(--dx-baseSurface) !important',
348
+ background: 'var(--color-base-surface) !important',
272
349
  paddingRight: '1rem',
273
350
  },
274
351
  });
@@ -26,7 +26,7 @@ export const overlap = (a: Range, b: Range): boolean => a.from <= b.to && a.to >
26
26
  * while positive - with the next one.
27
27
  */
28
28
  export interface CursorConverter {
29
- toCursor(position: number, assoc?: -1 | 1 | undefined): string;
29
+ toCursor(position: number, assoc?: -1 | 1): string;
30
30
  fromCursor(cursor: string): number;
31
31
  }
32
32
 
@@ -1,20 +0,0 @@
1
- import { EditorView } from '@codemirror/view';
2
- export declare const scrollToBottomEffect: import("@codemirror/state").StateEffectType<ScrollBehavior | undefined>;
3
- export type AutoScrollOptions = {
4
- /** Auto-scroll when reaches the bottom. */
5
- autoScroll?: boolean;
6
- /** Threshold in px to trigger scroll from bottom. */
7
- threshold?: number;
8
- /** Throttle time in ms. */
9
- throttleDelay?: number;
10
- /** Callback when auto-scrolling. */
11
- onAutoScroll?: (props: {
12
- view: EditorView;
13
- distanceFromBottom: number;
14
- }) => boolean | void;
15
- };
16
- /**
17
- * Extension that supports pinning the scroll position and automatically scrolls to the bottom when content is added.
18
- */
19
- export declare const autoScroll: ({ autoScroll, threshold, throttleDelay, onAutoScroll, }?: Partial<AutoScrollOptions>) => import("@codemirror/state").Extension[];
20
- //# sourceMappingURL=autoscroll.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"autoscroll.d.ts","sourceRoot":"","sources":["../../../../src/extensions/autoscroll.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAc,MAAM,kBAAkB,CAAC;AAQ1D,eAAO,MAAM,oBAAoB,yEAAmD,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CAC5F,CAAC;AAEF;;GAEG;AAEH,eAAO,MAAM,UAAU,GAAI,0DAKxB,OAAO,CAAC,iBAAiB,CAAM,4CAiIjC,CAAC"}