@dxos/react-ui-editor 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264 → 0.14.0
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/index.mjs +148 -133
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/translations.mjs.map +1 -1
- package/dist/types/src/components/Editor/Editor.d.ts +8 -8
- package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
- package/dist/types/src/components/Editor/Editor.stories.d.ts +1 -1
- package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Editor/EditorContext.d.ts +6 -6
- package/dist/types/src/components/Editor/EditorContext.d.ts.map +1 -1
- package/dist/types/src/components/Editor/EditorView.d.ts +5 -4
- package/dist/types/src/components/Editor/EditorView.d.ts.map +1 -1
- package/dist/types/src/components/Editor/index.d.ts +4 -3
- package/dist/types/src/components/Editor/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +2 -2
- package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/index.d.ts +5 -5
- package/dist/types/src/components/EditorMenuProvider/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts +1 -1
- package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/menu.d.ts +4 -4
- package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts +3 -3
- package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewContext.d.ts +1 -1
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewContext.d.ts.map +1 -1
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
- package/dist/types/src/components/EditorPreviewProvider/index.d.ts +2 -2
- package/dist/types/src/components/EditorPreviewProvider/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +5 -5
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +2 -2
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +2 -2
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/headings.d.ts +2 -2
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/image.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/index.d.ts +3 -3
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/lists.d.ts +2 -2
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/search.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts +2 -2
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +4 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.test.d.ts +2 -0
- package/dist/types/src/hooks/useTextEditor.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/stories/Assistant.stories.d.ts +1 -1
- package/dist/types/src/stories/Assistant.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Blocks.stories.d.ts +1 -1
- package/dist/types/src/stories/Blocks.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Diff.stories.d.ts +3 -3
- package/dist/types/src/stories/EditorToolbar.stories.d.ts +1 -1
- package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Experimental.stories.d.ts +3 -3
- package/dist/types/src/stories/Folding.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Markdown.stories.d.ts +7 -5
- package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Outliner.stories.d.ts +3 -1
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Popover.stories.d.ts +1 -1
- package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Suggest.stories.d.ts +1 -1
- package/dist/types/src/stories/Suggest.stories.d.ts.map +1 -1
- package/dist/types/src/stories/TextEditor.stories.d.ts +3 -3
- package/dist/types/src/stories/TrackChanges.stories.d.ts +1 -1
- package/dist/types/src/stories/TrackChanges.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Widgets.stories.d.ts +38 -6
- package/dist/types/src/stories/Widgets.stories.d.ts.map +1 -1
- package/dist/types/src/stories/{components → testing}/EditorStory.d.ts +2 -2
- package/dist/types/src/stories/testing/EditorStory.d.ts.map +1 -0
- package/dist/types/src/stories/testing/index.d.ts +3 -0
- package/dist/types/src/stories/testing/index.d.ts.map +1 -0
- package/dist/types/src/stories/testing/util.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/react.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -40
- package/src/components/Editor/Editor.stories.tsx +4 -4
- package/src/components/Editor/Editor.tsx +26 -12
- package/src/components/Editor/EditorContext.ts +6 -6
- package/src/components/Editor/EditorView.tsx +16 -8
- package/src/components/Editor/index.ts +7 -3
- package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +68 -79
- package/src/components/EditorMenuProvider/index.ts +5 -5
- package/src/components/EditorMenuProvider/menu-presets.ts +2 -2
- package/src/components/EditorMenuProvider/menu.ts +4 -4
- package/src/components/EditorMenuProvider/useEditorMenu.ts +4 -4
- package/src/components/EditorPreviewProvider/EditorPreviewContext.ts +1 -2
- package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +44 -11
- package/src/components/EditorPreviewProvider/index.ts +2 -2
- package/src/components/EditorToolbar/EditorToolbar.tsx +19 -21
- package/src/components/EditorToolbar/blocks.ts +2 -2
- package/src/components/EditorToolbar/formatting.ts +31 -22
- package/src/components/EditorToolbar/headings.ts +2 -2
- package/src/components/EditorToolbar/image.ts +1 -1
- package/src/components/EditorToolbar/index.ts +3 -3
- package/src/components/EditorToolbar/lists.ts +2 -2
- package/src/components/EditorToolbar/search.ts +1 -1
- package/src/components/EditorToolbar/view-mode.ts +3 -2
- package/src/components/index.ts +4 -4
- package/src/hooks/index.ts +2 -2
- package/src/hooks/useBasicMarkdownExtensions.ts +3 -3
- package/src/hooks/useTextEditor.test.tsx +49 -0
- package/src/hooks/useTextEditor.ts +17 -8
- package/src/index.ts +2 -2
- package/src/stories/Assistant.stories.tsx +6 -6
- package/src/stories/Automerge.stories.tsx +63 -17
- package/src/stories/Blocks.stories.tsx +4 -4
- package/src/stories/Comments.stories.tsx +17 -13
- package/src/stories/Diff.stories.tsx +1 -1
- package/src/stories/EditorToolbar.stories.tsx +6 -7
- package/src/stories/Experimental.stories.tsx +2 -2
- package/src/stories/Folding.stories.tsx +13 -10
- package/src/stories/Markdown.stories.tsx +26 -1
- package/src/stories/Outliner.stories.tsx +24 -2
- package/src/stories/Popover.stories.tsx +2 -2
- package/src/stories/Suggest.stories.tsx +4 -4
- package/src/stories/TextEditor.stories.tsx +1 -1
- package/src/stories/Theme.stories.tsx +3 -3
- package/src/stories/TrackChanges.stories.tsx +4 -4
- package/src/stories/Widgets.stories.tsx +186 -176
- package/src/stories/{components → testing}/EditorStory.tsx +7 -7
- package/src/stories/testing/index.ts +6 -0
- package/src/stories/{components → testing}/util.tsx +2 -2
- package/src/translations.ts +2 -2
- package/src/util/index.ts +1 -1
- package/src/util/react.tsx +4 -7
- package/dist/types/src/stories/components/EditorStory.d.ts.map +0 -1
- package/dist/types/src/stories/components/index.d.ts +0 -3
- package/dist/types/src/stories/components/index.d.ts.map +0 -1
- package/dist/types/src/stories/components/util.d.ts.map +0 -1
- package/src/stories/components/index.ts +0 -6
- /package/dist/types/src/stories/{components → testing}/util.d.ts +0 -0
package/dist/lib/index.mjs
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import { createContext } from "@
|
|
2
|
-
import * as Atom from "effect/
|
|
3
|
-
import { Fragment, forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
1
|
+
import { createContext, useControllableState } from "@dxos/react-hooks";
|
|
2
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
3
|
+
import { Fragment, Suspense, forwardRef, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { createPortal } from "react-dom";
|
|
5
5
|
import { invariant } from "@dxos/invariant";
|
|
6
6
|
import { mx } from "@dxos/ui-theme";
|
|
7
7
|
import { getProviderValue, isNonNullable, isTruthy } from "@dxos/util";
|
|
8
|
-
import { Inline, List, addBlockquote, addCodeblock, addLink,
|
|
8
|
+
import { Inline, List, addBlockquote, addCodeblock, addLink, computeDocChanges, createBasicExtensions, createMarkdownExtensions, createThemeExtensions, debugDispatcher, decorateMarkdown, documentId, initialSync, insertAtCursor, insertAtLineStart, insertTable, modalStateEffect, modalStateField, placeholder, removeBlockquote, removeCodeblock, removeLink, restoreEditorState, setHeading, setStyle, toggleList } from "@dxos/ui-editor";
|
|
9
9
|
import { EditorState, Prec, RangeSetBuilder, StateEffect, StateField, Transaction } from "@codemirror/state";
|
|
10
|
-
import { Decoration, EditorView, ViewPlugin, keymap } from "@codemirror/view";
|
|
11
|
-
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
10
|
+
import { Decoration, EditorView as EditorView$1, ViewPlugin, keymap } from "@codemirror/view";
|
|
12
11
|
import { addEventListener } from "@dxos/async";
|
|
13
|
-
import
|
|
12
|
+
import * as Field from "@dxos/react-ui/Field";
|
|
13
|
+
import * as Hooks from "@dxos/react-ui/Hooks";
|
|
14
|
+
import * as Icon from "@dxos/react-ui/Icon";
|
|
15
|
+
import * as Input from "@dxos/react-ui/Input";
|
|
16
|
+
import * as Layout from "@dxos/react-ui/Layout";
|
|
17
|
+
import * as Popover from "@dxos/react-ui/Popover";
|
|
18
|
+
import * as Theme from "@dxos/react-ui/Theme";
|
|
19
|
+
import * as Typography from "@dxos/react-ui/Typography";
|
|
20
|
+
import * as VirtualAnchor from "@dxos/react-ui/VirtualAnchor";
|
|
21
|
+
import { DX_ANCHOR_ACTIVATE } from "@dxos/ui-types";
|
|
14
22
|
import { translationKey } from "#translations";
|
|
15
23
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
import {
|
|
24
|
+
import { ActionToolbar, MenuBuilder, useMenuActions } from "@dxos/react-ui-menu";
|
|
17
25
|
import { openSearchPanel } from "@codemirror/search";
|
|
18
26
|
import { log } from "@dxos/log";
|
|
19
27
|
//#region src/components/Editor/controller.ts
|
|
@@ -117,7 +125,7 @@ var popover = (options = {}) => {
|
|
|
117
125
|
/**
|
|
118
126
|
* Listen for selection and document changes.
|
|
119
127
|
*/
|
|
120
|
-
var popoverTriggerListener = (options) => EditorView.updateListener.of(({ view, docChanged }) => {
|
|
128
|
+
var popoverTriggerListener = (options) => EditorView$1.updateListener.of(({ view, docChanged }) => {
|
|
121
129
|
const { range: activeRange, trigger } = view.state.field(popoverStateField) ?? {};
|
|
122
130
|
if (!activeRange) return;
|
|
123
131
|
const text = view.state.doc.sliceString(activeRange.from, activeRange.to);
|
|
@@ -137,7 +145,7 @@ var popoverTriggerListener = (options) => EditorView.updateListener.of(({ view,
|
|
|
137
145
|
* Open the popover while typing a word, without requiring a trigger character. Once a range is
|
|
138
146
|
* active, {@link popoverTriggerListener} keeps it in sync and closes it (whitespace, cursor moves).
|
|
139
147
|
*/
|
|
140
|
-
var popoverAutoActivate = (options) => EditorView.updateListener.of(({ view, docChanged, transactions }) => {
|
|
148
|
+
var popoverAutoActivate = (options) => EditorView$1.updateListener.of(({ view, docChanged, transactions }) => {
|
|
141
149
|
if (!docChanged || !transactions.some((tr) => tr.isUserEvent("input")) || view.state.field(popoverStateField)) return;
|
|
142
150
|
const selection = view.state.selection.main;
|
|
143
151
|
if (!selection.empty) return;
|
|
@@ -418,13 +426,13 @@ var linkSlashCommands = {
|
|
|
418
426
|
var __dxlog_file$3 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/components/EditorMenuProvider/EditorMenuProvider.tsx";
|
|
419
427
|
/**
|
|
420
428
|
* Implements the Popover and listens for the `dx-anchor-activate` event from the `popover` extension's decoration.
|
|
421
|
-
* NOTE: We don't use
|
|
429
|
+
* NOTE: We don't use Menu because the command menu needs to manage focus explicitly.
|
|
422
430
|
* I.e., focus must remain in the editor while displaying the menu (for type-ahead).
|
|
423
431
|
*/
|
|
424
432
|
var EditorMenuProvider = ({ children, getView, groups, currentItem, open: openProp, defaultOpen, numItems = 8, search, query = "", searchPlaceholder, onOpenChange, onActivate, onSelect, onCancel, onQueryChange, onNavigate }) => {
|
|
425
|
-
const { t } = useTranslation(translationKey);
|
|
433
|
+
const { t } = Hooks.useTranslation(translationKey);
|
|
426
434
|
const triggerRef = useRef(null);
|
|
427
|
-
const getViewRef = useDynamicRef(getView);
|
|
435
|
+
const getViewRef = Hooks.useDynamicRef(getView);
|
|
428
436
|
const [open, setOpen] = useControllableState({
|
|
429
437
|
prop: openProp,
|
|
430
438
|
defaultProp: defaultOpen,
|
|
@@ -433,7 +441,7 @@ var EditorMenuProvider = ({ children, getView, groups, currentItem, open: openPr
|
|
|
433
441
|
invariant(view, void 0, {
|
|
434
442
|
"~LogMeta": "~LogMeta",
|
|
435
443
|
F: __dxlog_file$3,
|
|
436
|
-
L:
|
|
444
|
+
L: 88,
|
|
437
445
|
S: void 0,
|
|
438
446
|
A: ["view", ""]
|
|
439
447
|
});
|
|
@@ -447,8 +455,8 @@ var EditorMenuProvider = ({ children, getView, groups, currentItem, open: openPr
|
|
|
447
455
|
useEffect(() => {
|
|
448
456
|
if (!root) return;
|
|
449
457
|
return addEventListener(root, DX_ANCHOR_ACTIVATE, (event) => {
|
|
450
|
-
const { trigger,
|
|
451
|
-
if (!
|
|
458
|
+
const { trigger, eid } = event;
|
|
459
|
+
if (!eid) {
|
|
452
460
|
triggerRef.current = trigger;
|
|
453
461
|
if (onActivate) {
|
|
454
462
|
const view = getViewRef.current?.();
|
|
@@ -468,7 +476,7 @@ var EditorMenuProvider = ({ children, getView, groups, currentItem, open: openPr
|
|
|
468
476
|
invariant(view, void 0, {
|
|
469
477
|
"~LogMeta": "~LogMeta",
|
|
470
478
|
F: __dxlog_file$3,
|
|
471
|
-
L:
|
|
479
|
+
L: 127,
|
|
472
480
|
S: void 0,
|
|
473
481
|
A: ["view", ""]
|
|
474
482
|
});
|
|
@@ -519,69 +527,54 @@ var EditorMenuProvider = ({ children, getView, groups, currentItem, open: openPr
|
|
|
519
527
|
onNavigate
|
|
520
528
|
]);
|
|
521
529
|
return /* @__PURE__ */ jsxs(Popover.Root, {
|
|
522
|
-
modal: false,
|
|
523
530
|
open,
|
|
524
|
-
onOpenChange: setOpen,
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
onSelect: handleSelect
|
|
557
|
-
}) })
|
|
558
|
-
})
|
|
559
|
-
}),
|
|
560
|
-
/* @__PURE__ */ jsx(Popover.Arrow, {})
|
|
561
|
-
]
|
|
562
|
-
}) }),
|
|
563
|
-
/* @__PURE__ */ jsx("div", {
|
|
564
|
-
className: "contents",
|
|
565
|
-
ref: setRoot,
|
|
566
|
-
children
|
|
567
|
-
})
|
|
568
|
-
]
|
|
531
|
+
onOpenChange: ({ open }) => setOpen(open),
|
|
532
|
+
positioning: {
|
|
533
|
+
...VirtualAnchor.virtualAnchor(triggerRef),
|
|
534
|
+
placement: "bottom-start"
|
|
535
|
+
},
|
|
536
|
+
autoFocus: !!search,
|
|
537
|
+
onEscapeKeyDown: () => {
|
|
538
|
+
const currentView = getViewRef.current?.();
|
|
539
|
+
if (currentView) onCancel?.({ view: currentView });
|
|
540
|
+
},
|
|
541
|
+
children: [/* @__PURE__ */ jsxs(Popover.Content, {
|
|
542
|
+
classNames: !search && !menuGroups.length ? "hidden" : void 0,
|
|
543
|
+
style: { maxBlockSize: 36 * numItems + 10 + (search ? 36 : 0) },
|
|
544
|
+
children: [search && /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsx(Input.Root, {
|
|
545
|
+
ref: searchInputRef,
|
|
546
|
+
variant: "subdued",
|
|
547
|
+
classNames: "shrink-0 mb-1",
|
|
548
|
+
value: query,
|
|
549
|
+
placeholder: searchPlaceholder,
|
|
550
|
+
"aria-label": searchPlaceholder ?? t("search.label"),
|
|
551
|
+
onChange: (event) => onQueryChange?.(event.target.value),
|
|
552
|
+
onKeyDown: handleSearchKeyDown
|
|
553
|
+
}) }), /* @__PURE__ */ jsx(Popover.Body, { children: /* @__PURE__ */ jsx(Menu, {
|
|
554
|
+
groups: menuGroups,
|
|
555
|
+
currentItem,
|
|
556
|
+
onSelect: handleSelect
|
|
557
|
+
}) })]
|
|
558
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
559
|
+
className: "contents",
|
|
560
|
+
ref: setRoot,
|
|
561
|
+
children
|
|
562
|
+
})]
|
|
569
563
|
});
|
|
570
564
|
};
|
|
571
|
-
var Menu
|
|
572
|
-
const { tx } = useThemeContext();
|
|
565
|
+
var Menu = ({ groups, currentItem, onSelect }) => {
|
|
573
566
|
return /* @__PURE__ */ jsx("ul", { children: groups.map((group, index) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MenuGroup, {
|
|
574
567
|
group,
|
|
575
568
|
currentItem,
|
|
576
569
|
onSelect
|
|
577
|
-
}), index < groups.length - 1 && /* @__PURE__ */ jsx(
|
|
570
|
+
}), index < groups.length - 1 && /* @__PURE__ */ jsx(Layout.Separator, {})] }, group.id)) });
|
|
578
571
|
};
|
|
579
572
|
var MenuGroup = ({ group, currentItem, onSelect }) => {
|
|
580
|
-
const {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
children:
|
|
573
|
+
const { t } = Hooks.useTranslation();
|
|
574
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [group.label && /* @__PURE__ */ jsx(Typography.Text, {
|
|
575
|
+
tone: "muted",
|
|
576
|
+
classNames: "px-2",
|
|
577
|
+
children: Theme.toLocalizedString(group.label, t)
|
|
585
578
|
}), group.items.map((item) => /* @__PURE__ */ jsx(MenuItem, {
|
|
586
579
|
item,
|
|
587
580
|
current: currentItem === item.id,
|
|
@@ -589,8 +582,7 @@ var MenuGroup = ({ group, currentItem, onSelect }) => {
|
|
|
589
582
|
}, item.id))] });
|
|
590
583
|
};
|
|
591
584
|
var MenuItem = ({ item, current, onSelect }) => {
|
|
592
|
-
const {
|
|
593
|
-
const { t } = useTranslation();
|
|
585
|
+
const { t } = Hooks.useTranslation();
|
|
594
586
|
const listRef = useRef(null);
|
|
595
587
|
useEffect(() => {
|
|
596
588
|
if (current && listRef.current) listRef.current.scrollIntoView({
|
|
@@ -601,11 +593,12 @@ var MenuItem = ({ item, current, onSelect }) => {
|
|
|
601
593
|
const handleSelect = useCallback(() => onSelect?.(item), [item, onSelect]);
|
|
602
594
|
return /* @__PURE__ */ jsxs("li", {
|
|
603
595
|
ref: listRef,
|
|
604
|
-
className:
|
|
596
|
+
className: "dx-menu-item",
|
|
597
|
+
"data-highlighted": current ? "" : void 0,
|
|
605
598
|
onClick: handleSelect,
|
|
606
|
-
children: [item.icon && /* @__PURE__ */ jsx(Icon, { icon: item.icon }), /* @__PURE__ */ jsx("span", {
|
|
607
|
-
className: "
|
|
608
|
-
children: toLocalizedString(item.label, t)
|
|
599
|
+
children: [item.icon && /* @__PURE__ */ jsx(Icon.Icon, { icon: item.icon }), /* @__PURE__ */ jsx("span", {
|
|
600
|
+
className: "dx-menu-item-text",
|
|
601
|
+
children: Theme.toLocalizedString(item.label, t)
|
|
609
602
|
})]
|
|
610
603
|
});
|
|
611
604
|
};
|
|
@@ -865,6 +858,7 @@ var addFormatting = (state, getView) => (builder) => {
|
|
|
865
858
|
const checked = !!formatting[type];
|
|
866
859
|
group.action(type, {
|
|
867
860
|
label: [`formatting.${type}.label`, { ns: translationKey }],
|
|
861
|
+
testId: `editor.toolbar.${type}`,
|
|
868
862
|
checked,
|
|
869
863
|
icon
|
|
870
864
|
}, () => {
|
|
@@ -1001,6 +995,7 @@ var addViewMode = (state, onViewModeChange, items = defaultViewModeItems) => (bu
|
|
|
1001
995
|
const value = state.viewMode ?? "source";
|
|
1002
996
|
builder.group("viewMode", {
|
|
1003
997
|
label: ["view-mode.label", { ns: translationKey }],
|
|
998
|
+
testId: "editor.toolbar.viewMode",
|
|
1004
999
|
icon: "ph--eye--regular",
|
|
1005
1000
|
iconOnly: true,
|
|
1006
1001
|
variant: "dropdownMenu",
|
|
@@ -1020,20 +1015,13 @@ var addViewMode = (state, onViewModeChange, items = defaultViewModeItems) => (bu
|
|
|
1020
1015
|
};
|
|
1021
1016
|
//#endregion
|
|
1022
1017
|
//#region src/components/EditorToolbar/EditorToolbar.tsx
|
|
1023
|
-
var SECTION_ROLE = "org.dxos.role.section";
|
|
1024
1018
|
var EditorToolbar$1 = memo(({ classNames, role, attendableId, onAction, ...props }) => {
|
|
1025
1019
|
const menuActions = useMarkdownMenuActions(props);
|
|
1026
|
-
return /* @__PURE__ */ jsx(
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
onAction,
|
|
1032
|
-
children: /* @__PURE__ */ jsx(Menu.Toolbar, {
|
|
1033
|
-
classNames,
|
|
1034
|
-
children: /* @__PURE__ */ jsx(Menu.Items, {})
|
|
1035
|
-
})
|
|
1036
|
-
})
|
|
1020
|
+
return /* @__PURE__ */ jsx(ActionToolbar, {
|
|
1021
|
+
...menuActions,
|
|
1022
|
+
attendableId,
|
|
1023
|
+
onAction,
|
|
1024
|
+
classNames
|
|
1037
1025
|
});
|
|
1038
1026
|
});
|
|
1039
1027
|
var useMarkdownMenuActions = ({ state, getView, customActions, ...features }) => {
|
|
@@ -1067,7 +1055,7 @@ var createMarkdownActions = ({ state, getView, customActions, ...features }) =>
|
|
|
1067
1055
|
//#region src/hooks/useBasicMarkdownExtensions.ts
|
|
1068
1056
|
/**
|
|
1069
1057
|
* Returns the standard CodeMirror extension stack for an inline markdown editor:
|
|
1070
|
-
* basic editor behaviors, themed syntax highlighting (theme mode read from {@link
|
|
1058
|
+
* basic editor behaviors, themed syntax highlighting (theme mode read from {@link useThemeMode}),
|
|
1071
1059
|
* markdown parsing, and visual decorations.
|
|
1072
1060
|
*
|
|
1073
1061
|
* Used by surfaces such as `AgentProperties` and `MagazineProperties` to render the
|
|
@@ -1077,7 +1065,7 @@ var createMarkdownActions = ({ state, getView, customActions, ...features }) =>
|
|
|
1077
1065
|
* so callers passing fresh option literals each render still hit the cache.
|
|
1078
1066
|
*/
|
|
1079
1067
|
var useBasicMarkdownExtensions = ({ placeholder, decorate = true, readonly = false, extensions } = {}) => {
|
|
1080
|
-
const
|
|
1068
|
+
const themeMode = Hooks.useThemeMode();
|
|
1081
1069
|
return useMemo(() => [
|
|
1082
1070
|
createBasicExtensions({
|
|
1083
1071
|
placeholder,
|
|
@@ -1106,11 +1094,11 @@ var instanceCount = 0;
|
|
|
1106
1094
|
* Creates codemirror text editor.
|
|
1107
1095
|
*/
|
|
1108
1096
|
var useTextEditor = (props = {}, deps = []) => {
|
|
1109
|
-
const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, selectionEnd, debug } = useMemo(() => getProviderValue(props), deps ?? []);
|
|
1097
|
+
const { id, doc, initialValue, extensions, autoFocus, scrollTo, scrollOffset, selection, selectionEnd, debug } = useMemo(() => getProviderValue(props), deps ?? []);
|
|
1110
1098
|
const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
|
|
1111
1099
|
const [view, setView] = useState(null);
|
|
1112
1100
|
const parentRef = useRef(null);
|
|
1113
|
-
|
|
1101
|
+
useLayoutEffect(() => {
|
|
1114
1102
|
let view = null;
|
|
1115
1103
|
if (parentRef.current) {
|
|
1116
1104
|
log("create", {
|
|
@@ -1120,7 +1108,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
1120
1108
|
}, {
|
|
1121
1109
|
"~LogMeta": "~LogMeta",
|
|
1122
1110
|
F: __dxlog_file$1,
|
|
1123
|
-
L:
|
|
1111
|
+
L: 82,
|
|
1124
1112
|
S: void 0
|
|
1125
1113
|
});
|
|
1126
1114
|
const length = (doc ?? initialValue)?.length ?? 0;
|
|
@@ -1133,20 +1121,23 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
1133
1121
|
extensions: [
|
|
1134
1122
|
id && documentId.of(id),
|
|
1135
1123
|
extensions,
|
|
1136
|
-
EditorView.exceptionSink.of((err) => {
|
|
1124
|
+
EditorView$1.exceptionSink.of((err) => {
|
|
1137
1125
|
log.catch(err, void 0, {
|
|
1138
1126
|
"~LogMeta": "~LogMeta",
|
|
1139
1127
|
F: __dxlog_file$1,
|
|
1140
|
-
L:
|
|
1128
|
+
L: 103,
|
|
1141
1129
|
S: void 0
|
|
1142
1130
|
});
|
|
1143
1131
|
})
|
|
1144
1132
|
].filter(isTruthy)
|
|
1145
1133
|
});
|
|
1146
|
-
view = new EditorView({
|
|
1134
|
+
view = new EditorView$1({
|
|
1147
1135
|
parent: parentRef.current,
|
|
1148
1136
|
state,
|
|
1149
|
-
scrollTo: scrollTo ? EditorView.scrollIntoView(scrollTo, {
|
|
1137
|
+
scrollTo: scrollTo != null ? EditorView$1.scrollIntoView(scrollTo, {
|
|
1138
|
+
y: "start",
|
|
1139
|
+
yMargin: 0
|
|
1140
|
+
}) : void 0,
|
|
1150
1141
|
dispatchTransactions: debug ? debugDispatcher : void 0
|
|
1151
1142
|
});
|
|
1152
1143
|
if (selectionEnd && !initialSelection) {
|
|
@@ -1159,7 +1150,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
1159
1150
|
log("destroy", { id }, {
|
|
1160
1151
|
"~LogMeta": "~LogMeta",
|
|
1161
1152
|
F: __dxlog_file$1,
|
|
1162
|
-
L:
|
|
1153
|
+
L: 127,
|
|
1163
1154
|
S: void 0
|
|
1164
1155
|
});
|
|
1165
1156
|
view?.destroy();
|
|
@@ -1167,7 +1158,7 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
1167
1158
|
}, deps);
|
|
1168
1159
|
useEffect(() => {
|
|
1169
1160
|
if (view) {
|
|
1170
|
-
if (scrollTo || selection) {
|
|
1161
|
+
if (scrollTo != null || selection) {
|
|
1171
1162
|
if (selection && selection.anchor > view.state.doc.length) {
|
|
1172
1163
|
log.warn("invalid selection", {
|
|
1173
1164
|
length: view.state.doc.length,
|
|
@@ -1176,24 +1167,26 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
1176
1167
|
}, {
|
|
1177
1168
|
"~LogMeta": "~LogMeta",
|
|
1178
1169
|
F: __dxlog_file$1,
|
|
1179
|
-
L:
|
|
1170
|
+
L: 136,
|
|
1180
1171
|
S: void 0
|
|
1181
1172
|
});
|
|
1182
1173
|
return;
|
|
1183
1174
|
}
|
|
1184
|
-
view
|
|
1175
|
+
restoreEditorState(view, {
|
|
1185
1176
|
scrollTo,
|
|
1177
|
+
scrollOffset,
|
|
1186
1178
|
selection
|
|
1187
|
-
})
|
|
1179
|
+
});
|
|
1188
1180
|
}
|
|
1189
1181
|
}
|
|
1190
1182
|
}, [
|
|
1191
1183
|
view,
|
|
1192
1184
|
scrollTo,
|
|
1185
|
+
scrollOffset,
|
|
1193
1186
|
selection
|
|
1194
1187
|
]);
|
|
1195
1188
|
useEffect(() => {
|
|
1196
|
-
if (view && autoFocus) view.focus();
|
|
1189
|
+
if (view && autoFocus && !view.dom.ownerDocument.activeElement?.closest("[role=\"menu\"], [role=\"listbox\"]")) view.focus();
|
|
1197
1190
|
}, [autoFocus, view]);
|
|
1198
1191
|
return {
|
|
1199
1192
|
parentRef,
|
|
@@ -1221,14 +1214,14 @@ var useTextEditor = (props = {}, deps = []) => {
|
|
|
1221
1214
|
* Minimal text editor.
|
|
1222
1215
|
* NOTE: This shouold not be used with the automerge extension.
|
|
1223
1216
|
*/
|
|
1224
|
-
var EditorView
|
|
1217
|
+
var EditorView = forwardRef(({ classNames, id, extensions, selectionEnd, focusable = true, value, onChange, ...props }, forwardedRef) => {
|
|
1225
1218
|
const onChangeRef = useRef(onChange);
|
|
1226
1219
|
onChangeRef.current = onChange;
|
|
1227
1220
|
const { parentRef, focusAttributes, view } = useTextEditor(() => ({
|
|
1228
1221
|
id,
|
|
1229
1222
|
initialValue: value,
|
|
1230
1223
|
selectionEnd,
|
|
1231
|
-
extensions: [extensions ?? [], EditorView.updateListener.of(({ view, docChanged, transactions }) => {
|
|
1224
|
+
extensions: [extensions ?? [], EditorView$1.updateListener.of(({ view, docChanged, transactions }) => {
|
|
1232
1225
|
if (!transactions.some((tr) => tr.annotation(Transaction.userEvent) === initialSync.value) && docChanged) onChangeRef.current?.(view.state.doc.toString());
|
|
1233
1226
|
})],
|
|
1234
1227
|
...props
|
|
@@ -1245,14 +1238,13 @@ var EditorView$2 = forwardRef(({ classNames, id, extensions, selectionEnd, focus
|
|
|
1245
1238
|
const next = value;
|
|
1246
1239
|
if (view.state.doc.toString() === next) return;
|
|
1247
1240
|
requestAnimationFrame(() => {
|
|
1248
|
-
|
|
1241
|
+
const current = view.state.doc.toString();
|
|
1242
|
+
if (current === next) return;
|
|
1243
|
+
const changes = computeDocChanges(current, next);
|
|
1244
|
+
if (changes.length === 0) return;
|
|
1249
1245
|
view.dispatch({
|
|
1250
1246
|
annotations: initialSync,
|
|
1251
|
-
changes
|
|
1252
|
-
from: 0,
|
|
1253
|
-
to: view.state.doc.length,
|
|
1254
|
-
insert: next
|
|
1255
|
-
}],
|
|
1247
|
+
changes,
|
|
1256
1248
|
selection: selectionEnd ? { anchor: next.length } : void 0
|
|
1257
1249
|
});
|
|
1258
1250
|
if (selectionEnd) view.focus();
|
|
@@ -1315,16 +1307,16 @@ var EDITOR_VIEW_NAME = "Editor.View";
|
|
|
1315
1307
|
* View component that renders the actual CodeMirror editor.
|
|
1316
1308
|
* Automatically registers the editor controller with the context.
|
|
1317
1309
|
*/
|
|
1318
|
-
var EditorView$
|
|
1310
|
+
var EditorView$2 = ({ extensions: providedExtensions, ...props }) => {
|
|
1319
1311
|
const { extensions: additionalExtensions = [], setController } = useEditorContext(EDITOR_VIEW_NAME);
|
|
1320
1312
|
const extensions = useMemo(() => [additionalExtensions, providedExtensions].filter(isNonNullable).flat(), [providedExtensions, additionalExtensions]);
|
|
1321
|
-
return /* @__PURE__ */ jsx(EditorView
|
|
1313
|
+
return /* @__PURE__ */ jsx(EditorView, {
|
|
1322
1314
|
...props,
|
|
1323
1315
|
extensions,
|
|
1324
1316
|
ref: setController
|
|
1325
1317
|
});
|
|
1326
1318
|
};
|
|
1327
|
-
EditorView$
|
|
1319
|
+
EditorView$2.displayName = EDITOR_VIEW_NAME;
|
|
1328
1320
|
var EDITOR_TOOLBAR_NAME = "Editor.Toolbar";
|
|
1329
1321
|
/**
|
|
1330
1322
|
* Toolbar component that provides editor formatting and control actions.
|
|
@@ -1336,7 +1328,7 @@ var EditorToolbar = (props) => {
|
|
|
1336
1328
|
invariant(controller?.view, void 0, {
|
|
1337
1329
|
"~LogMeta": "~LogMeta",
|
|
1338
1330
|
F: __dxlog_file,
|
|
1339
|
-
L:
|
|
1331
|
+
L: 159,
|
|
1340
1332
|
S: void 0,
|
|
1341
1333
|
A: ["controller?.view", ""]
|
|
1342
1334
|
});
|
|
@@ -1356,7 +1348,13 @@ var EDITOR_BLOCKS_NAME = "Editor.Blocks";
|
|
|
1356
1348
|
*/
|
|
1357
1349
|
var EditorBlocks = () => {
|
|
1358
1350
|
const { widgets = [] } = useEditorContext(EDITOR_BLOCKS_NAME);
|
|
1359
|
-
return /* @__PURE__ */ jsx(Fragment$1, { children: widgets.map(({ id, root, Component, props }) => /* @__PURE__ */ jsx("div", {
|
|
1351
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: widgets.map(({ id, root, Component, props }) => /* @__PURE__ */ jsx("div", {
|
|
1352
|
+
"data-testid": "editor.blocks.portal",
|
|
1353
|
+
children: createPortal(/* @__PURE__ */ jsx(Suspense, {
|
|
1354
|
+
fallback: null,
|
|
1355
|
+
children: /* @__PURE__ */ jsx(Component, { ...props })
|
|
1356
|
+
}), root)
|
|
1357
|
+
}, id)) });
|
|
1360
1358
|
};
|
|
1361
1359
|
EditorBlocks.displayName = EDITOR_BLOCKS_NAME;
|
|
1362
1360
|
var EDITOR_DIAGNOSTICS_NAME = "Editor.Diagnostics";
|
|
@@ -1392,11 +1390,11 @@ var EditorDiagnostics = ({ classNames }) => {
|
|
|
1392
1390
|
const head = doc.lineAt(main.head);
|
|
1393
1391
|
const extensionCount = countExtensions(extensions);
|
|
1394
1392
|
const item = (label, value) => /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsxs("span", {
|
|
1395
|
-
className: "text-
|
|
1393
|
+
className: "text-fg-subtle",
|
|
1396
1394
|
children: [label, " "]
|
|
1397
1395
|
}), value] });
|
|
1398
1396
|
return /* @__PURE__ */ jsxs("div", {
|
|
1399
|
-
className: mx("flex flex-wrap gap-x-4 gap-y-0.5 border-bs border-separator px-2 py-1 text-xs font-mono text-
|
|
1397
|
+
className: mx("flex flex-wrap gap-x-4 gap-y-0.5 border-bs border-separator px-2 py-1 text-xs font-mono text-fg-muted", classNames),
|
|
1400
1398
|
"data-testid": "editor.diagnostics",
|
|
1401
1399
|
children: [
|
|
1402
1400
|
item("chars", doc.length),
|
|
@@ -1414,7 +1412,7 @@ var Editor = {
|
|
|
1414
1412
|
Root: EditorRoot,
|
|
1415
1413
|
Toolbar: EditorToolbar,
|
|
1416
1414
|
Content: EditorContent,
|
|
1417
|
-
View: EditorView$
|
|
1415
|
+
View: EditorView$2,
|
|
1418
1416
|
Blocks: EditorBlocks,
|
|
1419
1417
|
Diagnostics: EditorDiagnostics
|
|
1420
1418
|
};
|
|
@@ -1432,13 +1430,21 @@ var EditorPreviewProvider = ({ children, onLookup }) => {
|
|
|
1432
1430
|
const triggerRef = useRef(null);
|
|
1433
1431
|
const [value, setValue] = useState({});
|
|
1434
1432
|
const [open, setOpen] = useState(false);
|
|
1433
|
+
const activationRef = useRef(0);
|
|
1435
1434
|
const handleActivate = useCallback((event) => {
|
|
1436
|
-
|
|
1435
|
+
if (event.state === false) {
|
|
1436
|
+
if (event.trigger !== triggerRef.current) return;
|
|
1437
|
+
activationRef.current++;
|
|
1438
|
+
setOpen(false);
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
const sequence = ++activationRef.current;
|
|
1442
|
+
const { eid, label, trigger } = event;
|
|
1437
1443
|
setValue((value) => ({
|
|
1438
1444
|
...value,
|
|
1439
1445
|
link: {
|
|
1440
1446
|
label,
|
|
1441
|
-
|
|
1447
|
+
eid
|
|
1442
1448
|
},
|
|
1443
1449
|
pending: true
|
|
1444
1450
|
}));
|
|
@@ -1446,13 +1452,20 @@ var EditorPreviewProvider = ({ children, onLookup }) => {
|
|
|
1446
1452
|
queueMicrotask(() => setOpen(true));
|
|
1447
1453
|
onLookup?.({
|
|
1448
1454
|
label,
|
|
1449
|
-
|
|
1450
|
-
}).then((target) =>
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
+
eid
|
|
1456
|
+
}).then((target) => {
|
|
1457
|
+
if (sequence !== activationRef.current) return;
|
|
1458
|
+
setValue((value) => ({
|
|
1459
|
+
...value,
|
|
1460
|
+
target: target ?? void 0,
|
|
1461
|
+
pending: false
|
|
1462
|
+
}));
|
|
1463
|
+
});
|
|
1455
1464
|
}, [onLookup]);
|
|
1465
|
+
const handleOpenChange = useCallback((next) => {
|
|
1466
|
+
if (!next) activationRef.current++;
|
|
1467
|
+
setOpen(next);
|
|
1468
|
+
}, []);
|
|
1456
1469
|
const [root, setRoot] = useState(null);
|
|
1457
1470
|
useEffect(() => {
|
|
1458
1471
|
if (!root || !handleActivate) return;
|
|
@@ -1465,18 +1478,20 @@ var EditorPreviewProvider = ({ children, onLookup }) => {
|
|
|
1465
1478
|
pending: value.pending,
|
|
1466
1479
|
link: value.link,
|
|
1467
1480
|
target: value.target,
|
|
1468
|
-
children: /* @__PURE__ */
|
|
1481
|
+
children: /* @__PURE__ */ jsx(Popover.Root, {
|
|
1469
1482
|
open,
|
|
1470
|
-
onOpenChange:
|
|
1471
|
-
|
|
1483
|
+
onOpenChange: ({ open }) => handleOpenChange(open),
|
|
1484
|
+
positioning: VirtualAnchor.virtualAnchor(triggerRef),
|
|
1485
|
+
autoFocus: false,
|
|
1486
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1472
1487
|
className: "contents",
|
|
1473
1488
|
ref: setRoot,
|
|
1474
1489
|
children
|
|
1475
|
-
})
|
|
1490
|
+
})
|
|
1476
1491
|
})
|
|
1477
1492
|
});
|
|
1478
1493
|
};
|
|
1479
1494
|
//#endregion
|
|
1480
|
-
export { Editor, EditorMenuProvider, EditorPreviewProvider, addViewMode, createEditorController, createMenuGroup, defaultViewModeItems, filterMenuGroups, formattingCommands, getMenuItem, getNextMenuItem, getPreviousMenuItem, linkSlashCommands, noopController, popover, popoverRangeEffect, popoverStateField, useBasicMarkdownExtensions, useEditorContext, useEditorMenu, useEditorPreview, useTextEditor };
|
|
1495
|
+
export { Editor, EditorMenuProvider, EditorPreviewProvider, EditorView as TextEditor, addViewMode, createEditorController, createMenuGroup, defaultViewModeItems, filterMenuGroups, formattingCommands, getMenuItem, getNextMenuItem, getPreviousMenuItem, linkSlashCommands, noopController, popover, popoverRangeEffect, popoverStateField, useBasicMarkdownExtensions, useEditorContext, useEditorMenu, useEditorPreview, useTextEditor };
|
|
1481
1496
|
|
|
1482
1497
|
//# sourceMappingURL=index.mjs.map
|