@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.
Files changed (47) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +3 -0
  3. package/dist/hooks/useDecorateRemoteCursors.d.ts +24 -0
  4. package/dist/hooks/useDecorateRemoteCursors.d.ts.map +1 -0
  5. package/dist/hooks/useRemoteCursorEditor.d.ts +4 -0
  6. package/dist/hooks/useRemoteCursorEditor.d.ts.map +1 -0
  7. package/dist/hooks/useRemoteCursorOverlayPositions.d.ts +19 -0
  8. package/dist/hooks/useRemoteCursorOverlayPositions.d.ts.map +1 -0
  9. package/dist/hooks/useRemoteCursorStateStore.d.ts +5 -0
  10. package/dist/hooks/useRemoteCursorStateStore.d.ts.map +1 -0
  11. package/dist/hooks/useRemoteCursorStates.d.ts +4 -0
  12. package/dist/hooks/useRemoteCursorStates.d.ts.map +1 -0
  13. package/dist/hooks/useUnsetCursorPositionOnBlur.d.ts +2 -0
  14. package/dist/hooks/useUnsetCursorPositionOnBlur.d.ts.map +1 -0
  15. package/dist/hooks/utils.d.ts +4 -0
  16. package/dist/hooks/utils.d.ts.map +1 -0
  17. package/dist/index.cjs +453 -0
  18. package/dist/index.cjs.map +1 -0
  19. package/dist/index.d.ts +6 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.global.js +31900 -0
  22. package/dist/index.global.js.map +1 -0
  23. package/dist/index.js +450 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/types.d.ts +5 -0
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/utils/getCursorRange.d.ts +4 -0
  28. package/dist/utils/getCursorRange.d.ts.map +1 -0
  29. package/dist/utils/getOverlayPosition.d.ts +24 -0
  30. package/dist/utils/getOverlayPosition.d.ts.map +1 -0
  31. package/dist/utils/react-editor-to-dom-range-safe.d.ts +4 -0
  32. package/dist/utils/react-editor-to-dom-range-safe.d.ts.map +1 -0
  33. package/package.json +55 -0
  34. package/src/hooks/useDecorateRemoteCursors.ts +125 -0
  35. package/src/hooks/useRemoteCursorEditor.ts +15 -0
  36. package/src/hooks/useRemoteCursorOverlayPositions.tsx +144 -0
  37. package/src/hooks/useRemoteCursorStateStore.ts +89 -0
  38. package/src/hooks/useRemoteCursorStates.ts +28 -0
  39. package/src/hooks/useUnsetCursorPositionOnBlur.ts +48 -0
  40. package/src/hooks/utils.ts +61 -0
  41. package/src/index.ts +26 -0
  42. package/src/types.ts +4 -0
  43. package/src/utils/getCursorRange.ts +45 -0
  44. package/src/utils/getOverlayPosition.ts +111 -0
  45. package/src/utils/react-editor-to-dom-range-safe.ts +13 -0
  46. package/tsconfig.json +11 -0
  47. 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,3 @@
1
+ This package contains React specific components/utils for slate-yjs. Feel free to poke around to learn more!
2
+
3
+ Docs: https://docs.slate-yjs.dev/api/slate-yjs-react
@@ -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,2 @@
1
+ export declare function useUnsetCursorPositionOnBlur(): void;
2
+ //# sourceMappingURL=useUnsetCursorPositionOnBlur.d.ts.map
@@ -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,4 @@
1
+ import { RefObject } from 'react';
2
+ export declare function useRequestRerender(): (immediately?: any) => void;
3
+ export declare function useOnResize<T extends HTMLElement>(ref: RefObject<T> | undefined, onResize: () => void): void;
4
+ //# sourceMappingURL=utils.d.ts.map
@@ -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