@dxos/react-ui-editor 0.4.6-main.3500f01 → 0.4.6-main.3724cc4

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