@dxos/react-ui-editor 0.6.1-main.ff751ec → 0.6.1
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 +48 -17
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +3 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +15 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/util/index.d.ts +3 -0
- package/dist/types/src/extensions/util/index.d.ts.map +1 -0
- package/dist/types/src/extensions/util/overlap.d.ts +8 -0
- package/dist/types/src/extensions/util/overlap.d.ts.map +1 -0
- package/package.json +25 -25
- package/src/components/Toolbar/Toolbar.tsx +3 -2
- package/src/extensions/comments.ts +52 -4
- package/src/extensions/util/index.ts +6 -0
- package/src/extensions/util/overlap.ts +11 -0
|
@@ -35,7 +35,7 @@ import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
|
|
|
35
35
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
36
36
|
import { EditorView as EditorView16 } from "@codemirror/view";
|
|
37
37
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
38
|
-
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as
|
|
38
|
+
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState3 } from "react";
|
|
39
39
|
import { log as log7 } from "@dxos/log";
|
|
40
40
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
41
41
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
@@ -1350,11 +1350,14 @@ import { invertedEffects } from "@codemirror/commands";
|
|
|
1350
1350
|
import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
|
|
1351
1351
|
import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7 } from "@codemirror/view";
|
|
1352
1352
|
import sortBy from "lodash.sortby";
|
|
1353
|
-
import { useEffect } from "react";
|
|
1353
|
+
import { useEffect, useMemo, useState } from "react";
|
|
1354
1354
|
import { debounce } from "@dxos/async";
|
|
1355
1355
|
import { log as log4 } from "@dxos/log";
|
|
1356
1356
|
import { nonNullable } from "@dxos/util";
|
|
1357
1357
|
|
|
1358
|
+
// packages/ui/react-ui-editor/src/extensions/util/overlap.ts
|
|
1359
|
+
var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
|
|
1360
|
+
|
|
1358
1361
|
// packages/ui/react-ui-editor/src/styles/markdown.ts
|
|
1359
1362
|
import { mx } from "@dxos/react-ui-theme";
|
|
1360
1363
|
var headings = {
|
|
@@ -1517,14 +1520,16 @@ var commentsDecorations = EditorView7.decorations.compute([
|
|
|
1517
1520
|
const { selection: { current }, comments: comments2 } = state2.field(commentsState);
|
|
1518
1521
|
const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
|
|
1519
1522
|
const range = comment.range;
|
|
1520
|
-
if (!range
|
|
1523
|
+
if (!range) {
|
|
1521
1524
|
log4.warn("Invalid range:", range, {
|
|
1522
1525
|
F: __dxlog_file6,
|
|
1523
|
-
L:
|
|
1526
|
+
L: 141,
|
|
1524
1527
|
S: void 0,
|
|
1525
1528
|
C: (f, a) => f(...a)
|
|
1526
1529
|
});
|
|
1527
1530
|
return void 0;
|
|
1531
|
+
} else if (range.from === range.to) {
|
|
1532
|
+
return void 0;
|
|
1528
1533
|
}
|
|
1529
1534
|
if (comment.comment.id === current) {
|
|
1530
1535
|
return commentCurrentMark.range(range.from, range.to);
|
|
@@ -1818,6 +1823,16 @@ var scrollThreadIntoView = (view, id, center = true) => {
|
|
|
1818
1823
|
});
|
|
1819
1824
|
}
|
|
1820
1825
|
};
|
|
1826
|
+
var selectionOverlapsComment = (state2) => {
|
|
1827
|
+
const { selection } = state2;
|
|
1828
|
+
const commentState = state2.field(commentsState);
|
|
1829
|
+
for (const range of selection.ranges) {
|
|
1830
|
+
if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
|
|
1831
|
+
return true;
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
return false;
|
|
1835
|
+
};
|
|
1821
1836
|
var useComments = (view, id, comments2) => {
|
|
1822
1837
|
useEffect(() => {
|
|
1823
1838
|
if (view) {
|
|
@@ -1836,6 +1851,18 @@ var useComments = (view, id, comments2) => {
|
|
|
1836
1851
|
comments2
|
|
1837
1852
|
]);
|
|
1838
1853
|
};
|
|
1854
|
+
var useCommentState = () => {
|
|
1855
|
+
const [comment, setComment] = useState(false);
|
|
1856
|
+
const observer = useMemo(() => EditorView7.updateListener.of((update2) => {
|
|
1857
|
+
if (update2.docChanged || update2.selectionSet) {
|
|
1858
|
+
setComment(() => selectionOverlapsComment(update2.state));
|
|
1859
|
+
}
|
|
1860
|
+
}), []);
|
|
1861
|
+
return [
|
|
1862
|
+
comment,
|
|
1863
|
+
observer
|
|
1864
|
+
];
|
|
1865
|
+
};
|
|
1839
1866
|
|
|
1840
1867
|
// packages/ui/react-ui-editor/src/extensions/doc.ts
|
|
1841
1868
|
import { Facet as Facet5 } from "@codemirror/state";
|
|
@@ -2271,7 +2298,7 @@ import { snippet } from "@codemirror/autocomplete";
|
|
|
2271
2298
|
import { syntaxTree } from "@codemirror/language";
|
|
2272
2299
|
import { EditorSelection } from "@codemirror/state";
|
|
2273
2300
|
import { EditorView as EditorView11, keymap as keymap6 } from "@codemirror/view";
|
|
2274
|
-
import { useMemo, useState } from "react";
|
|
2301
|
+
import { useMemo as useMemo2, useState as useState2 } from "react";
|
|
2275
2302
|
var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
|
|
2276
2303
|
var Inline;
|
|
2277
2304
|
(function(Inline2) {
|
|
@@ -3360,8 +3387,8 @@ var getFormatting = (state2) => {
|
|
|
3360
3387
|
};
|
|
3361
3388
|
};
|
|
3362
3389
|
var useFormattingState = () => {
|
|
3363
|
-
const [state2, setState] =
|
|
3364
|
-
const observer =
|
|
3390
|
+
const [state2, setState] = useState2();
|
|
3391
|
+
const observer = useMemo2(() => EditorView11.updateListener.of((update2) => {
|
|
3365
3392
|
if (update2.docChanged || update2.selectionSet) {
|
|
3366
3393
|
setState((prevState) => {
|
|
3367
3394
|
const newState = getFormatting(update2.state);
|
|
@@ -4515,7 +4542,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({
|
|
|
4515
4542
|
debug,
|
|
4516
4543
|
dataTestId
|
|
4517
4544
|
}, forwardedRef) => {
|
|
4518
|
-
const [instanceId] =
|
|
4545
|
+
const [instanceId] = useState3(() => `text-editor-${++instanceCount}`);
|
|
4519
4546
|
const scrollTo = useDefaultValue(propsScrollTo, EditorView16.scrollIntoView(0, {
|
|
4520
4547
|
yMargin: 0
|
|
4521
4548
|
}));
|
|
@@ -4523,7 +4550,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({
|
|
|
4523
4550
|
tabBehavior: "limited"
|
|
4524
4551
|
});
|
|
4525
4552
|
const rootRef = useRef(null);
|
|
4526
|
-
const [view, setView] =
|
|
4553
|
+
const [view, setView] = useState3(null);
|
|
4527
4554
|
useImperativeHandle(forwardedRef, () => view, [
|
|
4528
4555
|
view
|
|
4529
4556
|
]);
|
|
@@ -4638,7 +4665,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({
|
|
|
4638
4665
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4639
4666
|
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 } from "@phosphor-icons/react";
|
|
4640
4667
|
import { createContext } from "@radix-ui/react-context";
|
|
4641
|
-
import React2, { useEffect as useEffect3, useRef as useRef2, useState as
|
|
4668
|
+
import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
4642
4669
|
import { useDropzone } from "react-dropzone";
|
|
4643
4670
|
import { DensityProvider, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation, DropdownMenu, Button } from "@dxos/react-ui";
|
|
4644
4671
|
import { getSize } from "@dxos/react-ui-theme";
|
|
@@ -4711,8 +4738,8 @@ var MarkdownHeading = () => {
|
|
|
4711
4738
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4712
4739
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4713
4740
|
const suppressNextTooltip = useRef2(false);
|
|
4714
|
-
const [tooltipOpen, setTooltipOpen] =
|
|
4715
|
-
const [selectOpen, setSelectOpen] =
|
|
4741
|
+
const [tooltipOpen, setTooltipOpen] = useState4(false);
|
|
4742
|
+
const [selectOpen, setSelectOpen] = useState4(false);
|
|
4716
4743
|
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4717
4744
|
open: tooltipOpen,
|
|
4718
4745
|
onOpenChange: (nextOpen) => {
|
|
@@ -4924,7 +4951,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
|
|
|
4924
4951
|
}, t("image label")));
|
|
4925
4952
|
};
|
|
4926
4953
|
var MarkdownActions = () => {
|
|
4927
|
-
const { onAction } = useToolbarContext("MarkdownStyles");
|
|
4954
|
+
const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
|
|
4928
4955
|
const { t } = useTranslation(translationKey);
|
|
4929
4956
|
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ToolbarButton, {
|
|
4930
4957
|
value: "comment",
|
|
@@ -4932,7 +4959,8 @@ var MarkdownActions = () => {
|
|
|
4932
4959
|
"data-testid": "editor.toolbar.comment",
|
|
4933
4960
|
onClick: () => onAction?.({
|
|
4934
4961
|
type: "comment"
|
|
4935
|
-
})
|
|
4962
|
+
}),
|
|
4963
|
+
disabled: !state2 || state2.comment
|
|
4936
4964
|
}, t("comment label")));
|
|
4937
4965
|
};
|
|
4938
4966
|
var Toolbar = {
|
|
@@ -4953,14 +4981,14 @@ var useActionHandler = (view) => {
|
|
|
4953
4981
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4954
4982
|
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
4955
4983
|
import { useFocusableGroup as useFocusableGroup2 } from "@fluentui/react-tabster";
|
|
4956
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as
|
|
4984
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState5 } from "react";
|
|
4957
4985
|
import { log as log8 } from "@dxos/log";
|
|
4958
4986
|
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4959
4987
|
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4960
4988
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4961
|
-
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } =
|
|
4989
|
+
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
|
|
4962
4990
|
const onUpdate = useRef3();
|
|
4963
|
-
const [view, setView] =
|
|
4991
|
+
const [view, setView] = useState5();
|
|
4964
4992
|
const parentRef = useRef3(null);
|
|
4965
4993
|
useEffect4(() => {
|
|
4966
4994
|
let view2;
|
|
@@ -5097,6 +5125,7 @@ export {
|
|
|
5097
5125
|
callbackWrapper,
|
|
5098
5126
|
command,
|
|
5099
5127
|
comments,
|
|
5128
|
+
commentsState,
|
|
5100
5129
|
createBasicExtensions,
|
|
5101
5130
|
createComment,
|
|
5102
5131
|
createDataExtensions,
|
|
@@ -5135,6 +5164,7 @@ export {
|
|
|
5135
5164
|
removeList,
|
|
5136
5165
|
removeStyle,
|
|
5137
5166
|
scrollThreadIntoView,
|
|
5167
|
+
selectionOverlapsComment,
|
|
5138
5168
|
setBlockquote,
|
|
5139
5169
|
setComments,
|
|
5140
5170
|
setHeading,
|
|
@@ -5154,6 +5184,7 @@ export {
|
|
|
5154
5184
|
translations_default as translations,
|
|
5155
5185
|
typewriter,
|
|
5156
5186
|
useActionHandler,
|
|
5187
|
+
useCommentState,
|
|
5157
5188
|
useComments,
|
|
5158
5189
|
useFormattingState,
|
|
5159
5190
|
useTextEditor,
|