@dxos/react-ui-editor 0.4.5-next.ea4f804 → 0.4.6-main.268e405
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 +68 -45
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -0
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/styles/layout.d.ts +2 -3
- package/dist/types/src/styles/layout.d.ts.map +1 -1
- package/dist/types/src/themes/default.d.ts.map +1 -1
- package/package.json +26 -25
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +1 -1
- package/src/components/TextEditor/TextEditor.tsx +36 -18
- package/src/components/TextEditor/hooks.stories.tsx +11 -8
- package/src/components/Toolbar/Toolbar.stories.tsx +9 -6
- package/src/components/Toolbar/Toolbar.tsx +22 -2
- package/src/hooks/useTextEditor.ts +3 -3
- package/src/index.ts +1 -7
- package/src/styles/layout.ts +2 -5
- package/src/themes/default.ts +7 -3
|
@@ -32,7 +32,7 @@ import { tags as tags2 } from "@lezer/highlight";
|
|
|
32
32
|
|
|
33
33
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
34
34
|
import { EditorState as EditorState2 } from "@codemirror/state";
|
|
35
|
-
import { EditorView as EditorView14 } from "@codemirror/view";
|
|
35
|
+
import { EditorView as EditorView14, scrollPastEnd } from "@codemirror/view";
|
|
36
36
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
37
37
|
import defaultsDeep2 from "lodash.defaultsdeep";
|
|
38
38
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2, useMemo as useMemo2 } from "react";
|
|
@@ -1140,9 +1140,8 @@ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue)
|
|
|
1140
1140
|
|
|
1141
1141
|
// packages/ui/react-ui-editor/src/styles/layout.ts
|
|
1142
1142
|
var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
|
|
1143
|
-
var editorFillLayoutRoot = "bs-full
|
|
1144
|
-
var editorFillLayoutEditor = "
|
|
1145
|
-
var editorHalfViewportOverscrollContent = "after:block after:min-bs-[50dvh] after:pointer-events-none";
|
|
1143
|
+
var editorFillLayoutRoot = "bs-full relative";
|
|
1144
|
+
var editorFillLayoutEditor = "!absolute inset-0";
|
|
1146
1145
|
|
|
1147
1146
|
// packages/ui/react-ui-editor/src/util.ts
|
|
1148
1147
|
import { log as log2 } from "@dxos/log";
|
|
@@ -3602,13 +3601,17 @@ var defaultTheme = {
|
|
|
3602
3601
|
"&.cm-focused": {
|
|
3603
3602
|
outline: "none"
|
|
3604
3603
|
},
|
|
3604
|
+
// NOTE: See https://codemirror.net/docs/guide (DOM Structure).
|
|
3605
3605
|
".cm-scroller": {
|
|
3606
|
-
//
|
|
3606
|
+
// TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
|
|
3607
|
+
// Inside of that is the scroller element. If the editor has its own scrollbar, this one should be styled with overflow: auto. But it doesn't have to—the editor also supports growing to accomodate its content, or growing up to a certain max-height and then scrolling.
|
|
3608
|
+
overflowY: "auto",
|
|
3607
3609
|
fontFamily: get3(tokens, "fontFamily.mono", []).join(","),
|
|
3608
|
-
lineHeight: 1.
|
|
3610
|
+
lineHeight: 1.5
|
|
3609
3611
|
},
|
|
3610
3612
|
".cm-content": {
|
|
3611
|
-
|
|
3613
|
+
// TODO(burdon): Is it possible to remove the padding value from CM's default theme?
|
|
3614
|
+
// padding: 'unset',
|
|
3612
3615
|
// NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
|
|
3613
3616
|
fontSize: "16px"
|
|
3614
3617
|
},
|
|
@@ -3814,7 +3817,7 @@ var codeTheme = {
|
|
|
3814
3817
|
|
|
3815
3818
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
3816
3819
|
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
3817
|
-
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
|
|
3820
|
+
var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo = EditorView14.scrollIntoView(0), moveToEndOfLine, selection, theme, slots = defaultSlots, extensions = [], scrollPastEnd: _scrollPastEnd, debug }, forwardedRef) => {
|
|
3818
3821
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
3819
3822
|
tabBehavior: "limited"
|
|
3820
3823
|
});
|
|
@@ -3825,15 +3828,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3825
3828
|
view
|
|
3826
3829
|
]);
|
|
3827
3830
|
useEffect2(() => {
|
|
3828
|
-
if (autoFocus
|
|
3829
|
-
if (view?.state.selection.main?.from === 0) {
|
|
3830
|
-
const { to } = view.state.doc.lineAt(0);
|
|
3831
|
-
view?.dispatch({
|
|
3832
|
-
selection: {
|
|
3833
|
-
anchor: to
|
|
3834
|
-
}
|
|
3835
|
-
});
|
|
3836
|
-
}
|
|
3831
|
+
if (autoFocus) {
|
|
3837
3832
|
view?.focus();
|
|
3838
3833
|
}
|
|
3839
3834
|
}, [
|
|
@@ -3852,22 +3847,24 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3852
3847
|
EditorView14.exceptionSink.of((err) => {
|
|
3853
3848
|
log3.catch(err, void 0, {
|
|
3854
3849
|
F: __dxlog_file4,
|
|
3855
|
-
L:
|
|
3850
|
+
L: 122,
|
|
3856
3851
|
S: void 0,
|
|
3857
3852
|
C: (f, a) => f(...a)
|
|
3858
3853
|
});
|
|
3859
3854
|
}),
|
|
3860
3855
|
// Theme.
|
|
3861
|
-
// TODO(burdon): Make configurable.
|
|
3856
|
+
// TODO(burdon): Make base theme configurable.
|
|
3862
3857
|
EditorView14.baseTheme(defaultTheme),
|
|
3863
|
-
EditorView14.theme(theme
|
|
3858
|
+
theme && EditorView14.theme(theme),
|
|
3864
3859
|
EditorView14.darkTheme.of(themeMode === "dark"),
|
|
3865
|
-
EditorView14.editorAttributes.of({
|
|
3866
|
-
class: slots.editor
|
|
3860
|
+
slots.editor?.className && EditorView14.editorAttributes.of({
|
|
3861
|
+
class: slots.editor.className
|
|
3867
3862
|
}),
|
|
3868
|
-
EditorView14.contentAttributes.of({
|
|
3869
|
-
class: slots.content
|
|
3863
|
+
slots.content?.className && EditorView14.contentAttributes.of({
|
|
3864
|
+
class: slots.content.className
|
|
3870
3865
|
}),
|
|
3866
|
+
// NOTE: Assumes default line height.
|
|
3867
|
+
_scrollPastEnd && scrollPastEnd(),
|
|
3871
3868
|
// Focus.
|
|
3872
3869
|
EditorView14.updateListener.of((update2) => {
|
|
3873
3870
|
update2.transactions.forEach((transaction) => {
|
|
@@ -3886,26 +3883,33 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
|
|
|
3886
3883
|
...extensions
|
|
3887
3884
|
].filter(isNotFalsy4)
|
|
3888
3885
|
});
|
|
3889
|
-
const
|
|
3886
|
+
const view2 = new EditorView14({
|
|
3890
3887
|
state,
|
|
3891
3888
|
parent: rootRef.current,
|
|
3892
3889
|
scrollTo,
|
|
3893
3890
|
// NOTE: Uncomment to debug/monitor all transactions.
|
|
3894
3891
|
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
3895
|
-
dispatchTransactions: (trs,
|
|
3892
|
+
dispatchTransactions: (trs, view3) => {
|
|
3896
3893
|
if (debug) {
|
|
3897
3894
|
logChanges(trs);
|
|
3898
3895
|
}
|
|
3899
|
-
|
|
3896
|
+
view3.update(trs);
|
|
3900
3897
|
}
|
|
3901
3898
|
});
|
|
3902
|
-
|
|
3903
|
-
|
|
3899
|
+
setView(view2);
|
|
3900
|
+
if (moveToEndOfLine) {
|
|
3901
|
+
const { to } = view2.state.doc.lineAt(0);
|
|
3902
|
+
view2?.dispatch({
|
|
3903
|
+
selection: {
|
|
3904
|
+
anchor: to
|
|
3905
|
+
}
|
|
3906
|
+
});
|
|
3907
|
+
}
|
|
3904
3908
|
if (state.facet(editorMode).noTabster) {
|
|
3905
3909
|
rootRef.current.removeAttribute("data-tabster");
|
|
3906
3910
|
}
|
|
3907
3911
|
return () => {
|
|
3908
|
-
|
|
3912
|
+
view2?.destroy();
|
|
3909
3913
|
setView(null);
|
|
3910
3914
|
};
|
|
3911
3915
|
}, [
|
|
@@ -3989,7 +3993,7 @@ var defaultSlots = {
|
|
|
3989
3993
|
className: focusRing
|
|
3990
3994
|
},
|
|
3991
3995
|
editor: {
|
|
3992
|
-
className: "
|
|
3996
|
+
className: "bs-full"
|
|
3993
3997
|
}
|
|
3994
3998
|
};
|
|
3995
3999
|
var defaultTextSlots = {
|
|
@@ -4002,7 +4006,7 @@ var defaultMarkdownSlots = {
|
|
|
4002
4006
|
// packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
|
|
4003
4007
|
import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
|
|
4004
4008
|
import { createContext } from "@radix-ui/react-context";
|
|
4005
|
-
import React2 from "react";
|
|
4009
|
+
import React2, { useRef as useRef2, useState as useState3 } from "react";
|
|
4006
4010
|
import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
|
|
4007
4011
|
import { getSize } from "@dxos/react-ui-theme";
|
|
4008
4012
|
var tooltipProps = {
|
|
@@ -4060,9 +4064,29 @@ var MarkdownHeading = () => {
|
|
|
4060
4064
|
const header = blockType && /heading(\d)/.exec(blockType);
|
|
4061
4065
|
const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
|
|
4062
4066
|
const HeadingIcon = HeadingIcons[value ?? "0"];
|
|
4063
|
-
|
|
4067
|
+
const suppressNextTooltip = useRef2(false);
|
|
4068
|
+
const [tooltipOpen, setTooltipOpen] = useState3(false);
|
|
4069
|
+
const [selectOpen, setSelectOpen] = useState3(false);
|
|
4070
|
+
return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
|
|
4071
|
+
open: tooltipOpen,
|
|
4072
|
+
onOpenChange: (nextOpen) => {
|
|
4073
|
+
if (nextOpen && suppressNextTooltip.current) {
|
|
4074
|
+
suppressNextTooltip.current = false;
|
|
4075
|
+
return setTooltipOpen(false);
|
|
4076
|
+
} else {
|
|
4077
|
+
return setTooltipOpen(nextOpen);
|
|
4078
|
+
}
|
|
4079
|
+
}
|
|
4080
|
+
}, /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
4064
4081
|
disabled: value === null,
|
|
4065
4082
|
value: value ?? "0",
|
|
4083
|
+
open: selectOpen,
|
|
4084
|
+
onOpenChange: (nextOpen) => {
|
|
4085
|
+
if (!nextOpen) {
|
|
4086
|
+
suppressNextTooltip.current = true;
|
|
4087
|
+
}
|
|
4088
|
+
return setSelectOpen(nextOpen);
|
|
4089
|
+
},
|
|
4066
4090
|
onValueChange: (value2) => onAction?.({
|
|
4067
4091
|
type: "heading",
|
|
4068
4092
|
data: parseInt(value2)
|
|
@@ -4406,10 +4430,10 @@ var useActionHandler = (view) => {
|
|
|
4406
4430
|
};
|
|
4407
4431
|
|
|
4408
4432
|
// packages/ui/react-ui-editor/src/hooks/useEditorView.ts
|
|
4409
|
-
import { useRef as
|
|
4433
|
+
import { useRef as useRef3, useState as useState4 } from "react";
|
|
4410
4434
|
var useEditorView = (id) => {
|
|
4411
|
-
const editorRef =
|
|
4412
|
-
const [prev, setPrev] =
|
|
4435
|
+
const editorRef = useRef3(null);
|
|
4436
|
+
const [prev, setPrev] = useState4([
|
|
4413
4437
|
null,
|
|
4414
4438
|
""
|
|
4415
4439
|
]);
|
|
@@ -4428,14 +4452,14 @@ var useEditorView = (id) => {
|
|
|
4428
4452
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4429
4453
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4430
4454
|
import { EditorView as EditorView15 } from "@codemirror/view";
|
|
4431
|
-
import { useEffect as useEffect3, useRef as
|
|
4455
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
4432
4456
|
import { log as log5 } from "@dxos/log";
|
|
4433
4457
|
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4434
4458
|
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4435
4459
|
var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
|
|
4436
|
-
const onUpdate =
|
|
4437
|
-
const [view, setView] =
|
|
4438
|
-
const parentRef =
|
|
4460
|
+
const onUpdate = useRef4();
|
|
4461
|
+
const [view, setView] = useState5();
|
|
4462
|
+
const parentRef = useRef4(null);
|
|
4439
4463
|
useEffect3(() => {
|
|
4440
4464
|
let view2;
|
|
4441
4465
|
if (parentRef.current) {
|
|
@@ -4447,7 +4471,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
4447
4471
|
EditorView15.exceptionSink.of((err) => {
|
|
4448
4472
|
log5.catch(err, void 0, {
|
|
4449
4473
|
F: __dxlog_file6,
|
|
4450
|
-
L:
|
|
4474
|
+
L: 61,
|
|
4451
4475
|
S: void 0,
|
|
4452
4476
|
C: (f, a) => f(...a)
|
|
4453
4477
|
});
|
|
@@ -4477,7 +4501,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
|
|
|
4477
4501
|
view2?.destroy();
|
|
4478
4502
|
};
|
|
4479
4503
|
}, [
|
|
4480
|
-
|
|
4504
|
+
doc,
|
|
4481
4505
|
extensions
|
|
4482
4506
|
]);
|
|
4483
4507
|
useEffect3(() => {
|
|
@@ -4536,7 +4560,7 @@ var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
|
|
|
4536
4560
|
|
|
4537
4561
|
// packages/ui/react-ui-editor/src/hooks/useTextModel.ts
|
|
4538
4562
|
import get4 from "lodash.get";
|
|
4539
|
-
import { useState as
|
|
4563
|
+
import { useState as useState6, useMemo as useMemo3 } from "react";
|
|
4540
4564
|
import { generateName } from "@dxos/display-name";
|
|
4541
4565
|
import { getRawDoc } from "@dxos/echo-schema";
|
|
4542
4566
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
@@ -4544,7 +4568,7 @@ import { isAutomergeObject } from "@dxos/react-client/echo";
|
|
|
4544
4568
|
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
|
|
4545
4569
|
var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
|
|
4546
4570
|
var useInMemoryTextModel = ({ id, defaultContent }) => {
|
|
4547
|
-
const [content, setContent] =
|
|
4571
|
+
const [content, setContent] = useState6(defaultContent ?? "");
|
|
4548
4572
|
return {
|
|
4549
4573
|
id,
|
|
4550
4574
|
content,
|
|
@@ -4646,7 +4670,6 @@ export {
|
|
|
4646
4670
|
defaultTheme,
|
|
4647
4671
|
editorFillLayoutEditor,
|
|
4648
4672
|
editorFillLayoutRoot,
|
|
4649
|
-
editorHalfViewportOverscrollContent,
|
|
4650
4673
|
editorMode,
|
|
4651
4674
|
editorWithToolbarLayout,
|
|
4652
4675
|
focusComment,
|