@dxos/react-ui-editor 0.6.6-main.e1a6e1f → 0.6.6-staging.41c080b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +203 -307
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +5 -2
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts +6 -6
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +1 -2
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/cursor.d.ts +1 -1
- package/dist/types/src/extensions/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +1 -3
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/hooks/{useTextEditor.stories.d.ts → InputMode.stories.d.ts} +5 -9
- package/dist/types/src/hooks/InputMode.stories.d.ts.map +1 -0
- package/dist/types/src/{components/TextEditor → hooks}/TextEditor.stories.d.ts +4 -16
- package/dist/types/src/hooks/TextEditor.stories.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts +20 -3
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +25 -25
- package/src/components/Toolbar/Toolbar.stories.tsx +1 -1
- package/src/components/index.ts +0 -1
- package/src/extensions/automerge/automerge.stories.tsx +25 -18
- package/src/extensions/automerge/automerge.ts +2 -0
- package/src/extensions/automerge/cursor.ts +3 -4
- package/src/extensions/awareness/awareness-provider.ts +2 -0
- package/src/extensions/awareness/awareness.ts +34 -30
- package/src/extensions/comments.ts +6 -14
- package/src/extensions/cursor.ts +1 -1
- package/src/extensions/factories.ts +19 -13
- package/src/hooks/{useTextEditor.stories.tsx → InputMode.stories.tsx} +30 -35
- package/src/{components/TextEditor → hooks}/TextEditor.stories.tsx +22 -28
- package/src/hooks/useTextEditor.ts +75 -23
- package/src/themes/default.ts +20 -4
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +0 -34
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/index.d.ts +0 -2
- package/dist/types/src/components/TextEditor/index.d.ts.map +0 -1
- package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +0 -1
- package/src/components/TextEditor/TextEditor.tsx +0 -184
- package/src/components/TextEditor/index.ts +0 -5
|
@@ -35,14 +35,13 @@ import { keymap as keymap11 } from "@codemirror/view";
|
|
|
35
35
|
import { tags as tags2 } from "@lezer/highlight";
|
|
36
36
|
import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
37
37
|
|
|
38
|
-
// packages/ui/react-ui-editor/src/components/
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
38
|
+
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
39
|
+
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
|
|
40
|
+
import { createContext } from "@radix-ui/react-context";
|
|
41
|
+
import React, { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
42
|
+
import { useDropzone } from "react-dropzone";
|
|
43
|
+
import { Button, DensityProvider, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
44
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
46
45
|
|
|
47
46
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
48
47
|
import { StateField } from "@codemirror/state";
|
|
@@ -188,17 +187,16 @@ import { next as A3 } from "@dxos/automerge/automerge";
|
|
|
188
187
|
|
|
189
188
|
// packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
|
|
190
189
|
import { log } from "@dxos/log";
|
|
191
|
-
import {
|
|
190
|
+
import { fromCursor, toCursor } from "@dxos/react-client/echo";
|
|
192
191
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
|
|
193
192
|
var cursorConverter = (accessor) => ({
|
|
194
|
-
|
|
195
|
-
toCursor: (pos) => {
|
|
193
|
+
toCursor: (pos, assoc) => {
|
|
196
194
|
try {
|
|
197
|
-
return toCursor(accessor, pos);
|
|
195
|
+
return toCursor(accessor, pos, assoc);
|
|
198
196
|
} catch (err) {
|
|
199
197
|
log.catch(err, void 0, {
|
|
200
198
|
F: __dxlog_file,
|
|
201
|
-
L:
|
|
199
|
+
L: 15,
|
|
202
200
|
S: void 0,
|
|
203
201
|
C: (f, a) => f(...a)
|
|
204
202
|
});
|
|
@@ -211,7 +209,7 @@ var cursorConverter = (accessor) => ({
|
|
|
211
209
|
} catch (err) {
|
|
212
210
|
log.catch(err, void 0, {
|
|
213
211
|
F: __dxlog_file,
|
|
214
|
-
L:
|
|
212
|
+
L: 24,
|
|
215
213
|
S: void 0,
|
|
216
214
|
C: (f, a) => f(...a)
|
|
217
215
|
});
|
|
@@ -452,6 +450,7 @@ var automerge = (accessor) => {
|
|
|
452
450
|
const syncer = new Syncer(accessor.handle, syncState);
|
|
453
451
|
return [
|
|
454
452
|
Cursor.converter.of(cursorConverter(accessor)),
|
|
453
|
+
// Track heads.
|
|
455
454
|
syncState,
|
|
456
455
|
// Reconcile external updates.
|
|
457
456
|
ViewPlugin.fromClass(class {
|
|
@@ -506,13 +505,11 @@ var awareness = (provider = dummyProvider) => {
|
|
|
506
505
|
};
|
|
507
506
|
var RemoteSelectionsDecorator = class {
|
|
508
507
|
constructor(view) {
|
|
509
|
-
this.decorations = RangeSet.of([]);
|
|
510
508
|
this._ctx = new Context(void 0, {
|
|
511
509
|
F: __dxlog_file2,
|
|
512
|
-
L:
|
|
510
|
+
L: 82
|
|
513
511
|
});
|
|
514
|
-
this.
|
|
515
|
-
this._lastHead = void 0;
|
|
512
|
+
this.decorations = RangeSet.of([]);
|
|
516
513
|
this._cursorConverter = view.state.facet(Cursor.converter);
|
|
517
514
|
this._provider = view.state.facet(awarenessProvider);
|
|
518
515
|
this._provider.open();
|
|
@@ -529,12 +526,12 @@ var RemoteSelectionsDecorator = class {
|
|
|
529
526
|
this._provider.close();
|
|
530
527
|
}
|
|
531
528
|
update(update2) {
|
|
532
|
-
this._updateLocalSelection(update2);
|
|
533
|
-
this._updateRemoteSelections(update2);
|
|
529
|
+
this._updateLocalSelection(update2.view);
|
|
530
|
+
this._updateRemoteSelections(update2.view);
|
|
534
531
|
}
|
|
535
|
-
_updateLocalSelection(
|
|
536
|
-
const hasFocus =
|
|
537
|
-
const { anchor = void 0, head = void 0 } = hasFocus ?
|
|
532
|
+
_updateLocalSelection(view) {
|
|
533
|
+
const hasFocus = view.hasFocus && view.dom.ownerDocument.hasFocus();
|
|
534
|
+
const { anchor = void 0, head = void 0 } = hasFocus ? view.state.selection.main : {};
|
|
538
535
|
if (this._lastAnchor === anchor && this._lastHead === head) {
|
|
539
536
|
return;
|
|
540
537
|
}
|
|
@@ -542,10 +539,10 @@ var RemoteSelectionsDecorator = class {
|
|
|
542
539
|
this._lastHead = head;
|
|
543
540
|
this._provider.update(anchor !== void 0 && head !== void 0 ? {
|
|
544
541
|
anchor: this._cursorConverter.toCursor(anchor),
|
|
545
|
-
head: this._cursorConverter.toCursor(head)
|
|
542
|
+
head: this._cursorConverter.toCursor(head, -1)
|
|
546
543
|
} : void 0);
|
|
547
544
|
}
|
|
548
|
-
_updateRemoteSelections(
|
|
545
|
+
_updateRemoteSelections(view) {
|
|
549
546
|
const decorations = [];
|
|
550
547
|
const awarenessStates = this._provider.getRemoteStates();
|
|
551
548
|
for (const state2 of awarenessStates) {
|
|
@@ -554,12 +551,12 @@ var RemoteSelectionsDecorator = class {
|
|
|
554
551
|
if (anchor == null || head == null) {
|
|
555
552
|
continue;
|
|
556
553
|
}
|
|
557
|
-
const start = Math.min(Math.min(anchor, head),
|
|
558
|
-
const end = Math.min(Math.max(anchor, head),
|
|
559
|
-
const startLine =
|
|
560
|
-
const endLine =
|
|
561
|
-
const
|
|
562
|
-
const lightColor = state2.info.lightColor
|
|
554
|
+
const start = Math.min(Math.min(anchor, head), view.state.doc.length);
|
|
555
|
+
const end = Math.min(Math.max(anchor, head), view.state.doc.length);
|
|
556
|
+
const startLine = view.state.doc.lineAt(start);
|
|
557
|
+
const endLine = view.state.doc.lineAt(end);
|
|
558
|
+
const darkColor = state2.info.darkColor;
|
|
559
|
+
const lightColor = state2.info.lightColor;
|
|
563
560
|
if (startLine.number === endLine.number) {
|
|
564
561
|
decorations.push({
|
|
565
562
|
from: start,
|
|
@@ -593,7 +590,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
593
590
|
})
|
|
594
591
|
});
|
|
595
592
|
for (let i = startLine.number + 1; i < endLine.number; i++) {
|
|
596
|
-
const linePos =
|
|
593
|
+
const linePos = view.state.doc.line(i).from;
|
|
597
594
|
decorations.push({
|
|
598
595
|
from: linePos,
|
|
599
596
|
to: linePos,
|
|
@@ -612,7 +609,7 @@ var RemoteSelectionsDecorator = class {
|
|
|
612
609
|
value: Decoration2.widget({
|
|
613
610
|
side: head - anchor > 0 ? -1 : 1,
|
|
614
611
|
block: false,
|
|
615
|
-
widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous",
|
|
612
|
+
widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", darkColor)
|
|
616
613
|
})
|
|
617
614
|
});
|
|
618
615
|
}
|
|
@@ -698,12 +695,11 @@ var styles2 = EditorView3.baseTheme({
|
|
|
698
695
|
lineHeight: "normal",
|
|
699
696
|
userSelect: "none",
|
|
700
697
|
color: "white",
|
|
701
|
-
padding: "2px",
|
|
698
|
+
padding: "2px 6px",
|
|
702
699
|
zIndex: 101,
|
|
703
700
|
transition: "opacity .3s ease-in-out",
|
|
704
701
|
backgroundColor: "inherit",
|
|
705
702
|
borderRadius: "2px",
|
|
706
|
-
// These should be separate.
|
|
707
703
|
opacity: 0,
|
|
708
704
|
transitionDelay: "0s",
|
|
709
705
|
whiteSpace: "nowrap"
|
|
@@ -763,7 +759,7 @@ var SpaceAwarenessProvider = class {
|
|
|
763
759
|
err
|
|
764
760
|
}, {
|
|
765
761
|
F: __dxlog_file3,
|
|
766
|
-
L:
|
|
762
|
+
L: 91,
|
|
767
763
|
S: this,
|
|
768
764
|
C: (f, a) => f(...a)
|
|
769
765
|
});
|
|
@@ -780,7 +776,7 @@ var SpaceAwarenessProvider = class {
|
|
|
780
776
|
update(position) {
|
|
781
777
|
invariant(this._postTask, void 0, {
|
|
782
778
|
F: __dxlog_file3,
|
|
783
|
-
L:
|
|
779
|
+
L: 106,
|
|
784
780
|
S: this,
|
|
785
781
|
A: [
|
|
786
782
|
"this._postTask",
|
|
@@ -797,7 +793,7 @@ var SpaceAwarenessProvider = class {
|
|
|
797
793
|
_handleQueryMessage() {
|
|
798
794
|
invariant(this._postTask, void 0, {
|
|
799
795
|
F: __dxlog_file3,
|
|
800
|
-
L:
|
|
796
|
+
L: 117,
|
|
801
797
|
S: this,
|
|
802
798
|
A: [
|
|
803
799
|
"this._postTask",
|
|
@@ -809,7 +805,7 @@ var SpaceAwarenessProvider = class {
|
|
|
809
805
|
_handlePostMessage(message) {
|
|
810
806
|
invariant(message.kind === "post", void 0, {
|
|
811
807
|
F: __dxlog_file3,
|
|
812
|
-
L:
|
|
808
|
+
L: 122,
|
|
813
809
|
S: this,
|
|
814
810
|
A: [
|
|
815
811
|
"message.kind === 'post'",
|
|
@@ -1545,7 +1541,7 @@ var commentsDecorations = EditorView7.decorations.compute([
|
|
|
1545
1541
|
if (!range) {
|
|
1546
1542
|
log4.warn("Invalid range:", range, {
|
|
1547
1543
|
F: __dxlog_file6,
|
|
1548
|
-
L:
|
|
1544
|
+
L: 181,
|
|
1549
1545
|
S: void 0,
|
|
1550
1546
|
C: (f, a) => f(...a)
|
|
1551
1547
|
});
|
|
@@ -1883,16 +1879,12 @@ var hasActiveSelection = (state2) => {
|
|
|
1883
1879
|
return state2.selection.ranges.some((range) => !range.empty);
|
|
1884
1880
|
};
|
|
1885
1881
|
var ExternalCommentSync = class {
|
|
1886
|
-
constructor(view, id, subscribe,
|
|
1882
|
+
constructor(view, id, subscribe, getComments) {
|
|
1887
1883
|
this.destroy = () => {
|
|
1888
1884
|
this.unsubscribe();
|
|
1889
1885
|
};
|
|
1890
1886
|
const updateComments = () => {
|
|
1891
|
-
const
|
|
1892
|
-
const comments2 = threads.filter(nonNullable).filter((thread) => thread.anchor).map((thread) => ({
|
|
1893
|
-
id: thread.id,
|
|
1894
|
-
cursor: thread.anchor
|
|
1895
|
-
}));
|
|
1887
|
+
const comments2 = getComments();
|
|
1896
1888
|
if (id === view.state.facet(documentId)) {
|
|
1897
1889
|
queueMicrotask(() => view.dispatch({
|
|
1898
1890
|
effects: setComments.of({
|
|
@@ -1905,9 +1897,9 @@ var ExternalCommentSync = class {
|
|
|
1905
1897
|
this.unsubscribe = subscribe(updateComments);
|
|
1906
1898
|
}
|
|
1907
1899
|
};
|
|
1908
|
-
var createExternalCommentSync = (id, subscribe,
|
|
1900
|
+
var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
|
|
1909
1901
|
constructor(view) {
|
|
1910
|
-
return new ExternalCommentSync(view, id, subscribe,
|
|
1902
|
+
return new ExternalCommentSync(view, id, subscribe, getComments);
|
|
1911
1903
|
}
|
|
1912
1904
|
});
|
|
1913
1905
|
var useCommentState = () => {
|
|
@@ -1943,7 +1935,7 @@ var useComments = (view, id, comments2) => {
|
|
|
1943
1935
|
});
|
|
1944
1936
|
};
|
|
1945
1937
|
var useCommentClickListener = (onCommentClick) => {
|
|
1946
|
-
|
|
1938
|
+
return useMemo(() => EditorView7.updateListener.of((update2) => {
|
|
1947
1939
|
update2.transactions.forEach((transaction) => {
|
|
1948
1940
|
transaction.effects.forEach((effect) => {
|
|
1949
1941
|
if (effect.is(commentClickedEffect)) {
|
|
@@ -1954,15 +1946,14 @@ var useCommentClickListener = (onCommentClick) => {
|
|
|
1954
1946
|
}), [
|
|
1955
1947
|
onCommentClick
|
|
1956
1948
|
]);
|
|
1957
|
-
return observer;
|
|
1958
1949
|
};
|
|
1959
1950
|
|
|
1960
1951
|
// packages/ui/react-ui-editor/src/extensions/debug.ts
|
|
1961
1952
|
import { syntaxTree } from "@codemirror/language";
|
|
1962
1953
|
import { StateField as StateField5 } from "@codemirror/state";
|
|
1963
|
-
var debugNodeLogger = (
|
|
1954
|
+
var debugNodeLogger = (log8 = console.log) => {
|
|
1964
1955
|
const logTokens = (state2) => syntaxTree(state2).iterate({
|
|
1965
|
-
enter: (node) =>
|
|
1956
|
+
enter: (node) => log8(node.type)
|
|
1966
1957
|
});
|
|
1967
1958
|
return StateField5.define({
|
|
1968
1959
|
create: (state2) => logTokens(state2),
|
|
@@ -2159,19 +2150,34 @@ var defaultTheme = {
|
|
|
2159
2150
|
// tooltip
|
|
2160
2151
|
//
|
|
2161
2152
|
".cm-tooltip": {
|
|
2162
|
-
border: "none"
|
|
2163
|
-
|
|
2153
|
+
border: "none"
|
|
2154
|
+
},
|
|
2155
|
+
"&light .cm-tooltip": {
|
|
2156
|
+
background: `${get2(tokens, "extend.colors.neutral.100")} !important`
|
|
2157
|
+
},
|
|
2158
|
+
"&dark .cm-tooltip": {
|
|
2159
|
+
background: `${get2(tokens, "extend.colors.neutral.900")} !important`
|
|
2164
2160
|
},
|
|
2165
2161
|
".cm-tooltip-below": {},
|
|
2166
2162
|
//
|
|
2167
2163
|
// autocomplete
|
|
2164
|
+
// https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
|
|
2168
2165
|
//
|
|
2169
2166
|
".cm-tooltip-autocomplete": {
|
|
2170
2167
|
marginTop: "4px",
|
|
2171
2168
|
marginLeft: "-3px"
|
|
2172
2169
|
},
|
|
2173
|
-
".cm-tooltip-autocomplete ul
|
|
2174
|
-
|
|
2170
|
+
".cm-tooltip-autocomplete > ul": {
|
|
2171
|
+
maxHeight: "20em !important"
|
|
2172
|
+
},
|
|
2173
|
+
".cm-tooltip-autocomplete > ul > li": {},
|
|
2174
|
+
".cm-tooltip-autocomplete > ul > li[aria-selected]": {},
|
|
2175
|
+
// TODO(burdon): Can we add a class prefix to avoid adding !important?
|
|
2176
|
+
".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
|
|
2177
|
+
paddingLeft: "4px !important",
|
|
2178
|
+
borderBottom: "none !important",
|
|
2179
|
+
color: get2(tokens, "extend.colors.primary.500")
|
|
2180
|
+
},
|
|
2175
2181
|
".cm-completionIcon": {
|
|
2176
2182
|
display: "none"
|
|
2177
2183
|
},
|
|
@@ -2179,7 +2185,8 @@ var defaultTheme = {
|
|
|
2179
2185
|
fontFamily: get2(tokens, "fontFamily.body", []).join(",")
|
|
2180
2186
|
},
|
|
2181
2187
|
".cm-completionMatchedText": {
|
|
2182
|
-
textDecoration: "none"
|
|
2188
|
+
textDecoration: "none !important",
|
|
2189
|
+
opacity: 0.5
|
|
2183
2190
|
},
|
|
2184
2191
|
//
|
|
2185
2192
|
// table
|
|
@@ -2365,23 +2372,23 @@ var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
|
2365
2372
|
].filter(isNotFalsy2);
|
|
2366
2373
|
};
|
|
2367
2374
|
var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2368
|
-
const extensions =
|
|
2369
|
-
|
|
2370
|
-
|
|
2375
|
+
const extensions = [];
|
|
2376
|
+
if (text) {
|
|
2377
|
+
extensions.push(automerge(text));
|
|
2378
|
+
}
|
|
2371
2379
|
if (space && identity) {
|
|
2372
2380
|
const peerId = identity?.identityKey.toHex();
|
|
2373
2381
|
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
2374
|
-
|
|
2382
|
+
extensions.push(awareness(new SpaceAwarenessProvider({
|
|
2375
2383
|
space,
|
|
2376
2384
|
channel: `awareness.${id}`,
|
|
2377
2385
|
peerId: identity.identityKey.toHex(),
|
|
2378
2386
|
info: {
|
|
2379
2387
|
displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
|
|
2380
|
-
|
|
2388
|
+
darkColor: cursorDarkValue,
|
|
2381
2389
|
lightColor: cursorLightValue
|
|
2382
2390
|
}
|
|
2383
|
-
});
|
|
2384
|
-
extensions.push(awareness(awarenessProvider2));
|
|
2391
|
+
})));
|
|
2385
2392
|
}
|
|
2386
2393
|
return extensions;
|
|
2387
2394
|
};
|
|
@@ -4645,168 +4652,27 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4645
4652
|
];
|
|
4646
4653
|
};
|
|
4647
4654
|
|
|
4648
|
-
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4649
|
-
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4650
|
-
var instanceCount = 0;
|
|
4651
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({
|
|
4652
|
-
id,
|
|
4653
|
-
// TODO(wittjosiah): Rename initialText?
|
|
4654
|
-
doc,
|
|
4655
|
-
selection,
|
|
4656
|
-
extensions,
|
|
4657
|
-
className,
|
|
4658
|
-
autoFocus,
|
|
4659
|
-
scrollTo: propsScrollTo,
|
|
4660
|
-
moveToEndOfLine,
|
|
4661
|
-
debug,
|
|
4662
|
-
dataTestId
|
|
4663
|
-
}, forwardedRef) => {
|
|
4664
|
-
const [instanceId] = useState3(() => `text-editor-${++instanceCount}`);
|
|
4665
|
-
const scrollTo = useDefaultValue(propsScrollTo, EditorView16.scrollIntoView(0, {
|
|
4666
|
-
yMargin: 0
|
|
4667
|
-
}));
|
|
4668
|
-
const tabsterDOMAttribute = useFocusableGroup({
|
|
4669
|
-
tabBehavior: "limited"
|
|
4670
|
-
});
|
|
4671
|
-
const rootRef = useRef(null);
|
|
4672
|
-
const [view, setView] = useState3(null);
|
|
4673
|
-
useImperativeHandle(forwardedRef, () => view, [
|
|
4674
|
-
view
|
|
4675
|
-
]);
|
|
4676
|
-
useEffect2(() => {
|
|
4677
|
-
if (autoFocus) {
|
|
4678
|
-
view?.focus();
|
|
4679
|
-
}
|
|
4680
|
-
}, [
|
|
4681
|
-
view,
|
|
4682
|
-
autoFocus
|
|
4683
|
-
]);
|
|
4684
|
-
useEffect2(() => {
|
|
4685
|
-
log7("create", {
|
|
4686
|
-
id,
|
|
4687
|
-
instanceId
|
|
4688
|
-
}, {
|
|
4689
|
-
F: __dxlog_file11,
|
|
4690
|
-
L: 91,
|
|
4691
|
-
S: void 0,
|
|
4692
|
-
C: (f, a) => f(...a)
|
|
4693
|
-
});
|
|
4694
|
-
const state2 = EditorState2.create({
|
|
4695
|
-
doc,
|
|
4696
|
-
extensions: [
|
|
4697
|
-
id && documentId2.of(id),
|
|
4698
|
-
// TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
|
|
4699
|
-
EditorView16.exceptionSink.of((err) => {
|
|
4700
|
-
log7.catch(err, void 0, {
|
|
4701
|
-
F: __dxlog_file11,
|
|
4702
|
-
L: 104,
|
|
4703
|
-
S: void 0,
|
|
4704
|
-
C: (f, a) => f(...a)
|
|
4705
|
-
});
|
|
4706
|
-
}),
|
|
4707
|
-
// Focus.
|
|
4708
|
-
EditorView16.updateListener.of((update2) => {
|
|
4709
|
-
update2.transactions.forEach((transaction) => {
|
|
4710
|
-
if (transaction.isUserEvent(focusEvent)) {
|
|
4711
|
-
rootRef.current?.focus();
|
|
4712
|
-
}
|
|
4713
|
-
});
|
|
4714
|
-
}),
|
|
4715
|
-
extensions
|
|
4716
|
-
].filter(isNotFalsy4)
|
|
4717
|
-
});
|
|
4718
|
-
const view2 = new EditorView16({
|
|
4719
|
-
state: state2,
|
|
4720
|
-
parent: rootRef.current,
|
|
4721
|
-
scrollTo,
|
|
4722
|
-
// NOTE: Uncomment to debug/monitor all transactions.
|
|
4723
|
-
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
4724
|
-
dispatchTransactions: (trs, view3) => {
|
|
4725
|
-
if (debug) {
|
|
4726
|
-
logChanges(trs);
|
|
4727
|
-
}
|
|
4728
|
-
view3.update(trs);
|
|
4729
|
-
}
|
|
4730
|
-
});
|
|
4731
|
-
if (moveToEndOfLine && !(scrollTo || selection)) {
|
|
4732
|
-
const { to } = view2.state.doc.lineAt(0);
|
|
4733
|
-
view2.dispatch({
|
|
4734
|
-
selection: {
|
|
4735
|
-
anchor: to
|
|
4736
|
-
}
|
|
4737
|
-
});
|
|
4738
|
-
}
|
|
4739
|
-
if (state2.facet(editorInputMode).noTabster) {
|
|
4740
|
-
rootRef.current?.removeAttribute("data-tabster");
|
|
4741
|
-
}
|
|
4742
|
-
setView(view2);
|
|
4743
|
-
return () => {
|
|
4744
|
-
log7("destroy", {
|
|
4745
|
-
id,
|
|
4746
|
-
instanceId
|
|
4747
|
-
}, {
|
|
4748
|
-
F: __dxlog_file11,
|
|
4749
|
-
L: 153,
|
|
4750
|
-
S: void 0,
|
|
4751
|
-
C: (f, a) => f(...a)
|
|
4752
|
-
});
|
|
4753
|
-
view2?.destroy();
|
|
4754
|
-
};
|
|
4755
|
-
}, [
|
|
4756
|
-
id,
|
|
4757
|
-
selection,
|
|
4758
|
-
scrollTo,
|
|
4759
|
-
extensions
|
|
4760
|
-
]);
|
|
4761
|
-
const handleKeyUp = useCallback((event) => {
|
|
4762
|
-
const { key } = event;
|
|
4763
|
-
switch (key) {
|
|
4764
|
-
case "Enter": {
|
|
4765
|
-
view?.focus();
|
|
4766
|
-
break;
|
|
4767
|
-
}
|
|
4768
|
-
}
|
|
4769
|
-
}, [
|
|
4770
|
-
view
|
|
4771
|
-
]);
|
|
4772
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
4773
|
-
role: "none",
|
|
4774
|
-
ref: rootRef,
|
|
4775
|
-
tabIndex: 0,
|
|
4776
|
-
className,
|
|
4777
|
-
"data-testid": dataTestId,
|
|
4778
|
-
...tabsterDOMAttribute,
|
|
4779
|
-
onKeyUp: handleKeyUp
|
|
4780
|
-
});
|
|
4781
|
-
});
|
|
4782
|
-
|
|
4783
4655
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4784
|
-
import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
|
|
4785
|
-
import { createContext } from "@radix-ui/react-context";
|
|
4786
|
-
import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
4787
|
-
import { useDropzone } from "react-dropzone";
|
|
4788
|
-
import { Button, DensityProvider, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4789
|
-
import { getSize } from "@dxos/react-ui-theme";
|
|
4790
4656
|
var iconStyles = getSize(5);
|
|
4791
4657
|
var buttonStyles = "min-bs-0 p-2";
|
|
4792
4658
|
var tooltipProps = {
|
|
4793
4659
|
side: "top",
|
|
4794
4660
|
classNames: "z-10"
|
|
4795
4661
|
};
|
|
4796
|
-
var ToolbarSeparator = () => /* @__PURE__ */
|
|
4662
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React.createElement("div", {
|
|
4797
4663
|
role: "separator",
|
|
4798
4664
|
className: "grow"
|
|
4799
4665
|
});
|
|
4800
4666
|
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
4801
4667
|
var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
4802
|
-
return /* @__PURE__ */
|
|
4668
|
+
return /* @__PURE__ */ React.createElement(ToolbarContextProvider, {
|
|
4803
4669
|
onAction,
|
|
4804
4670
|
state: state2
|
|
4805
|
-
}, /* @__PURE__ */
|
|
4671
|
+
}, /* @__PURE__ */ React.createElement(DensityProvider, {
|
|
4806
4672
|
density: "fine"
|
|
4807
|
-
}, /* @__PURE__ */
|
|
4673
|
+
}, /* @__PURE__ */ React.createElement(ElevationProvider, {
|
|
4808
4674
|
elevation: "chrome"
|
|
4809
|
-
}, /* @__PURE__ */
|
|
4675
|
+
}, /* @__PURE__ */ React.createElement(NaturalToolbar.Root, {
|
|
4810
4676
|
classNames: [
|
|
4811
4677
|
"p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
|
|
4812
4678
|
classNames
|
|
@@ -4817,30 +4683,30 @@ var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
|
|
|
4817
4683
|
}, children))));
|
|
4818
4684
|
};
|
|
4819
4685
|
var ToolbarToggleButton = ({ Icon, children, ...props }) => {
|
|
4820
|
-
return /* @__PURE__ */
|
|
4686
|
+
return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
4821
4687
|
asChild: true
|
|
4822
|
-
}, /* @__PURE__ */
|
|
4688
|
+
}, /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroupItem, {
|
|
4823
4689
|
variant: "ghost",
|
|
4824
4690
|
...props,
|
|
4825
4691
|
classNames: buttonStyles
|
|
4826
|
-
}, /* @__PURE__ */
|
|
4692
|
+
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
4827
4693
|
className: iconStyles
|
|
4828
|
-
}), /* @__PURE__ */
|
|
4694
|
+
}), /* @__PURE__ */ React.createElement("span", {
|
|
4829
4695
|
className: "sr-only"
|
|
4830
|
-
}, children))), /* @__PURE__ */
|
|
4696
|
+
}, children))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
|
|
4831
4697
|
};
|
|
4832
4698
|
var ToolbarButton = ({ Icon, children, ...props }) => {
|
|
4833
|
-
return /* @__PURE__ */
|
|
4699
|
+
return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
4834
4700
|
asChild: true
|
|
4835
|
-
}, /* @__PURE__ */
|
|
4701
|
+
}, /* @__PURE__ */ React.createElement(NaturalToolbar.Button, {
|
|
4836
4702
|
variant: "ghost",
|
|
4837
4703
|
...props,
|
|
4838
4704
|
classNames: buttonStyles
|
|
4839
|
-
}, /* @__PURE__ */
|
|
4705
|
+
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
4840
4706
|
className: iconStyles
|
|
4841
|
-
}), /* @__PURE__ */
|
|
4707
|
+
}), /* @__PURE__ */ React.createElement("span", {
|
|
4842
4708
|
className: "sr-only"
|
|
4843
|
-
}, children))), /* @__PURE__ */
|
|
4709
|
+
}, children))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
|
|
4844
4710
|
};
|
|
4845
4711
|
var ViewModeIcons = {
|
|
4846
4712
|
preview: PencilSimple,
|
|
@@ -4851,10 +4717,10 @@ var MarkdownView = ({ mode }) => {
|
|
|
4851
4717
|
const { t } = useTranslation(translationKey);
|
|
4852
4718
|
const { onAction } = useToolbarContext("ViewMode");
|
|
4853
4719
|
const ModeIcon = ViewModeIcons[mode ?? "preview"];
|
|
4854
|
-
const suppressNextTooltip =
|
|
4855
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4856
|
-
const [selectOpen, setSelectOpen] =
|
|
4857
|
-
return /* @__PURE__ */
|
|
4720
|
+
const suppressNextTooltip = useRef(false);
|
|
4721
|
+
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
|
4722
|
+
const [selectOpen, setSelectOpen] = useState3(false);
|
|
4723
|
+
return /* @__PURE__ */ React.createElement(Tooltip.Root, {
|
|
4858
4724
|
open: tooltipOpen,
|
|
4859
4725
|
onOpenChange: (nextOpen) => {
|
|
4860
4726
|
if (nextOpen && suppressNextTooltip.current) {
|
|
@@ -4864,7 +4730,7 @@ var MarkdownView = ({ mode }) => {
|
|
|
4864
4730
|
return setTooltipOpen(nextOpen);
|
|
4865
4731
|
}
|
|
4866
4732
|
}
|
|
4867
|
-
}, /* @__PURE__ */
|
|
4733
|
+
}, /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
|
|
4868
4734
|
open: selectOpen,
|
|
4869
4735
|
onOpenChange: (nextOpen) => {
|
|
4870
4736
|
if (!nextOpen) {
|
|
@@ -4872,39 +4738,39 @@ var MarkdownView = ({ mode }) => {
|
|
|
4872
4738
|
}
|
|
4873
4739
|
return setSelectOpen(nextOpen);
|
|
4874
4740
|
}
|
|
4875
|
-
}, /* @__PURE__ */
|
|
4741
|
+
}, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
4876
4742
|
asChild: true
|
|
4877
|
-
}, /* @__PURE__ */
|
|
4743
|
+
}, /* @__PURE__ */ React.createElement(NaturalToolbar.Button, {
|
|
4878
4744
|
asChild: true
|
|
4879
|
-
}, /* @__PURE__ */
|
|
4745
|
+
}, /* @__PURE__ */ React.createElement(DropdownMenu.Trigger, {
|
|
4880
4746
|
asChild: true
|
|
4881
|
-
}, /* @__PURE__ */
|
|
4747
|
+
}, /* @__PURE__ */ React.createElement(Button, {
|
|
4882
4748
|
variant: "ghost",
|
|
4883
4749
|
classNames: buttonStyles
|
|
4884
|
-
}, /* @__PURE__ */
|
|
4750
|
+
}, /* @__PURE__ */ React.createElement("span", {
|
|
4885
4751
|
className: "sr-only"
|
|
4886
|
-
}, t("mode label")), /* @__PURE__ */
|
|
4752
|
+
}, t("mode label")), /* @__PURE__ */ React.createElement(ModeIcon, {
|
|
4887
4753
|
className: iconStyles
|
|
4888
|
-
}), /* @__PURE__ */
|
|
4754
|
+
}), /* @__PURE__ */ React.createElement(CaretDown, null))))), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, {
|
|
4889
4755
|
classNames: "is-min md:is-min",
|
|
4890
4756
|
onCloseAutoFocus: (e) => e.preventDefault()
|
|
4891
|
-
}, /* @__PURE__ */
|
|
4757
|
+
}, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
|
|
4892
4758
|
const Icon = ViewModeIcons[value];
|
|
4893
|
-
return /* @__PURE__ */
|
|
4759
|
+
return /* @__PURE__ */ React.createElement(DropdownMenu.CheckboxItem, {
|
|
4894
4760
|
key: value,
|
|
4895
4761
|
checked: value === mode,
|
|
4896
4762
|
onClick: () => onAction?.({
|
|
4897
4763
|
type: "view-mode",
|
|
4898
4764
|
data: value
|
|
4899
4765
|
})
|
|
4900
|
-
}, /* @__PURE__ */
|
|
4766
|
+
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
4901
4767
|
className: iconStyles
|
|
4902
|
-
}), /* @__PURE__ */
|
|
4768
|
+
}), /* @__PURE__ */ React.createElement("span", {
|
|
4903
4769
|
className: "whitespace-nowrap grow"
|
|
4904
|
-
}, t(`${value} mode label`)), /* @__PURE__ */
|
|
4770
|
+
}, t(`${value} mode label`)), /* @__PURE__ */ React.createElement(Check, {
|
|
4905
4771
|
className: value === mode ? "visible" : "invisible"
|
|
4906
4772
|
}));
|
|
4907
|
-
})), /* @__PURE__ */
|
|
4773
|
+
})), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
|
|
4908
4774
|
};
|
|
4909
4775
|
var HeadingIcons = {
|
|
4910
4776
|
"0": Paragraph,
|
|
@@ -4922,10 +4788,10 @@ var MarkdownHeading = () => {
|
|
|
4922
4788
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4923
4789
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4924
4790
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4925
|
-
const suppressNextTooltip =
|
|
4926
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4927
|
-
const [selectOpen, setSelectOpen] =
|
|
4928
|
-
return /* @__PURE__ */
|
|
4791
|
+
const suppressNextTooltip = useRef(false);
|
|
4792
|
+
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
|
4793
|
+
const [selectOpen, setSelectOpen] = useState3(false);
|
|
4794
|
+
return /* @__PURE__ */ React.createElement(Tooltip.Root, {
|
|
4929
4795
|
open: tooltipOpen,
|
|
4930
4796
|
onOpenChange: (nextOpen) => {
|
|
4931
4797
|
if (nextOpen && suppressNextTooltip.current) {
|
|
@@ -4935,7 +4801,7 @@ var MarkdownHeading = () => {
|
|
|
4935
4801
|
return setTooltipOpen(nextOpen);
|
|
4936
4802
|
}
|
|
4937
4803
|
}
|
|
4938
|
-
}, /* @__PURE__ */
|
|
4804
|
+
}, /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
|
|
4939
4805
|
open: selectOpen,
|
|
4940
4806
|
onOpenChange: (nextOpen) => {
|
|
4941
4807
|
if (!nextOpen) {
|
|
@@ -4943,40 +4809,40 @@ var MarkdownHeading = () => {
|
|
|
4943
4809
|
}
|
|
4944
4810
|
return setSelectOpen(nextOpen);
|
|
4945
4811
|
}
|
|
4946
|
-
}, /* @__PURE__ */
|
|
4812
|
+
}, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
4947
4813
|
asChild: true
|
|
4948
|
-
}, /* @__PURE__ */
|
|
4814
|
+
}, /* @__PURE__ */ React.createElement(NaturalToolbar.Button, {
|
|
4949
4815
|
asChild: true
|
|
4950
|
-
}, /* @__PURE__ */
|
|
4816
|
+
}, /* @__PURE__ */ React.createElement(DropdownMenu.Trigger, {
|
|
4951
4817
|
asChild: true
|
|
4952
|
-
}, /* @__PURE__ */
|
|
4818
|
+
}, /* @__PURE__ */ React.createElement(Button, {
|
|
4953
4819
|
variant: "ghost",
|
|
4954
4820
|
classNames: buttonStyles,
|
|
4955
4821
|
disabled: value === null
|
|
4956
|
-
}, /* @__PURE__ */
|
|
4822
|
+
}, /* @__PURE__ */ React.createElement("span", {
|
|
4957
4823
|
className: "sr-only"
|
|
4958
|
-
}, t("heading label")), /* @__PURE__ */
|
|
4824
|
+
}, t("heading label")), /* @__PURE__ */ React.createElement(HeadingIcon, {
|
|
4959
4825
|
className: iconStyles
|
|
4960
|
-
}), /* @__PURE__ */
|
|
4826
|
+
}), /* @__PURE__ */ React.createElement(CaretDown, null))))), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, {
|
|
4961
4827
|
classNames: "is-min md:is-min",
|
|
4962
4828
|
onCloseAutoFocus: (e) => e.preventDefault()
|
|
4963
|
-
}, /* @__PURE__ */
|
|
4829
|
+
}, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
|
|
4964
4830
|
const Icon = HeadingIcons[level];
|
|
4965
|
-
return /* @__PURE__ */
|
|
4831
|
+
return /* @__PURE__ */ React.createElement(DropdownMenu.CheckboxItem, {
|
|
4966
4832
|
key: level,
|
|
4967
4833
|
checked: value === level,
|
|
4968
4834
|
onClick: () => onAction?.({
|
|
4969
4835
|
type: "heading",
|
|
4970
4836
|
data: level
|
|
4971
4837
|
})
|
|
4972
|
-
}, /* @__PURE__ */
|
|
4838
|
+
}, /* @__PURE__ */ React.createElement("span", {
|
|
4973
4839
|
className: "sr-only"
|
|
4974
4840
|
}, t("heading level label", {
|
|
4975
4841
|
count: parseInt(level)
|
|
4976
|
-
})), /* @__PURE__ */
|
|
4842
|
+
})), /* @__PURE__ */ React.createElement(Icon, {
|
|
4977
4843
|
className: iconStyles
|
|
4978
|
-
}), /* @__PURE__ */
|
|
4979
|
-
})), /* @__PURE__ */
|
|
4844
|
+
}), /* @__PURE__ */ React.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React.createElement(Check, null)));
|
|
4845
|
+
})), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
|
|
4980
4846
|
};
|
|
4981
4847
|
var markdownStyles = [
|
|
4982
4848
|
{
|
|
@@ -5008,10 +4874,10 @@ var markdownStyles = [
|
|
|
5008
4874
|
var MarkdownStyles = () => {
|
|
5009
4875
|
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
5010
4876
|
const { t } = useTranslation(translationKey);
|
|
5011
|
-
return /* @__PURE__ */
|
|
4877
|
+
return /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroup, {
|
|
5012
4878
|
type: "multiple",
|
|
5013
4879
|
value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
|
|
5014
|
-
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */
|
|
4880
|
+
}, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React.createElement(ToolbarToggleButton, {
|
|
5015
4881
|
key: type,
|
|
5016
4882
|
value: type,
|
|
5017
4883
|
Icon,
|
|
@@ -5042,10 +4908,10 @@ var markdownLists = [
|
|
|
5042
4908
|
var MarkdownLists = () => {
|
|
5043
4909
|
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
5044
4910
|
const { t } = useTranslation(translationKey);
|
|
5045
|
-
return /* @__PURE__ */
|
|
4911
|
+
return /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroup, {
|
|
5046
4912
|
type: "single",
|
|
5047
4913
|
value: state2?.listStyle ? `list-${state2.listStyle}` : ""
|
|
5048
|
-
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */
|
|
4914
|
+
}, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React.createElement(ToolbarToggleButton, {
|
|
5049
4915
|
key: type,
|
|
5050
4916
|
value: type,
|
|
5051
4917
|
Icon,
|
|
@@ -5077,10 +4943,10 @@ var MarkdownBlocks = () => {
|
|
|
5077
4943
|
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
5078
4944
|
const { t } = useTranslation(translationKey);
|
|
5079
4945
|
const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
|
|
5080
|
-
return /* @__PURE__ */
|
|
4946
|
+
return /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroup, {
|
|
5081
4947
|
type: "single",
|
|
5082
4948
|
value: value?.type ?? ""
|
|
5083
|
-
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */
|
|
4949
|
+
}, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React.createElement(ToolbarToggleButton, {
|
|
5084
4950
|
key: type,
|
|
5085
4951
|
value: type,
|
|
5086
4952
|
Icon,
|
|
@@ -5091,7 +4957,7 @@ var MarkdownBlocks = () => {
|
|
|
5091
4957
|
}) : void 0
|
|
5092
4958
|
}, t(`${type} label`))));
|
|
5093
4959
|
};
|
|
5094
|
-
var MarkdownStandard = () => /* @__PURE__ */
|
|
4960
|
+
var MarkdownStandard = () => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(MarkdownHeading, null), /* @__PURE__ */ React.createElement(MarkdownStyles, null), /* @__PURE__ */ React.createElement(MarkdownLists, null), /* @__PURE__ */ React.createElement(MarkdownBlocks, null));
|
|
5095
4961
|
var MarkdownCustom = ({ onUpload } = {}) => {
|
|
5096
4962
|
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
5097
4963
|
const { t } = useTranslation(translationKey);
|
|
@@ -5107,7 +4973,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
|
|
|
5107
4973
|
]
|
|
5108
4974
|
}
|
|
5109
4975
|
});
|
|
5110
|
-
|
|
4976
|
+
useEffect2(() => {
|
|
5111
4977
|
if (onUpload && acceptedFiles.length) {
|
|
5112
4978
|
requestAnimationFrame(async () => {
|
|
5113
4979
|
const f = acceptedFiles[0];
|
|
@@ -5129,7 +4995,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
|
|
|
5129
4995
|
}, [
|
|
5130
4996
|
acceptedFiles
|
|
5131
4997
|
]);
|
|
5132
|
-
return /* @__PURE__ */
|
|
4998
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("input", getInputProps()), /* @__PURE__ */ React.createElement(ToolbarButton, {
|
|
5133
4999
|
value: "image",
|
|
5134
5000
|
Icon: Image,
|
|
5135
5001
|
onClick: () => open()
|
|
@@ -5138,7 +5004,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
|
|
|
5138
5004
|
var MarkdownActions = () => {
|
|
5139
5005
|
const { onAction, state: state2 } = useToolbarContext("MarkdownActions");
|
|
5140
5006
|
const { t } = useTranslation(translationKey);
|
|
5141
|
-
return /* @__PURE__ */
|
|
5007
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ToolbarButton, {
|
|
5142
5008
|
value: "comment",
|
|
5143
5009
|
Icon: ChatText,
|
|
5144
5010
|
"data-testid": "editor.toolbar.comment",
|
|
@@ -5164,51 +5030,71 @@ var useActionHandler = (view) => {
|
|
|
5164
5030
|
};
|
|
5165
5031
|
|
|
5166
5032
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
5167
|
-
import {
|
|
5168
|
-
import { EditorView as
|
|
5169
|
-
import { useFocusableGroup
|
|
5170
|
-
import { useCallback
|
|
5171
|
-
import { log as
|
|
5172
|
-
import {
|
|
5173
|
-
|
|
5174
|
-
var
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
const
|
|
5178
|
-
|
|
5179
|
-
|
|
5033
|
+
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
5034
|
+
import { EditorView as EditorView16 } from "@codemirror/view";
|
|
5035
|
+
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
5036
|
+
import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
|
|
5037
|
+
import { log as log7 } from "@dxos/log";
|
|
5038
|
+
import { useDefaultValue } from "@dxos/react-ui";
|
|
5039
|
+
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
5040
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
5041
|
+
var instanceCount = 0;
|
|
5042
|
+
var useTextEditor = (props = {}, deps = []) => {
|
|
5043
|
+
const { id, initialValue, selection, extensions, autoFocus, scrollTo: _scrollTo, moveToEndOfLine, debug } = useMemo3(() => {
|
|
5044
|
+
return typeof props === "function" ? props() : props;
|
|
5045
|
+
}, deps ?? []);
|
|
5046
|
+
const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
|
|
5047
|
+
const scrollTo = useDefaultValue(_scrollTo, EditorView16.scrollIntoView(0, {
|
|
5048
|
+
yMargin: 0
|
|
5049
|
+
}));
|
|
5050
|
+
const onUpdate = useRef2();
|
|
5051
|
+
const [view, setView] = useState4();
|
|
5052
|
+
const parentRef = useRef2(null);
|
|
5053
|
+
useEffect3(() => {
|
|
5180
5054
|
let view2;
|
|
5181
5055
|
if (parentRef.current) {
|
|
5182
|
-
|
|
5183
|
-
id
|
|
5056
|
+
log7("create", {
|
|
5057
|
+
id,
|
|
5058
|
+
instanceId,
|
|
5059
|
+
doc: initialValue?.length ?? 0
|
|
5184
5060
|
}, {
|
|
5185
|
-
F:
|
|
5186
|
-
L:
|
|
5061
|
+
F: __dxlog_file11,
|
|
5062
|
+
L: 86,
|
|
5187
5063
|
S: void 0,
|
|
5188
5064
|
C: (f, a) => f(...a)
|
|
5189
5065
|
});
|
|
5190
|
-
|
|
5191
|
-
|
|
5066
|
+
let initialSelection = selection;
|
|
5067
|
+
if (moveToEndOfLine && selection === void 0) {
|
|
5068
|
+
const index = initialValue?.indexOf("\n");
|
|
5069
|
+
const anchor = !index || index === -1 ? 0 : index;
|
|
5070
|
+
initialSelection = {
|
|
5071
|
+
anchor
|
|
5072
|
+
};
|
|
5073
|
+
}
|
|
5074
|
+
const state2 = EditorState2.create({
|
|
5075
|
+
doc: initialValue,
|
|
5076
|
+
selection: initialSelection,
|
|
5192
5077
|
extensions: [
|
|
5193
5078
|
id && documentId2.of(id),
|
|
5194
5079
|
// TODO(burdon): Doesn't catch errors in keymap functions.
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
F:
|
|
5198
|
-
L:
|
|
5080
|
+
EditorView16.exceptionSink.of((err) => {
|
|
5081
|
+
log7.catch(err, void 0, {
|
|
5082
|
+
F: __dxlog_file11,
|
|
5083
|
+
L: 104,
|
|
5199
5084
|
S: void 0,
|
|
5200
5085
|
C: (f, a) => f(...a)
|
|
5201
5086
|
});
|
|
5202
5087
|
}),
|
|
5203
5088
|
extensions,
|
|
5204
|
-
|
|
5089
|
+
EditorView16.updateListener.of(() => {
|
|
5205
5090
|
onUpdate.current?.();
|
|
5206
5091
|
})
|
|
5207
|
-
].filter(
|
|
5092
|
+
].filter(isNotFalsy4)
|
|
5208
5093
|
});
|
|
5209
|
-
view2 = new
|
|
5094
|
+
view2 = new EditorView16({
|
|
5210
5095
|
parent: parentRef.current,
|
|
5211
5096
|
scrollTo,
|
|
5097
|
+
selection: initialSelection,
|
|
5212
5098
|
state: state2,
|
|
5213
5099
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
5214
5100
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
@@ -5219,30 +5105,34 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
5219
5105
|
view3.update(trs);
|
|
5220
5106
|
}
|
|
5221
5107
|
});
|
|
5108
|
+
if (!initialValue && moveToEndOfLine) {
|
|
5109
|
+
const { to } = view2.state.doc.lineAt(0);
|
|
5110
|
+
view2.dispatch({
|
|
5111
|
+
selection: {
|
|
5112
|
+
anchor: to
|
|
5113
|
+
}
|
|
5114
|
+
});
|
|
5115
|
+
}
|
|
5222
5116
|
setView(view2);
|
|
5223
5117
|
}
|
|
5224
5118
|
return () => {
|
|
5225
|
-
|
|
5119
|
+
log7("destroy", {
|
|
5226
5120
|
id
|
|
5227
5121
|
}, {
|
|
5228
|
-
F:
|
|
5229
|
-
L:
|
|
5122
|
+
F: __dxlog_file11,
|
|
5123
|
+
L: 139,
|
|
5230
5124
|
S: void 0,
|
|
5231
5125
|
C: (f, a) => f(...a)
|
|
5232
5126
|
});
|
|
5233
5127
|
view2?.destroy();
|
|
5234
5128
|
};
|
|
5235
5129
|
}, deps);
|
|
5236
|
-
|
|
5130
|
+
useEffect3(() => {
|
|
5237
5131
|
if (view) {
|
|
5238
|
-
if (
|
|
5239
|
-
selection = EditorSelection2.single(view.state.doc.line(1).to);
|
|
5240
|
-
}
|
|
5241
|
-
if (selection || scrollTo) {
|
|
5132
|
+
if (scrollTo) {
|
|
5242
5133
|
onUpdate.current = () => {
|
|
5243
5134
|
onUpdate.current = void 0;
|
|
5244
5135
|
view.dispatch({
|
|
5245
|
-
selection,
|
|
5246
5136
|
effects: scrollTo && [
|
|
5247
5137
|
scrollTo
|
|
5248
5138
|
],
|
|
@@ -5250,20 +5140,27 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
|
5250
5140
|
});
|
|
5251
5141
|
};
|
|
5252
5142
|
}
|
|
5253
|
-
if (
|
|
5254
|
-
|
|
5143
|
+
if (view.state.facet(editorInputMode).noTabster) {
|
|
5144
|
+
parentRef.current?.removeAttribute("data-tabster");
|
|
5255
5145
|
}
|
|
5256
5146
|
}
|
|
5257
5147
|
}, [
|
|
5258
5148
|
view,
|
|
5259
|
-
autoFocus,
|
|
5260
5149
|
selection,
|
|
5261
5150
|
scrollTo
|
|
5262
5151
|
]);
|
|
5263
|
-
|
|
5152
|
+
useEffect3(() => {
|
|
5153
|
+
if (view && autoFocus) {
|
|
5154
|
+
view.focus();
|
|
5155
|
+
}
|
|
5156
|
+
}, [
|
|
5157
|
+
autoFocus,
|
|
5158
|
+
view
|
|
5159
|
+
]);
|
|
5160
|
+
const focusableGroup = useFocusableGroup({
|
|
5264
5161
|
tabBehavior: "limited"
|
|
5265
5162
|
});
|
|
5266
|
-
const handleKeyUp =
|
|
5163
|
+
const handleKeyUp = useCallback((event) => {
|
|
5267
5164
|
const { key, target, currentTarget } = event;
|
|
5268
5165
|
if (target === currentTarget) {
|
|
5269
5166
|
switch (key) {
|
|
@@ -5296,7 +5193,6 @@ export {
|
|
|
5296
5193
|
List,
|
|
5297
5194
|
RemoteSelectionsDecorator,
|
|
5298
5195
|
SpaceAwarenessProvider,
|
|
5299
|
-
TextEditor,
|
|
5300
5196
|
TextKind,
|
|
5301
5197
|
Toolbar,
|
|
5302
5198
|
addBlockquote,
|