@dxos/react-ui-editor 0.8.3-main.672df60 → 0.8.3-main.7f5a14c
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 +868 -260
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +911 -297
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +868 -260
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/EditorToolbar/util.d.ts +2 -2
- package/dist/types/src/components/Popover/CommandMenu.d.ts +34 -0
- package/dist/types/src/components/Popover/CommandMenu.d.ts.map +1 -0
- package/dist/types/src/components/Popover/RefPopover.d.ts +19 -6
- package/dist/types/src/components/Popover/RefPopover.d.ts.map +1 -1
- package/dist/types/src/components/Popover/index.d.ts +1 -0
- package/dist/types/src/components/Popover/index.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/command/menu.d.ts +40 -0
- package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +1 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/placeholder.d.ts +4 -0
- package/dist/types/src/extensions/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +8 -9
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/CommandMenu.stories.d.ts +12 -0
- package/dist/types/src/stories/CommandMenu.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
- package/package.json +31 -28
- package/src/components/Popover/CommandMenu.tsx +279 -0
- package/src/components/Popover/RefPopover.tsx +44 -22
- package/src/components/Popover/index.ts +1 -0
- package/src/defaults.ts +1 -0
- package/src/extensions/command/menu.ts +306 -4
- package/src/extensions/factories.ts +4 -1
- package/src/extensions/index.ts +1 -0
- package/src/extensions/outliner/outliner.ts +0 -3
- package/src/extensions/placeholder.ts +82 -0
- package/src/extensions/preview/preview.ts +3 -6
- package/src/hooks/useTextEditor.ts +11 -12
- package/src/stories/CommandMenu.stories.tsx +143 -0
- package/src/stories/Preview.stories.tsx +32 -30
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RefPopover.d.ts","sourceRoot":"","sources":["../../../../../src/components/Popover/RefPopover.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,
|
1
|
+
{"version":3,"file":"RefPopover.d.ts","sourceRoot":"","sources":["../../../../../src/components/Popover/RefPopover.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EACZ,KAAK,iBAAiB,EAOvB,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAInG,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAChD,CAAC,CAAC;AAEH,eAAO,MAAM,UAAU;YANb,OAAO;WACR,OAAO;mBACC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI;iBACzB,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI;;;yCAsB/C,CAAC;AAGF,KAAK,eAAe,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAGtG,QAAA,MAAkC,aAAa;UAHR,cAAc;YAAU,iBAAiB;aAAW,OAAO;EAGA,CAAC;AAEnG,KAAK,oBAAoB,GAAG,iBAAiB,CAAC;IAAE,QAAQ,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC,CAAC;AAE5E,QAAA,MAAM,eAAe,GAAI,wBAAwB,oBAAoB,sBAiCpE,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAE1C,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/Popover/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC"}
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/Popover/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/defaults.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,oDAAoD,CAAC;AAE7E,eAAO,MAAM,WAAW,EAAE,sBAAsB,CAAC,OAAO,CAOvD,CAAC;AAEF,eAAO,MAAM,YAAY,
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/defaults.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,oDAAoD,CAAC;AAE7E,eAAO,MAAM,WAAW,EAAE,sBAAsB,CAAC,OAAO,CAOvD,CAAC;AAEF,eAAO,MAAM,YAAY,uCAKvB,CAAC;AAEH,eAAO,MAAM,eAAe,uCAI1B,CAAC;AAEH,eAAO,MAAM,uBAAuB,sIACiG,CAAC;AAEtI,eAAO,MAAM,gCAAgC,GAAI,OAAO,MAAM,WAI3D,CAAC;AAEJ,eAAO,MAAM,iCAAiC,GAAI,OAAO,MAAM,WAI5D,CAAC"}
|
@@ -1,7 +1,47 @@
|
|
1
|
+
import { StateField } from '@codemirror/state';
|
2
|
+
import { EditorView } from '@codemirror/view';
|
3
|
+
import { type RefObject } from 'react';
|
4
|
+
import { type DxRefTag, type DxRefTagActivate } from '@dxos/lit-ui';
|
5
|
+
import { type MaybePromise } from '@dxos/util';
|
6
|
+
import { type CommandMenuGroup, type CommandMenuItem } from '../../components';
|
7
|
+
import { type Range } from '../../types';
|
8
|
+
import { multilinePlaceholder } from '../placeholder';
|
1
9
|
export type FloatingMenuOptions = {
|
2
10
|
icon?: string;
|
3
11
|
height?: number;
|
4
12
|
padding?: number;
|
5
13
|
};
|
6
14
|
export declare const floatingMenu: (options?: FloatingMenuOptions) => import("@codemirror/state").Extension[];
|
15
|
+
type CommandState = {
|
16
|
+
trigger: string;
|
17
|
+
range: Range;
|
18
|
+
};
|
19
|
+
export declare const commandRangeEffect: import("@codemirror/state").StateEffectType<CommandState | null>;
|
20
|
+
export type CommandMenuOptions = {
|
21
|
+
trigger: string | string[];
|
22
|
+
placeholder?: Parameters<typeof multilinePlaceholder>[0];
|
23
|
+
onArrowDown?: () => void;
|
24
|
+
onArrowUp?: () => void;
|
25
|
+
onDeactivate?: () => void;
|
26
|
+
onEnter?: () => void;
|
27
|
+
onTextChange?: (trigger: string, text: string) => void;
|
28
|
+
};
|
29
|
+
export declare const commandMenu: (options: CommandMenuOptions) => (import("@codemirror/state").Extension | StateField<CommandState | null>)[];
|
30
|
+
export type UseCommandMenuOptions = {
|
31
|
+
viewRef: RefObject<EditorView | undefined>;
|
32
|
+
trigger: string | string[];
|
33
|
+
placeholder?: Parameters<typeof multilinePlaceholder>[0];
|
34
|
+
getGroups: (trigger: string, query?: string) => MaybePromise<CommandMenuGroup[]>;
|
35
|
+
};
|
36
|
+
export declare const useCommandMenu: ({ viewRef, trigger, placeholder, getGroups }: UseCommandMenuOptions) => {
|
37
|
+
commandMenu: (import("@codemirror/state").Extension | StateField<CommandState | null>)[];
|
38
|
+
currentItem: string | undefined;
|
39
|
+
groupsRef: import("react").MutableRefObject<CommandMenuGroup[]>;
|
40
|
+
ref: import("react").MutableRefObject<DxRefTag | null>;
|
41
|
+
open: boolean;
|
42
|
+
onActivate: (event: DxRefTagActivate) => Promise<void>;
|
43
|
+
onOpenChange: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
44
|
+
onSelect: (item: CommandMenuItem) => void;
|
45
|
+
};
|
46
|
+
export {};
|
7
47
|
//# sourceMappingURL=menu.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/command/menu.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/command/menu.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,UAAU,EAAqB,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAuE,MAAM,kBAAkB,CAAC;AACnH,OAAO,EAAE,KAAK,SAAS,EAA0C,MAAM,OAAO,CAAC;AAG/E,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAyC,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACtH,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,UAAS,mBAAwB,4CAqH7D,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAGF,eAAO,MAAM,kBAAkB,kEAA4C,CAAC;AAkB5E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,SAAS,kBAAkB,gFA2JtD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC,gBAAgB,EAAE,CAAC,CAAC;CAClF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,8CAA8C,qBAAqB;;;;;;wBAwBhF,gBAAgB;;qBAeQ,eAAe;CA2DxD,CAAC"}
|
@@ -24,6 +24,7 @@ export type BasicExtensionsOptions = {
|
|
24
24
|
lineNumbers?: boolean;
|
25
25
|
/** If false then do not set a max-width or side margin on the editor. */
|
26
26
|
lineWrapping?: boolean;
|
27
|
+
monospace?: boolean;
|
27
28
|
placeholder?: string;
|
28
29
|
/** If true user cannot edit the text, but they can still select and copy it. */
|
29
30
|
readOnly?: boolean;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/extensions/factories.ts"],"names":[],"mappings":"AAQA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAmBhE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
1
|
+
{"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/extensions/factories.ts"],"names":[],"mappings":"AAQA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAmBhE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQhD,OAAO,EAAE,KAAK,WAAW,EAAgB,MAAM,WAAW,CAAC;AAM3D,eAAO,MAAM,cAAc,WAA4E,CAAC;AAExG;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,UAAU,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAqBF,eAAO,MAAM,qBAAqB,GAAI,SAAS,sBAAsB,KAAG,SAgDvE,CAAC;AAMF,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE;YACP,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,MAAM,CAAC,EAAE;YACP,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,OAAO,CAAC,EAAE;YACR,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH,CAAC;CACH,CAAC;AAQF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,iFAKnC,sBAA2B,KAAG,SAmBhC,CAAC;AAMF,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC5B,CAAC;AAGF,eAAO,MAAM,oBAAoB,GAAI,CAAC,EAAE,+BAA+B,mBAAmB,CAAC,CAAC,CAAC,KAAG,SAAS,EA2BxG,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"placeholder.d.ts","sourceRoot":"","sources":["../../../../src/extensions/placeholder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAc,UAAU,EAA0B,MAAM,kBAAkB,CAAC;AA2ClF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,CAAC,CAAC,IAAI,EAAE,UAAU,KAAK,WAAW,CAAC,GAAG,SAAS,CA+BnH"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/preview/preview.ts"],"names":[],"mappings":"AAIA,OAAO,8BAA8B,CAAC;AAGtC,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;CAC3B,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAGN,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEpG,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;AAEnE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,CAAC,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,UAAS,cAAmB,KAAG,
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/preview/preview.ts"],"names":[],"mappings":"AAIA,OAAO,8BAA8B,CAAC;AAGtC,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;CAC3B,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAGN,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEpG,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;AAEnE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,CAAC,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,UAAS,cAAmB,KAAG,SAqBtD,CAAC"}
|
@@ -4,14 +4,6 @@ import { type TabsterTypes } from '@fluentui/react-tabster';
|
|
4
4
|
import { type DependencyList, type KeyboardEventHandler, type RefObject } from 'react';
|
5
5
|
import { type MaybeProvider } from '@dxos/util';
|
6
6
|
import { type EditorSelection } from '../extensions';
|
7
|
-
export type UseTextEditor = {
|
8
|
-
parentRef: RefObject<HTMLDivElement>;
|
9
|
-
view?: EditorView;
|
10
|
-
focusAttributes?: TabsterTypes.TabsterDOMAttribute & {
|
11
|
-
tabIndex: 0;
|
12
|
-
onKeyUp: KeyboardEventHandler<HTMLDivElement>;
|
13
|
-
};
|
14
|
-
};
|
15
7
|
export type CursorInfo = {
|
16
8
|
from: number;
|
17
9
|
to: number;
|
@@ -20,11 +12,18 @@ export type CursorInfo = {
|
|
20
12
|
length: number;
|
21
13
|
after?: string;
|
22
14
|
};
|
15
|
+
export type UseTextEditor = {
|
16
|
+
parentRef: RefObject<HTMLDivElement>;
|
17
|
+
view?: EditorView;
|
18
|
+
focusAttributes?: TabsterTypes.TabsterDOMAttribute & {
|
19
|
+
tabIndex: 0;
|
20
|
+
onKeyUp: KeyboardEventHandler<HTMLDivElement>;
|
21
|
+
};
|
22
|
+
};
|
23
23
|
export type UseTextEditorProps = Pick<EditorStateConfig, 'extensions'> & {
|
24
24
|
id?: string;
|
25
25
|
doc?: Text;
|
26
26
|
initialValue?: string;
|
27
|
-
className?: string;
|
28
27
|
autoFocus?: boolean;
|
29
28
|
scrollTo?: number;
|
30
29
|
selection?: EditorSelection;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useTextEditor.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextEditor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,iBAAiB,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9E,OAAO,EAAE,KAAK,eAAe,EAA6D,MAAM,eAAe,CAAC;
|
1
|
+
{"version":3,"file":"useTextEditor.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextEditor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,iBAAiB,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE9E,OAAO,EAAE,KAAK,eAAe,EAA6D,MAAM,eAAe,CAAC;AAKhH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAE1B,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC,mBAAmB,GAAG;QACnD,QAAQ,EAAE,CAAC,CAAC;QACZ,OAAO,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAAG;IACvE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,GACxB,QAAO,aAAa,CAAC,kBAAkB,CAAM,EAC7C,OAAM,cAAmB,KACxB,aA+HF,CAAC"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import '@dxos-theme';
|
2
|
+
import { type StoryObj } from '@storybook/react';
|
3
|
+
import { type Meta } from '@dxos/storybook-utils';
|
4
|
+
import { type UseCommandMenuOptions } from '../extensions';
|
5
|
+
type Args = Omit<UseCommandMenuOptions, 'viewRef'> & {
|
6
|
+
text: string;
|
7
|
+
};
|
8
|
+
declare const meta: Meta<Args>;
|
9
|
+
export default meta;
|
10
|
+
export declare const Slash: StoryObj<Args>;
|
11
|
+
export declare const Link: StoryObj<Args>;
|
12
|
+
//# sourceMappingURL=CommandMenu.stories.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"CommandMenu.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/CommandMenu.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAOjD,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAczE,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK3E,KAAK,IAAI,GAAG,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AA+BtE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CAKpB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,IAAI,CAShC,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,QAAQ,CAAC,IAAI,CA0D/B,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Preview.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Preview.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAuC,MAAM,OAAO,CAAC;
|
1
|
+
{"version":3,"file":"Preview.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/Preview.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAuC,MAAM,OAAO,CAAC;AAM5D,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAgG3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAKlC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,OAAO;;CA+BnB,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@dxos/react-ui-editor",
|
3
|
-
"version": "0.8.3-main.
|
3
|
+
"version": "0.8.3-main.7f5a14c",
|
4
4
|
"description": "Document editing experience within a DXOS shell.",
|
5
5
|
"homepage": "https://dxos.org",
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
@@ -59,20 +59,21 @@
|
|
59
59
|
"lodash.merge": "^4.6.2",
|
60
60
|
"lodash.sortby": "^4.7.0",
|
61
61
|
"style-mod": "^4.1.0",
|
62
|
-
"@dxos/app-graph": "0.8.3-main.
|
63
|
-
"@dxos/async": "0.8.3-main.
|
64
|
-
"@dxos/context": "0.8.3-main.
|
65
|
-
"@dxos/debug": "0.8.3-main.
|
66
|
-
"@dxos/
|
67
|
-
"@dxos/
|
68
|
-
"@dxos/invariant": "0.8.3-main.
|
69
|
-
"@dxos/lit-ui": "0.8.3-main.
|
70
|
-
"@dxos/live-object": "0.8.3-main.
|
71
|
-
"@dxos/log": "0.8.3-main.
|
72
|
-
"@dxos/protocols": "0.8.3-main.
|
73
|
-
"@dxos/react-hooks": "0.8.3-main.
|
74
|
-
"@dxos/
|
75
|
-
"@dxos/react-ui-
|
62
|
+
"@dxos/app-graph": "0.8.3-main.7f5a14c",
|
63
|
+
"@dxos/async": "0.8.3-main.7f5a14c",
|
64
|
+
"@dxos/context": "0.8.3-main.7f5a14c",
|
65
|
+
"@dxos/debug": "0.8.3-main.7f5a14c",
|
66
|
+
"@dxos/echo-schema": "0.8.3-main.7f5a14c",
|
67
|
+
"@dxos/display-name": "0.8.3-main.7f5a14c",
|
68
|
+
"@dxos/invariant": "0.8.3-main.7f5a14c",
|
69
|
+
"@dxos/lit-ui": "0.8.3-main.7f5a14c",
|
70
|
+
"@dxos/live-object": "0.8.3-main.7f5a14c",
|
71
|
+
"@dxos/log": "0.8.3-main.7f5a14c",
|
72
|
+
"@dxos/protocols": "0.8.3-main.7f5a14c",
|
73
|
+
"@dxos/react-hooks": "0.8.3-main.7f5a14c",
|
74
|
+
"@dxos/react-ui-menu": "0.8.3-main.7f5a14c",
|
75
|
+
"@dxos/react-ui-stack": "0.8.3-main.7f5a14c",
|
76
|
+
"@dxos/util": "0.8.3-main.7f5a14c"
|
76
77
|
},
|
77
78
|
"devDependencies": {
|
78
79
|
"@automerge/automerge": "3.0.0-beta.4",
|
@@ -101,16 +102,18 @@
|
|
101
102
|
"vite": "5.4.7",
|
102
103
|
"vite-plugin-top-level-await": "^1.4.1",
|
103
104
|
"vite-plugin-wasm": "^3.3.0",
|
104
|
-
"@dxos/config": "0.8.3-main.
|
105
|
-
"@dxos/
|
106
|
-
"@dxos/
|
107
|
-
"@dxos/
|
108
|
-
"@dxos/react-client": "0.8.3-main.
|
109
|
-
"@dxos/react-ui
|
110
|
-
"@dxos/react-ui": "0.8.3-main.
|
111
|
-
"@dxos/react-ui-syntax-highlighter": "0.8.3-main.
|
112
|
-
"@dxos/
|
113
|
-
"@dxos/
|
105
|
+
"@dxos/config": "0.8.3-main.7f5a14c",
|
106
|
+
"@dxos/echo": "0.8.3-main.7f5a14c",
|
107
|
+
"@dxos/keyboard": "0.8.3-main.7f5a14c",
|
108
|
+
"@dxos/random": "0.8.3-main.7f5a14c",
|
109
|
+
"@dxos/react-client": "0.8.3-main.7f5a14c",
|
110
|
+
"@dxos/react-ui": "0.8.3-main.7f5a14c",
|
111
|
+
"@dxos/react-ui-attention": "0.8.3-main.7f5a14c",
|
112
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.3-main.7f5a14c",
|
113
|
+
"@dxos/react-ui-theme": "0.8.3-main.7f5a14c",
|
114
|
+
"@dxos/echo-signals": "0.8.3-main.7f5a14c",
|
115
|
+
"@dxos/storybook-utils": "0.8.3-main.7f5a14c",
|
116
|
+
"@dxos/schema": "0.8.3-main.7f5a14c"
|
114
117
|
},
|
115
118
|
"peerDependencies": {
|
116
119
|
"@effect-rx/rx-react": "^0.34.1",
|
@@ -119,9 +122,9 @@
|
|
119
122
|
"effect": "^3.13.3",
|
120
123
|
"react": "~18.2.0",
|
121
124
|
"react-dom": "~18.2.0",
|
122
|
-
"@dxos/react-ui": "0.8.3-main.
|
123
|
-
"@dxos/react-client": "0.8.3-main.
|
124
|
-
"@dxos/react-ui
|
125
|
+
"@dxos/react-ui-theme": "0.8.3-main.7f5a14c",
|
126
|
+
"@dxos/react-client": "0.8.3-main.7f5a14c",
|
127
|
+
"@dxos/react-ui": "0.8.3-main.7f5a14c"
|
125
128
|
},
|
126
129
|
"publishConfig": {
|
127
130
|
"access": "public"
|
@@ -0,0 +1,279 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2025 DXOS.org
|
3
|
+
//
|
4
|
+
|
5
|
+
import { type EditorView } from '@codemirror/view';
|
6
|
+
import React, { useCallback, useEffect, useRef } from 'react';
|
7
|
+
|
8
|
+
import { Icon, type Label, Popover, toLocalizedString, useThemeContext, useTranslation } from '@dxos/react-ui';
|
9
|
+
import { type MaybePromise } from '@dxos/util';
|
10
|
+
|
11
|
+
import { commandRangeEffect } from '../../extensions';
|
12
|
+
|
13
|
+
export type CommandMenuGroup = {
|
14
|
+
id: string;
|
15
|
+
label?: Label;
|
16
|
+
items: CommandMenuItem[];
|
17
|
+
};
|
18
|
+
|
19
|
+
export type CommandMenuItem = {
|
20
|
+
id: string;
|
21
|
+
label: Label;
|
22
|
+
icon?: string;
|
23
|
+
onSelect?: (view: EditorView, head: number) => MaybePromise<void>;
|
24
|
+
};
|
25
|
+
|
26
|
+
export type CommandMenuProps = {
|
27
|
+
groups: CommandMenuGroup[];
|
28
|
+
currentItem?: string;
|
29
|
+
onSelect: (item: CommandMenuItem) => void;
|
30
|
+
};
|
31
|
+
|
32
|
+
// NOTE: Not using DropdownMenu because the command menu needs to manage focus explicitly.
|
33
|
+
export const CommandMenu = ({ groups, currentItem, onSelect }: CommandMenuProps) => {
|
34
|
+
const { tx } = useThemeContext();
|
35
|
+
const groupsWithItems = groups.filter((group) => group.items.length > 0);
|
36
|
+
return (
|
37
|
+
<Popover.Portal>
|
38
|
+
<Popover.Content
|
39
|
+
align='start'
|
40
|
+
onOpenAutoFocus={(event) => event.preventDefault()}
|
41
|
+
classNames={tx('menu.content', 'menu--exotic-unfocusable', { elevation: 'positioned' }, [
|
42
|
+
'max-h-[300px] overflow-y-auto',
|
43
|
+
])}
|
44
|
+
>
|
45
|
+
<Popover.Viewport classNames={tx('menu.viewport', 'menu__viewport--exotic-unfocusable', {})}>
|
46
|
+
<ul>
|
47
|
+
{groupsWithItems.map((group, index) => (
|
48
|
+
<React.Fragment key={group.id}>
|
49
|
+
<CommandGroup group={group} currentItem={currentItem} onSelect={onSelect} />
|
50
|
+
{index < groupsWithItems.length - 1 && <div className={tx('menu.separator', 'menu__item', {})} />}
|
51
|
+
</React.Fragment>
|
52
|
+
))}
|
53
|
+
</ul>
|
54
|
+
</Popover.Viewport>
|
55
|
+
</Popover.Content>
|
56
|
+
</Popover.Portal>
|
57
|
+
);
|
58
|
+
};
|
59
|
+
|
60
|
+
const CommandGroup = ({
|
61
|
+
group,
|
62
|
+
currentItem,
|
63
|
+
onSelect,
|
64
|
+
}: {
|
65
|
+
group: CommandMenuGroup;
|
66
|
+
currentItem?: string;
|
67
|
+
onSelect: (item: CommandMenuItem) => void;
|
68
|
+
}) => {
|
69
|
+
const { tx } = useThemeContext();
|
70
|
+
const { t } = useTranslation();
|
71
|
+
return (
|
72
|
+
<>
|
73
|
+
{group.label && (
|
74
|
+
<div className={tx('menu.groupLabel', 'menu__group__label', {})}>
|
75
|
+
<span>{toLocalizedString(group.label, t)}</span>
|
76
|
+
</div>
|
77
|
+
)}
|
78
|
+
{group.items.map((item) => (
|
79
|
+
<CommandItem key={item.id} item={item} current={currentItem === item.id} onSelect={onSelect} />
|
80
|
+
))}
|
81
|
+
</>
|
82
|
+
);
|
83
|
+
};
|
84
|
+
|
85
|
+
const CommandItem = ({
|
86
|
+
item,
|
87
|
+
current,
|
88
|
+
onSelect,
|
89
|
+
}: {
|
90
|
+
item: CommandMenuItem;
|
91
|
+
current: boolean;
|
92
|
+
onSelect: (item: CommandMenuItem) => void;
|
93
|
+
}) => {
|
94
|
+
const ref = useRef<HTMLLIElement>(null);
|
95
|
+
const { tx } = useThemeContext();
|
96
|
+
const { t } = useTranslation();
|
97
|
+
const handleSelect = useCallback(() => onSelect(item), [item, onSelect]);
|
98
|
+
|
99
|
+
useEffect(() => {
|
100
|
+
if (current && ref.current) {
|
101
|
+
ref.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
102
|
+
}
|
103
|
+
}, [current]);
|
104
|
+
|
105
|
+
return (
|
106
|
+
<li
|
107
|
+
ref={ref}
|
108
|
+
className={tx('menu.item', 'menu__item--exotic-unfocusable', {}, [current && 'bg-hoverSurface'])}
|
109
|
+
onClick={handleSelect}
|
110
|
+
>
|
111
|
+
{item.icon && <Icon icon={item.icon} size={5} />}
|
112
|
+
<span className='grow truncate'>{toLocalizedString(item.label, t)}</span>
|
113
|
+
</li>
|
114
|
+
);
|
115
|
+
};
|
116
|
+
|
117
|
+
// TODO(wittjosiah): Factor out into a separate file.
|
118
|
+
|
119
|
+
//
|
120
|
+
// Helpers
|
121
|
+
//
|
122
|
+
|
123
|
+
export const getItem = (groups: CommandMenuGroup[], id?: string): CommandMenuItem | undefined => {
|
124
|
+
return groups.flatMap((group) => group.items).find((item) => item.id === id);
|
125
|
+
};
|
126
|
+
|
127
|
+
export const getNextItem = (groups: CommandMenuGroup[], id?: string): CommandMenuItem => {
|
128
|
+
const items = groups.flatMap((group) => group.items);
|
129
|
+
const index = items.findIndex((item) => item.id === id);
|
130
|
+
return items[(index + 1) % items.length];
|
131
|
+
};
|
132
|
+
|
133
|
+
export const getPreviousItem = (groups: CommandMenuGroup[], id?: string): CommandMenuItem => {
|
134
|
+
const items = groups.flatMap((group) => group.items);
|
135
|
+
const index = items.findIndex((item) => item.id === id);
|
136
|
+
return items[(index - 1 + items.length) % items.length];
|
137
|
+
};
|
138
|
+
|
139
|
+
export const filterItems = (
|
140
|
+
groups: CommandMenuGroup[],
|
141
|
+
filter: (item: CommandMenuItem) => boolean,
|
142
|
+
): CommandMenuGroup[] => {
|
143
|
+
return groups.map((group) => ({
|
144
|
+
...group,
|
145
|
+
items: group.items.filter(filter),
|
146
|
+
}));
|
147
|
+
};
|
148
|
+
|
149
|
+
export const insertAtCursor = (view: EditorView, head: number, insert: string) => {
|
150
|
+
view.dispatch({
|
151
|
+
changes: { from: head, to: head, insert },
|
152
|
+
selection: { anchor: head + insert.length, head: head + insert.length },
|
153
|
+
});
|
154
|
+
};
|
155
|
+
|
156
|
+
/**
|
157
|
+
* If the cursor is at the start of a line, insert the text at the cursor.
|
158
|
+
* Otherwise, insert the text on a new line.
|
159
|
+
*/
|
160
|
+
export const insertAtLineStart = (view: EditorView, head: number, insert: string) => {
|
161
|
+
const line = view.state.doc.lineAt(head);
|
162
|
+
if (line.from === head) {
|
163
|
+
insertAtCursor(view, head, insert);
|
164
|
+
} else {
|
165
|
+
insert = '\n' + insert;
|
166
|
+
view.dispatch({
|
167
|
+
changes: { from: line.to, to: line.to, insert },
|
168
|
+
selection: { anchor: line.to + insert.length, head: line.to + insert.length },
|
169
|
+
});
|
170
|
+
}
|
171
|
+
};
|
172
|
+
|
173
|
+
export const coreSlashCommands: CommandMenuGroup = {
|
174
|
+
id: 'markdown',
|
175
|
+
label: 'Markdown',
|
176
|
+
items: [
|
177
|
+
{
|
178
|
+
id: 'heading-1',
|
179
|
+
label: 'Heading 1',
|
180
|
+
icon: 'ph--text-h-one--regular',
|
181
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '# '),
|
182
|
+
},
|
183
|
+
{
|
184
|
+
id: 'heading-2',
|
185
|
+
label: 'Heading 2',
|
186
|
+
icon: 'ph--text-h-two--regular',
|
187
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '## '),
|
188
|
+
},
|
189
|
+
{
|
190
|
+
id: 'heading-3',
|
191
|
+
label: 'Heading 3',
|
192
|
+
icon: 'ph--text-h-three--regular',
|
193
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '### '),
|
194
|
+
},
|
195
|
+
{
|
196
|
+
id: 'heading-4',
|
197
|
+
label: 'Heading 4',
|
198
|
+
icon: 'ph--text-h-four--regular',
|
199
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '#### '),
|
200
|
+
},
|
201
|
+
{
|
202
|
+
id: 'heading-5',
|
203
|
+
label: 'Heading 5',
|
204
|
+
icon: 'ph--text-h-five--regular',
|
205
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '##### '),
|
206
|
+
},
|
207
|
+
{
|
208
|
+
id: 'heading-6',
|
209
|
+
label: 'Heading 6',
|
210
|
+
icon: 'ph--text-h-six--regular',
|
211
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '###### '),
|
212
|
+
},
|
213
|
+
{
|
214
|
+
id: 'bullet-list',
|
215
|
+
label: 'Bullet List',
|
216
|
+
icon: 'ph--list-bullets--regular',
|
217
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '- '),
|
218
|
+
},
|
219
|
+
{
|
220
|
+
id: 'numbered-list',
|
221
|
+
label: 'Numbered List',
|
222
|
+
icon: 'ph--list-numbers--regular',
|
223
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '1. '),
|
224
|
+
},
|
225
|
+
{
|
226
|
+
id: 'task-list',
|
227
|
+
label: 'Task List',
|
228
|
+
icon: 'ph--list-checks--regular',
|
229
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '- [ ] '),
|
230
|
+
},
|
231
|
+
{
|
232
|
+
id: 'quote',
|
233
|
+
label: 'Quote',
|
234
|
+
icon: 'ph--quotes--regular',
|
235
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '> '),
|
236
|
+
},
|
237
|
+
{
|
238
|
+
id: 'code-block',
|
239
|
+
label: 'Code Block',
|
240
|
+
icon: 'ph--code-block--regular',
|
241
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '```\n\n```'),
|
242
|
+
},
|
243
|
+
{
|
244
|
+
id: 'table',
|
245
|
+
label: 'Table',
|
246
|
+
icon: 'ph--table--regular',
|
247
|
+
onSelect: (view, head) => insertAtLineStart(view, head, '| | | |\n|---|---|---|\n| | | |'),
|
248
|
+
},
|
249
|
+
],
|
250
|
+
};
|
251
|
+
|
252
|
+
export const linkSlashCommands: CommandMenuGroup = {
|
253
|
+
id: 'link',
|
254
|
+
label: 'Link',
|
255
|
+
items: [
|
256
|
+
{
|
257
|
+
id: 'inline-link',
|
258
|
+
label: 'Inline link',
|
259
|
+
icon: 'ph--link--regular',
|
260
|
+
onSelect: (view, head) =>
|
261
|
+
view.dispatch({
|
262
|
+
changes: { from: head, insert: '@' },
|
263
|
+
selection: { anchor: head + 1, head: head + 1 },
|
264
|
+
effects: commandRangeEffect.of({ trigger: '@', range: { from: head, to: head + 1 } }),
|
265
|
+
}),
|
266
|
+
},
|
267
|
+
{
|
268
|
+
id: 'block-embed',
|
269
|
+
label: 'Block embed',
|
270
|
+
icon: 'ph--lego--regular',
|
271
|
+
onSelect: (view, head) =>
|
272
|
+
view.dispatch({
|
273
|
+
changes: { from: head, insert: '@@' },
|
274
|
+
selection: { anchor: head + 2, head: head + 2 },
|
275
|
+
effects: commandRangeEffect.of({ trigger: '@', range: { from: head, to: head + 2 } }),
|
276
|
+
}),
|
277
|
+
},
|
278
|
+
],
|
279
|
+
};
|