@getguru/slate-yjs-react 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/README.md +3 -0
- package/dist/hooks/useDecorateRemoteCursors.d.ts +24 -0
- package/dist/hooks/useDecorateRemoteCursors.d.ts.map +1 -0
- package/dist/hooks/useRemoteCursorEditor.d.ts +4 -0
- package/dist/hooks/useRemoteCursorEditor.d.ts.map +1 -0
- package/dist/hooks/useRemoteCursorOverlayPositions.d.ts +19 -0
- package/dist/hooks/useRemoteCursorOverlayPositions.d.ts.map +1 -0
- package/dist/hooks/useRemoteCursorStateStore.d.ts +5 -0
- package/dist/hooks/useRemoteCursorStateStore.d.ts.map +1 -0
- package/dist/hooks/useRemoteCursorStates.d.ts +4 -0
- package/dist/hooks/useRemoteCursorStates.d.ts.map +1 -0
- package/dist/hooks/useUnsetCursorPositionOnBlur.d.ts +2 -0
- package/dist/hooks/useUnsetCursorPositionOnBlur.d.ts.map +1 -0
- package/dist/hooks/utils.d.ts +4 -0
- package/dist/hooks/utils.d.ts.map +1 -0
- package/dist/index.cjs +453 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.global.js +31900 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +450 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/getCursorRange.d.ts +4 -0
- package/dist/utils/getCursorRange.d.ts.map +1 -0
- package/dist/utils/getOverlayPosition.d.ts +24 -0
- package/dist/utils/getOverlayPosition.d.ts.map +1 -0
- package/dist/utils/react-editor-to-dom-range-safe.d.ts +4 -0
- package/dist/utils/react-editor-to-dom-range-safe.d.ts.map +1 -0
- package/package.json +55 -0
- package/src/hooks/useDecorateRemoteCursors.ts +125 -0
- package/src/hooks/useRemoteCursorEditor.ts +15 -0
- package/src/hooks/useRemoteCursorOverlayPositions.tsx +144 -0
- package/src/hooks/useRemoteCursorStateStore.ts +89 -0
- package/src/hooks/useRemoteCursorStates.ts +28 -0
- package/src/hooks/useUnsetCursorPositionOnBlur.ts +48 -0
- package/src/hooks/utils.ts +61 -0
- package/src/index.ts +26 -0
- package/src/types.ts +4 -0
- package/src/utils/getCursorRange.ts +45 -0
- package/src/utils/getOverlayPosition.ts +111 -0
- package/src/utils/react-editor-to-dom-range-safe.ts +13 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +32 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @slate-yjs/react
|
|
2
|
+
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#412](https://github.com/BitPhinix/slate-yjs/pull/412) [`8ab46c0`](https://github.com/BitPhinix/slate-yjs/commit/8ab46c0bcdacdd18133b60b5fc885c915580c5f5) Thanks [@ilya2204](https://github.com/ilya2204)! - Add error handling to cursor overlay
|
|
8
|
+
|
|
9
|
+
## 1.0.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`a6a27c8`](https://github.com/BitPhinix/slate-yjs/commit/a6a27c86678656e55ecbf0ba76852545605a0955), [`a6a27c8`](https://github.com/BitPhinix/slate-yjs/commit/a6a27c86678656e55ecbf0ba76852545605a0955), [`72bbbf3`](https://github.com/BitPhinix/slate-yjs/commit/72bbbf3bb8a3f57762153cbd9a7f689d2b282f0c)]:
|
|
14
|
+
- @slate-yjs/core@1.0.0
|
|
15
|
+
|
|
16
|
+
## 0.3.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- [#363](https://github.com/BitPhinix/slate-yjs/pull/363) [`3710c48`](https://github.com/BitPhinix/slate-yjs/commit/3710c4887ee89946ace787ba24436d82d95bc856) Thanks [@BitPhinix](https://github.com/BitPhinix)! - Changed:
|
|
21
|
+
|
|
22
|
+
- Rewrite of `useRemoteCursorOverlayPositions` to provide stricter typings, make it react 18 safe and add new `shouldGenerateOverlay` option.
|
|
23
|
+
|
|
24
|
+
Added:
|
|
25
|
+
|
|
26
|
+
- Remote cursor decorations using the new `useDecorateRemoteCursors` hook
|
|
27
|
+
- Remote cursor data hooks `useRemoteCursorStatesSelector` and `useRemoteCursorStates`
|
|
28
|
+
- Utility hooks to un-send the current cursor position on window/editor blur: `useUnsetCursorPositionOnBlur`
|
|
29
|
+
- `getCursorRange` helper
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Updated dependencies [[`3710c48`](https://github.com/BitPhinix/slate-yjs/commit/3710c4887ee89946ace787ba24436d82d95bc856)]:
|
|
34
|
+
- @slate-yjs/core@0.3.0
|
|
35
|
+
|
|
36
|
+
## 0.2.4
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- [#339](https://github.com/BitPhinix/slate-yjs/pull/339) [`042a0a2`](https://github.com/BitPhinix/slate-yjs/commit/042a0a22f57ed7542a4e05840532f16d37629e33) Thanks [@BitPhinix](https://github.com/BitPhinix)! - Replace workspace:^ dependencies with concrete version range
|
|
41
|
+
|
|
42
|
+
## 0.2.3
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [[`5172e4a`](https://github.com/BitPhinix/slate-yjs/commit/5172e4a0033db41bc3530f227c5371e9ddb22269)]:
|
|
47
|
+
- @slate-yjs/core@0.2.3
|
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CursorState } from '@getguru/slate-yjs-core';
|
|
2
|
+
import { BaseRange, BaseText, NodeEntry } from 'slate';
|
|
3
|
+
export declare const REMOTE_CURSOR_DECORATION_PREFIX = "remote-cursor-";
|
|
4
|
+
export declare const REMOTE_CURSOR_CARET_DECORATION_PREFIX = "remote-caret-";
|
|
5
|
+
export declare type RemoteCaretDecoration<TCursorData extends Record<string, unknown> = Record<string, unknown>> = {
|
|
6
|
+
[key: `${typeof REMOTE_CURSOR_CARET_DECORATION_PREFIX}${string}`]: CursorState<TCursorData> & {
|
|
7
|
+
isBackward: boolean;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export declare type RemoteCursorDecoration<TCursorData extends Record<string, unknown> = Record<string, unknown>> = {
|
|
11
|
+
[key: `${typeof REMOTE_CURSOR_DECORATION_PREFIX}${string}`]: CursorState<TCursorData>;
|
|
12
|
+
};
|
|
13
|
+
export declare type RemoteCursorDecoratedRange<TCursorData extends Record<string, unknown> = Record<string, unknown>> = BaseRange & RemoteCursorDecoration<TCursorData>;
|
|
14
|
+
export declare type RemoteCaretDecoratedRange<TCursorData extends Record<string, unknown> = Record<string, unknown>> = BaseRange & RemoteCaretDecoration<TCursorData>;
|
|
15
|
+
export declare type TextWithRemoteCursors<TCursorData extends Record<string, unknown> = Record<string, unknown>> = BaseText & RemoteCursorDecoration<TCursorData> & RemoteCaretDecoration<TCursorData>;
|
|
16
|
+
export declare function getRemoteCursorsOnLeaf<TCursorData extends Record<string, unknown>, TLeaf extends TextWithRemoteCursors<TCursorData>>(leaf: TLeaf): CursorState<TCursorData>[];
|
|
17
|
+
export declare function getRemoteCaretsOnLeaf<TCursorData extends Record<string, unknown>, TLeaf extends TextWithRemoteCursors<TCursorData>>(leaf: TLeaf): (CursorState<TCursorData> & {
|
|
18
|
+
isBackward: boolean;
|
|
19
|
+
})[];
|
|
20
|
+
export declare type UseDecorateRemoteCursorsOptions = {
|
|
21
|
+
carets?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare function useDecorateRemoteCursors<TCursorData extends Record<string, unknown> = Record<string, unknown>>({ carets }?: UseDecorateRemoteCursorsOptions): (entry: NodeEntry<import("slate").Node>) => (RemoteCursorDecoratedRange<TCursorData> | RemoteCaretDecoratedRange<TCursorData>)[];
|
|
24
|
+
//# sourceMappingURL=useDecorateRemoteCursors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDecorateRemoteCursors.d.ts","sourceRoot":"","sources":["../../src/hooks/useDecorateRemoteCursors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAS,MAAM,OAAO,CAAC;AAK9D,eAAO,MAAM,+BAA+B,mBAAmB,CAAC;AAChE,eAAO,MAAM,qCAAqC,kBAAkB,CAAC;AAErE,oBAAY,qBAAqB,CAC/B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACnE;IACF,CACE,GAAG,EAAE,GAAG,OAAO,qCAAqC,GAAG,MAAM,EAAE,GAC9D,WAAW,CAAC,WAAW,CAAC,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;CACvD,CAAC;AAEF,oBAAY,sBAAsB,CAChC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACnE;IACF,CACE,GAAG,EAAE,GAAG,OAAO,+BAA+B,GAAG,MAAM,EAAE,GACxD,WAAW,CAAC,WAAW,CAAC,CAAC;CAC7B,CAAC;AAEF,oBAAY,0BAA0B,CACpC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACnE,SAAS,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;AAEpD,oBAAY,yBAAyB,CACnC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACnE,SAAS,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;AAEnD,oBAAY,qBAAqB,CAC/B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACnE,QAAQ,GACV,sBAAsB,CAAC,WAAW,CAAC,GACnC,qBAAqB,CAAC,WAAW,CAAC,CAAC;AAErC,wBAAgB,sBAAsB,CACpC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,KAAK,SAAS,qBAAqB,CAAC,WAAW,CAAC,EAChD,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,EAAE,CAIzC;AAED,wBAAgB,qBAAqB,CACnC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,KAAK,SAAS,qBAAqB,CAAC,WAAW,CAAC,EAChD,IAAI,EAAE,KAAK,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,CAIrE;AAED,oBAAY,+BAA+B,GAAG;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AA0BF,wBAAgB,wBAAwB,CACtC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrE,EAAE,MAAa,EAAE,GAAE,+BAAoC,oIAoCxD"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CursorEditor } from '@getguru/slate-yjs-core';
|
|
2
|
+
import { ReactEditor } from 'slate-react';
|
|
3
|
+
export declare function useRemoteCursorEditor<TCursorData extends Record<string, unknown> = Record<string, unknown>>(): CursorEditor<TCursorData> & ReactEditor;
|
|
4
|
+
//# sourceMappingURL=useRemoteCursorEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRemoteCursorEditor.d.ts","sourceRoot":"","sources":["../../src/hooks/useRemoteCursorEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAE1D,wBAAgB,qBAAqB,CACnC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAClE,YAAY,CAAC,WAAW,CAAC,GAAG,WAAW,CAS3C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CursorState } from '@getguru/slate-yjs-core';
|
|
2
|
+
import { RefObject } from 'react';
|
|
3
|
+
import { BaseRange, NodeMatch, Text } from 'slate';
|
|
4
|
+
import { CaretPosition, SelectionRect } from '../utils/getOverlayPosition';
|
|
5
|
+
export declare type UseRemoteCursorOverlayPositionsOptions<T extends HTMLElement> = {
|
|
6
|
+
shouldGenerateOverlay?: NodeMatch<Text>;
|
|
7
|
+
} & ({
|
|
8
|
+
containerRef?: undefined;
|
|
9
|
+
} | {
|
|
10
|
+
containerRef: RefObject<T>;
|
|
11
|
+
refreshOnResize?: boolean | 'debounced';
|
|
12
|
+
});
|
|
13
|
+
export declare type CursorOverlayData<TCursorData extends Record<string, unknown>> = CursorState<TCursorData> & {
|
|
14
|
+
range: BaseRange | null;
|
|
15
|
+
caretPosition: CaretPosition | null;
|
|
16
|
+
selectionRects: SelectionRect[];
|
|
17
|
+
};
|
|
18
|
+
export declare function useRemoteCursorOverlayPositions<TCursorData extends Record<string, unknown>, TContainer extends HTMLElement = HTMLDivElement>({ containerRef, shouldGenerateOverlay, ...opts }?: UseRemoteCursorOverlayPositionsOptions<TContainer>): readonly [CursorOverlayData<TCursorData>[], () => void];
|
|
19
|
+
//# sourceMappingURL=useRemoteCursorOverlayPositions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRemoteCursorOverlayPositions.d.ts","sourceRoot":"","sources":["../../src/hooks/useRemoteCursorOverlayPositions.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,SAAS,EAMV,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EACL,aAAa,EAGb,aAAa,EACd,MAAM,6BAA6B,CAAC;AAOrC,oBAAY,sCAAsC,CAAC,CAAC,SAAS,WAAW,IAAI;IAC1E,qBAAqB,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;CACzC,GAAG,CACA;IAIE,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B,GACD;IACE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAK3B,eAAe,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CACzC,CACJ,CAAC;AAEF,oBAAY,iBAAiB,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACvE,WAAW,CAAC,WAAW,CAAC,GAAG;IACzB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC,CAAC;AAEJ,wBAAgB,+BAA+B,CAC7C,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,UAAU,SAAS,WAAW,GAAG,cAAc,EAC/C,EACA,YAAY,EACZ,qBAAqB,EACrB,GAAG,IAAI,EACR,GAAE,sCAAsC,CAAC,UAAU,CAAM,2DAuFzD"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CursorState } from '@getguru/slate-yjs-core';
|
|
2
|
+
import { Store } from '../types';
|
|
3
|
+
export declare type CursorStore<TCursorData extends Record<string, unknown> = Record<string, unknown>> = Store<Record<string, CursorState<TCursorData>>>;
|
|
4
|
+
export declare function useRemoteCursorStateStore<TCursorData extends Record<string, unknown> = Record<string, unknown>>(): CursorStore<TCursorData>;
|
|
5
|
+
//# sourceMappingURL=useRemoteCursorStateStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRemoteCursorStateStore.d.ts","sourceRoot":"","sources":["../../src/hooks/useRemoteCursorStateStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAEZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,oBAAY,WAAW,CACrB,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACnE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAwEpD,wBAAgB,yBAAyB,CACvC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,8BAItE"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CursorState } from '@getguru/slate-yjs-core';
|
|
2
|
+
export declare function useRemoteCursorStates<TCursorData extends Record<string, unknown> = Record<string, unknown>>(): Record<string, CursorState<TCursorData>>;
|
|
3
|
+
export declare function useRemoteCursorStatesSelector<TCursorData extends Record<string, unknown> = Record<string, unknown>, TSelection = unknown>(selector: (cursors: Record<string, CursorState<TCursorData>>) => TSelection, isEqual?: (a: TSelection, b: TSelection) => boolean): TSelection;
|
|
4
|
+
//# sourceMappingURL=useRemoteCursorStates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRemoteCursorStates.d.ts","sourceRoot":"","sources":["../../src/hooks/useRemoteCursorStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,wBAAgB,qBAAqB,CACnC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,8CAItE;AAED,wBAAgB,6BAA6B,CAC3C,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrE,UAAU,GAAG,OAAO,EAEpB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,KAAK,UAAU,EAC3E,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,KAAK,OAAO,GAClD,UAAU,CASZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUnsetCursorPositionOnBlur.d.ts","sourceRoot":"","sources":["../../src/hooks/useUnsetCursorPositionOnBlur.ts"],"names":[],"mappings":"AAKA,wBAAgB,4BAA4B,SA0C3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/hooks/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EAMV,MAAM,OAAO,CAAC;AAEf,wBAAgB,kBAAkB,gCA0BjC;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAC/C,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,EAC7B,QAAQ,EAAE,MAAM,IAAI,QAqBrB"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
9
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
|
+
var __spreadValues = (a, b) => {
|
|
11
|
+
for (var prop in b || (b = {}))
|
|
12
|
+
if (__hasOwnProp.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
if (__getOwnPropSymbols)
|
|
15
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
16
|
+
if (__propIsEnum.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
18
|
+
}
|
|
19
|
+
return a;
|
|
20
|
+
};
|
|
21
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
22
|
+
var __objRest = (source, exclude) => {
|
|
23
|
+
var target = {};
|
|
24
|
+
for (var prop in source)
|
|
25
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
26
|
+
target[prop] = source[prop];
|
|
27
|
+
if (source != null && __getOwnPropSymbols)
|
|
28
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
29
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
30
|
+
target[prop] = source[prop];
|
|
31
|
+
}
|
|
32
|
+
return target;
|
|
33
|
+
};
|
|
34
|
+
var __export = (target, all) => {
|
|
35
|
+
for (var name in all)
|
|
36
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
37
|
+
};
|
|
38
|
+
var __copyProps = (to, from, except, desc) => {
|
|
39
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
40
|
+
for (let key of __getOwnPropNames(from))
|
|
41
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
42
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
43
|
+
}
|
|
44
|
+
return to;
|
|
45
|
+
};
|
|
46
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
47
|
+
|
|
48
|
+
// src/index.ts
|
|
49
|
+
var src_exports = {};
|
|
50
|
+
__export(src_exports, {
|
|
51
|
+
getCursorRange: () => getCursorRange,
|
|
52
|
+
getRemoteCaretsOnLeaf: () => getRemoteCaretsOnLeaf,
|
|
53
|
+
getRemoteCursorsOnLeaf: () => getRemoteCursorsOnLeaf,
|
|
54
|
+
useDecorateRemoteCursors: () => useDecorateRemoteCursors,
|
|
55
|
+
useRemoteCursorOverlayPositions: () => useRemoteCursorOverlayPositions,
|
|
56
|
+
useRemoteCursorStates: () => useRemoteCursorStates,
|
|
57
|
+
useRemoteCursorStatesSelector: () => useRemoteCursorStatesSelector,
|
|
58
|
+
useUnsetCursorPositionOnBlur: () => useUnsetCursorPositionOnBlur
|
|
59
|
+
});
|
|
60
|
+
module.exports = __toCommonJS(src_exports);
|
|
61
|
+
|
|
62
|
+
// src/hooks/useDecorateRemoteCursors.ts
|
|
63
|
+
var import_react = require("react");
|
|
64
|
+
var import_slate = require("slate");
|
|
65
|
+
|
|
66
|
+
// src/utils/getCursorRange.ts
|
|
67
|
+
var import_slate_yjs_core = require("@getguru/slate-yjs-core");
|
|
68
|
+
var CHILDREN_TO_CURSOR_STATE_TO_RANGE = /* @__PURE__ */ new WeakMap();
|
|
69
|
+
function getCursorRange(editor, cursorState) {
|
|
70
|
+
if (!cursorState.relativeSelection) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
let cursorStates = CHILDREN_TO_CURSOR_STATE_TO_RANGE.get(editor.children);
|
|
74
|
+
if (!cursorStates) {
|
|
75
|
+
cursorStates = /* @__PURE__ */ new WeakMap();
|
|
76
|
+
CHILDREN_TO_CURSOR_STATE_TO_RANGE.set(editor.children, cursorStates);
|
|
77
|
+
}
|
|
78
|
+
let range = cursorStates.get(cursorState);
|
|
79
|
+
if (range === void 0) {
|
|
80
|
+
try {
|
|
81
|
+
range = (0, import_slate_yjs_core.relativeRangeToSlateRange)(editor.sharedRoot, editor, cursorState.relativeSelection);
|
|
82
|
+
cursorStates.set(cursorState, range);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return range;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/hooks/useRemoteCursorEditor.ts
|
|
91
|
+
var import_slate_yjs_core2 = require("@getguru/slate-yjs-core");
|
|
92
|
+
var import_slate_react = require("slate-react");
|
|
93
|
+
function useRemoteCursorEditor() {
|
|
94
|
+
const editor = (0, import_slate_react.useSlateStatic)();
|
|
95
|
+
if (!import_slate_yjs_core2.CursorEditor.isCursorEditor(editor)) {
|
|
96
|
+
throw new Error("Cannot use useSyncExternalStore outside the context of a RemoteCursorEditor");
|
|
97
|
+
}
|
|
98
|
+
return editor;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/hooks/useRemoteCursorStates.ts
|
|
102
|
+
var import_shim = require("use-sync-external-store/shim");
|
|
103
|
+
var import_with_selector = require("use-sync-external-store/shim/with-selector");
|
|
104
|
+
|
|
105
|
+
// src/hooks/useRemoteCursorStateStore.ts
|
|
106
|
+
var import_slate_yjs_core3 = require("@getguru/slate-yjs-core");
|
|
107
|
+
var EDITOR_TO_CURSOR_STORE = /* @__PURE__ */ new WeakMap();
|
|
108
|
+
function createRemoteCursorStateStore(editor) {
|
|
109
|
+
let cursors = {};
|
|
110
|
+
const changed = /* @__PURE__ */ new Set();
|
|
111
|
+
const addChanged = changed.add.bind(changed);
|
|
112
|
+
const onStoreChangeListeners = /* @__PURE__ */ new Set();
|
|
113
|
+
let changeHandler = null;
|
|
114
|
+
const subscribe = (onStoreChange) => {
|
|
115
|
+
onStoreChangeListeners.add(onStoreChange);
|
|
116
|
+
if (!changeHandler) {
|
|
117
|
+
changeHandler = (event) => {
|
|
118
|
+
event.added.forEach(addChanged);
|
|
119
|
+
event.removed.forEach(addChanged);
|
|
120
|
+
event.updated.forEach(addChanged);
|
|
121
|
+
onStoreChangeListeners.forEach((listener) => listener());
|
|
122
|
+
};
|
|
123
|
+
import_slate_yjs_core3.CursorEditor.on(editor, "change", changeHandler);
|
|
124
|
+
}
|
|
125
|
+
return () => {
|
|
126
|
+
onStoreChangeListeners.delete(onStoreChange);
|
|
127
|
+
if (changeHandler && onStoreChangeListeners.size === 0) {
|
|
128
|
+
import_slate_yjs_core3.CursorEditor.off(editor, "change", changeHandler);
|
|
129
|
+
changeHandler = null;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const getSnapshot = () => {
|
|
134
|
+
if (changed.size === 0) {
|
|
135
|
+
return cursors;
|
|
136
|
+
}
|
|
137
|
+
changed.forEach((clientId) => {
|
|
138
|
+
const state = import_slate_yjs_core3.CursorEditor.cursorState(editor, clientId);
|
|
139
|
+
if (state === null) {
|
|
140
|
+
delete cursors[clientId.toString()];
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
cursors[clientId] = state;
|
|
144
|
+
});
|
|
145
|
+
changed.clear();
|
|
146
|
+
cursors = __spreadValues({}, cursors);
|
|
147
|
+
return cursors;
|
|
148
|
+
};
|
|
149
|
+
return [subscribe, getSnapshot];
|
|
150
|
+
}
|
|
151
|
+
function getCursorStateStore(editor) {
|
|
152
|
+
const existing = EDITOR_TO_CURSOR_STORE.get(editor);
|
|
153
|
+
if (existing) {
|
|
154
|
+
return existing;
|
|
155
|
+
}
|
|
156
|
+
const store = createRemoteCursorStateStore(editor);
|
|
157
|
+
EDITOR_TO_CURSOR_STORE.set(editor, store);
|
|
158
|
+
return store;
|
|
159
|
+
}
|
|
160
|
+
function useRemoteCursorStateStore() {
|
|
161
|
+
const editor = useRemoteCursorEditor();
|
|
162
|
+
return getCursorStateStore(editor);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/hooks/useRemoteCursorStates.ts
|
|
166
|
+
function useRemoteCursorStates() {
|
|
167
|
+
const [subscribe, getSnapshot] = useRemoteCursorStateStore();
|
|
168
|
+
return (0, import_shim.useSyncExternalStore)(subscribe, getSnapshot);
|
|
169
|
+
}
|
|
170
|
+
function useRemoteCursorStatesSelector(selector, isEqual) {
|
|
171
|
+
const [subscribe, getSnapshot] = useRemoteCursorStateStore();
|
|
172
|
+
return (0, import_with_selector.useSyncExternalStoreWithSelector)(subscribe, getSnapshot, null, selector, isEqual);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/hooks/useDecorateRemoteCursors.ts
|
|
176
|
+
var REMOTE_CURSOR_DECORATION_PREFIX = "remote-cursor-";
|
|
177
|
+
var REMOTE_CURSOR_CARET_DECORATION_PREFIX = "remote-caret-";
|
|
178
|
+
function getRemoteCursorsOnLeaf(leaf) {
|
|
179
|
+
return Object.entries(leaf).filter(([key]) => key.startsWith(REMOTE_CURSOR_DECORATION_PREFIX)).map(([, data]) => data);
|
|
180
|
+
}
|
|
181
|
+
function getRemoteCaretsOnLeaf(leaf) {
|
|
182
|
+
return Object.entries(leaf).filter(([key]) => key.startsWith(REMOTE_CURSOR_CARET_DECORATION_PREFIX)).map(([, data]) => data);
|
|
183
|
+
}
|
|
184
|
+
function getDecoration(clientId, state, range, caret) {
|
|
185
|
+
if (!caret) {
|
|
186
|
+
const key2 = `${REMOTE_CURSOR_DECORATION_PREFIX}${clientId}`;
|
|
187
|
+
return __spreadProps(__spreadValues({}, range), { [key2]: state });
|
|
188
|
+
}
|
|
189
|
+
const key = `${REMOTE_CURSOR_CARET_DECORATION_PREFIX}${clientId}`;
|
|
190
|
+
return __spreadProps(__spreadValues({}, range), {
|
|
191
|
+
anchor: range.focus,
|
|
192
|
+
[key]: state
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function useDecorateRemoteCursors({ carets = true } = {}) {
|
|
196
|
+
const editor = useRemoteCursorEditor();
|
|
197
|
+
const cursors = useRemoteCursorStates();
|
|
198
|
+
const cursorsRef = (0, import_react.useRef)(cursors);
|
|
199
|
+
cursorsRef.current = cursors;
|
|
200
|
+
return (0, import_react.useCallback)((entry) => {
|
|
201
|
+
const [, path] = entry;
|
|
202
|
+
if (path.length !== 0) {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
return Object.entries(cursorsRef.current).flatMap(([clientId, state]) => {
|
|
206
|
+
const range = getCursorRange(editor, state);
|
|
207
|
+
if (!range) {
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
if (carets && import_slate.Range.isCollapsed(range)) {
|
|
211
|
+
return getDecoration(clientId, state, range, true);
|
|
212
|
+
}
|
|
213
|
+
if (!carets) {
|
|
214
|
+
return getDecoration(clientId, state, range, false);
|
|
215
|
+
}
|
|
216
|
+
return [
|
|
217
|
+
getDecoration(clientId, state, range, false),
|
|
218
|
+
getDecoration(clientId, state, range, true)
|
|
219
|
+
];
|
|
220
|
+
});
|
|
221
|
+
}, [carets, editor]);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/hooks/useUnsetCursorPositionOnBlur.ts
|
|
225
|
+
var import_slate_yjs_core4 = require("@getguru/slate-yjs-core");
|
|
226
|
+
var import_react2 = require("react");
|
|
227
|
+
var import_slate_react2 = require("slate-react");
|
|
228
|
+
function useUnsetCursorPositionOnBlur() {
|
|
229
|
+
const editor = useRemoteCursorEditor();
|
|
230
|
+
const isSlateFocused = (0, import_slate_react2.useFocused)();
|
|
231
|
+
const sendCursorPosition = (0, import_react2.useCallback)((isFocused) => {
|
|
232
|
+
if (isFocused && editor.selection) {
|
|
233
|
+
import_slate_yjs_core4.CursorEditor.sendCursorPosition(editor, editor.selection);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (!isFocused) {
|
|
237
|
+
import_slate_yjs_core4.CursorEditor.sendCursorPosition(editor, null);
|
|
238
|
+
}
|
|
239
|
+
}, [editor]);
|
|
240
|
+
(0, import_react2.useEffect)(() => {
|
|
241
|
+
const handleWindowBlur = () => {
|
|
242
|
+
if (isSlateFocused) {
|
|
243
|
+
sendCursorPosition(false);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
const handleWindowFocus = () => {
|
|
247
|
+
if (isSlateFocused) {
|
|
248
|
+
sendCursorPosition(true);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
window.addEventListener("blur", handleWindowBlur);
|
|
252
|
+
window.addEventListener("focus", handleWindowFocus);
|
|
253
|
+
return () => {
|
|
254
|
+
window.removeEventListener("blur", handleWindowBlur);
|
|
255
|
+
window.removeEventListener("focus", handleWindowFocus);
|
|
256
|
+
};
|
|
257
|
+
}, [isSlateFocused, sendCursorPosition]);
|
|
258
|
+
(0, import_react2.useEffect)(() => {
|
|
259
|
+
sendCursorPosition(isSlateFocused);
|
|
260
|
+
}, [editor, isSlateFocused, sendCursorPosition]);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/hooks/useRemoteCursorOverlayPositions.tsx
|
|
264
|
+
var import_react4 = require("react");
|
|
265
|
+
|
|
266
|
+
// src/utils/getOverlayPosition.ts
|
|
267
|
+
var import_slate2 = require("slate");
|
|
268
|
+
var import_slate_react4 = require("slate-react");
|
|
269
|
+
|
|
270
|
+
// src/utils/react-editor-to-dom-range-safe.ts
|
|
271
|
+
var import_slate_react3 = require("slate-react");
|
|
272
|
+
function reactEditorToDomRangeSafe(editor, range) {
|
|
273
|
+
try {
|
|
274
|
+
return import_slate_react3.ReactEditor.toDOMRange(editor, range);
|
|
275
|
+
} catch (e) {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/utils/getOverlayPosition.ts
|
|
281
|
+
function getOverlayPosition(editor, range, { yOffset, xOffset, shouldGenerateOverlay }) {
|
|
282
|
+
const [start, end] = import_slate2.Range.edges(range);
|
|
283
|
+
const domRange = reactEditorToDomRangeSafe(editor, range);
|
|
284
|
+
if (!domRange) {
|
|
285
|
+
return {
|
|
286
|
+
caretPosition: null,
|
|
287
|
+
selectionRects: []
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
const selectionRects = [];
|
|
291
|
+
const nodeIterator = import_slate2.Editor.nodes(editor, {
|
|
292
|
+
at: range,
|
|
293
|
+
match: (n, p) => import_slate2.Text.isText(n) && (!shouldGenerateOverlay || shouldGenerateOverlay(n, p))
|
|
294
|
+
});
|
|
295
|
+
let caretPosition = null;
|
|
296
|
+
const isBackward = import_slate2.Range.isBackward(range);
|
|
297
|
+
for (const [node, path] of nodeIterator) {
|
|
298
|
+
const domNode = import_slate_react4.ReactEditor.toDOMNode(editor, node);
|
|
299
|
+
const isStartNode = import_slate2.Path.equals(path, start.path);
|
|
300
|
+
const isEndNode = import_slate2.Path.equals(path, end.path);
|
|
301
|
+
let clientRects = null;
|
|
302
|
+
if (isStartNode || isEndNode) {
|
|
303
|
+
const nodeRange = document.createRange();
|
|
304
|
+
nodeRange.selectNode(domNode);
|
|
305
|
+
if (isStartNode) {
|
|
306
|
+
nodeRange.setStart(domRange.startContainer, domRange.startOffset);
|
|
307
|
+
}
|
|
308
|
+
if (isEndNode) {
|
|
309
|
+
nodeRange.setEnd(domRange.endContainer, domRange.endOffset);
|
|
310
|
+
}
|
|
311
|
+
clientRects = nodeRange.getClientRects();
|
|
312
|
+
} else {
|
|
313
|
+
clientRects = domNode.getClientRects();
|
|
314
|
+
}
|
|
315
|
+
const isCaret = isBackward ? isStartNode : isEndNode;
|
|
316
|
+
for (let i = 0; i < clientRects.length; i++) {
|
|
317
|
+
const clientRect = clientRects.item(i);
|
|
318
|
+
if (!clientRect) {
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
const isCaretRect = isCaret && (isBackward ? i === 0 : i === clientRects.length - 1);
|
|
322
|
+
const top = clientRect.top - yOffset;
|
|
323
|
+
const left = clientRect.left - xOffset;
|
|
324
|
+
if (isCaretRect) {
|
|
325
|
+
caretPosition = {
|
|
326
|
+
height: clientRect.height,
|
|
327
|
+
top,
|
|
328
|
+
left: left + (isBackward || import_slate2.Range.isCollapsed(range) ? 0 : clientRect.width)
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
selectionRects.push({
|
|
332
|
+
width: clientRect.width,
|
|
333
|
+
height: clientRect.height,
|
|
334
|
+
top,
|
|
335
|
+
left
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
selectionRects,
|
|
341
|
+
caretPosition
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// src/hooks/utils.ts
|
|
346
|
+
var import_react3 = require("react");
|
|
347
|
+
function useRequestRerender() {
|
|
348
|
+
const [, rerender] = (0, import_react3.useReducer)((s) => s + 1, 0);
|
|
349
|
+
const animationFrameIdRef = (0, import_react3.useRef)(null);
|
|
350
|
+
const clearAnimationFrame = () => {
|
|
351
|
+
if (animationFrameIdRef.current) {
|
|
352
|
+
cancelAnimationFrame(animationFrameIdRef.current);
|
|
353
|
+
animationFrameIdRef.current = 0;
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
(0, import_react3.useEffect)(clearAnimationFrame);
|
|
357
|
+
(0, import_react3.useEffect)(() => clearAnimationFrame, []);
|
|
358
|
+
return (0, import_react3.useCallback)((immediately = false) => {
|
|
359
|
+
if (immediately) {
|
|
360
|
+
rerender();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
if (animationFrameIdRef.current) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
animationFrameIdRef.current = requestAnimationFrame(rerender);
|
|
367
|
+
}, []);
|
|
368
|
+
}
|
|
369
|
+
function useOnResize(ref, onResize) {
|
|
370
|
+
const onResizeRef = (0, import_react3.useRef)(onResize);
|
|
371
|
+
onResizeRef.current = onResize;
|
|
372
|
+
const [observer] = (0, import_react3.useState)(() => new ResizeObserver(() => {
|
|
373
|
+
onResizeRef.current();
|
|
374
|
+
}));
|
|
375
|
+
(0, import_react3.useEffect)(() => {
|
|
376
|
+
if (!(ref == null ? void 0 : ref.current)) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
const { current: element } = ref;
|
|
380
|
+
observer.observe(element);
|
|
381
|
+
return () => observer.unobserve(element);
|
|
382
|
+
}, [observer, ref]);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// src/hooks/useRemoteCursorOverlayPositions.tsx
|
|
386
|
+
var FROZEN_EMPTY_ARRAY = Object.freeze([]);
|
|
387
|
+
function useRemoteCursorOverlayPositions(_a = {}) {
|
|
388
|
+
var _b = _a, {
|
|
389
|
+
containerRef,
|
|
390
|
+
shouldGenerateOverlay
|
|
391
|
+
} = _b, opts = __objRest(_b, [
|
|
392
|
+
"containerRef",
|
|
393
|
+
"shouldGenerateOverlay"
|
|
394
|
+
]);
|
|
395
|
+
var _a2;
|
|
396
|
+
const editor = useRemoteCursorEditor();
|
|
397
|
+
const cursorStates = useRemoteCursorStates();
|
|
398
|
+
const requestRerender = useRequestRerender();
|
|
399
|
+
const overlayPositionCache = (0, import_react4.useRef)(/* @__PURE__ */ new WeakMap());
|
|
400
|
+
const [overlayPositions, setOverlayPositions] = (0, import_react4.useState)({});
|
|
401
|
+
const refreshOnResize = "refreshOnResize" in opts ? (_a2 = opts.refreshOnResize) != null ? _a2 : true : true;
|
|
402
|
+
useOnResize(refreshOnResize ? containerRef : void 0, () => {
|
|
403
|
+
overlayPositionCache.current = /* @__PURE__ */ new WeakMap();
|
|
404
|
+
requestRerender(refreshOnResize !== "debounced");
|
|
405
|
+
});
|
|
406
|
+
(0, import_react4.useLayoutEffect)(() => {
|
|
407
|
+
var _a3, _b2, _c;
|
|
408
|
+
if (containerRef && !containerRef.current) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const containerRect = (_a3 = containerRef == null ? void 0 : containerRef.current) == null ? void 0 : _a3.getBoundingClientRect();
|
|
412
|
+
const xOffset = (_b2 = containerRect == null ? void 0 : containerRect.x) != null ? _b2 : 0;
|
|
413
|
+
const yOffset = (_c = containerRect == null ? void 0 : containerRect.y) != null ? _c : 0;
|
|
414
|
+
let overlayPositionsChanged = Object.keys(overlayPositions).length !== Object.keys(cursorStates).length;
|
|
415
|
+
const updated = Object.fromEntries(Object.entries(cursorStates).map(([key, state]) => {
|
|
416
|
+
const range = state.relativeSelection && getCursorRange(editor, state);
|
|
417
|
+
if (!range) {
|
|
418
|
+
return [key, FROZEN_EMPTY_ARRAY];
|
|
419
|
+
}
|
|
420
|
+
const cached = overlayPositionCache.current.get(range);
|
|
421
|
+
if (cached) {
|
|
422
|
+
return [key, cached];
|
|
423
|
+
}
|
|
424
|
+
const overlayPosition = getOverlayPosition(editor, range, {
|
|
425
|
+
xOffset,
|
|
426
|
+
yOffset,
|
|
427
|
+
shouldGenerateOverlay
|
|
428
|
+
});
|
|
429
|
+
overlayPositionsChanged = true;
|
|
430
|
+
overlayPositionCache.current.set(range, overlayPosition);
|
|
431
|
+
return [key, overlayPosition];
|
|
432
|
+
}));
|
|
433
|
+
if (overlayPositionsChanged) {
|
|
434
|
+
setOverlayPositions(updated);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
const overlayData = (0, import_react4.useMemo)(() => Object.entries(cursorStates).map(([clientId, state]) => {
|
|
438
|
+
var _a3, _b2;
|
|
439
|
+
const range = state.relativeSelection && getCursorRange(editor, state);
|
|
440
|
+
const overlayPosition = overlayPositions[clientId];
|
|
441
|
+
return __spreadProps(__spreadValues({}, state), {
|
|
442
|
+
range,
|
|
443
|
+
caretPosition: (_a3 = overlayPosition == null ? void 0 : overlayPosition.caretPosition) != null ? _a3 : null,
|
|
444
|
+
selectionRects: (_b2 = overlayPosition == null ? void 0 : overlayPosition.selectionRects) != null ? _b2 : FROZEN_EMPTY_ARRAY
|
|
445
|
+
});
|
|
446
|
+
}), [cursorStates, editor, overlayPositions]);
|
|
447
|
+
const refresh = (0, import_react4.useCallback)(() => {
|
|
448
|
+
overlayPositionCache.current = /* @__PURE__ */ new WeakMap();
|
|
449
|
+
requestRerender(true);
|
|
450
|
+
}, [requestRerender]);
|
|
451
|
+
return [overlayData, refresh];
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=index.cjs.map
|