|
1 | | -import { useEffect } from "react"; |
2 | | -import { UseFloatingOptions } from "@floating-ui/react"; |
3 | | -import { |
4 | | - OpenAtCursorContext, |
5 | | - openedAtCursorChange$, |
6 | | -} from "@web/common/context/open-at-cursor"; |
7 | | -import { useMetaContext } from "@web/common/hooks/useMetaContext"; |
8 | | - |
9 | | -export function useOpenAtCursor({ |
10 | | - onOpenChange, |
11 | | -}: Pick<UseFloatingOptions, "onOpenChange"> = {}) { |
12 | | - const context = useMetaContext(OpenAtCursorContext, "useOpenAtCursor"); |
| 1 | +import { useEffect, useState } from "react"; |
| 2 | +import { BehaviorSubject, Observable, distinctUntilChanged, share } from "rxjs"; |
| 3 | +import { Placement, Strategy } from "@floating-ui/react"; |
| 4 | + |
| 5 | +export enum CursorItem { |
| 6 | + EventForm = "EventForm", |
| 7 | + EventPreview = "EventPreview", |
| 8 | + EventContextMenu = "EventContextMenu", |
| 9 | +} |
| 10 | + |
| 11 | +const nodeId$ = new BehaviorSubject<CursorItem | null>(null); |
| 12 | +const placement$ = new BehaviorSubject<Placement>("right-start"); |
| 13 | +const strategy$ = new BehaviorSubject<Strategy>("absolute"); |
| 14 | +const reference$ = new BehaviorSubject<Element | null>(null); |
| 15 | +const $nodeId = nodeId$.pipe(distinctUntilChanged(), share()); |
| 16 | +const $placement = placement$.pipe(distinctUntilChanged(), share()); |
| 17 | +const $strategy = strategy$.pipe(distinctUntilChanged(), share()); |
| 18 | +const $reference = reference$.pipe(distinctUntilChanged(), share()); |
| 19 | + |
| 20 | +function useValue<T>( |
| 21 | + subject: BehaviorSubject<T>, |
| 22 | + sharedSubject: Observable<T>, |
| 23 | +): T { |
| 24 | + const [value, setValue] = useState<T>(subject.getValue()); |
13 | 25 |
|
14 | 26 | useEffect(() => { |
15 | | - if (onOpenChange) { |
16 | | - const subscription = openedAtCursorChange$.subscribe((args) => |
17 | | - onOpenChange(...args), |
18 | | - ); |
| 27 | + const subscription = sharedSubject.subscribe((v) => { |
| 28 | + setValue(v); |
| 29 | + }); |
| 30 | + |
| 31 | + return () => subscription.unsubscribe(); |
| 32 | + }); |
| 33 | + |
| 34 | + return value; |
| 35 | +} |
| 36 | + |
| 37 | +export function useFloatingNodeIdAtCursor(): CursorItem | null { |
| 38 | + return useValue<CursorItem | null>(nodeId$, $nodeId); |
| 39 | +} |
| 40 | + |
| 41 | +export function useFloatingPlacementAtCursor(): Placement { |
| 42 | + return useValue<Placement>(placement$, $placement); |
| 43 | +} |
| 44 | + |
| 45 | +export function useFloatingStrategyAtCursor(): Strategy { |
| 46 | + return useValue<Strategy>(strategy$, $strategy); |
| 47 | +} |
| 48 | + |
| 49 | +export function useFloatingReferenceAtCursor(): Element | null { |
| 50 | + return useValue<Element | null>(reference$, $reference); |
| 51 | +} |
| 52 | + |
| 53 | +export function setFloatingNodeIdAtCursor(nodeId: CursorItem | null) { |
| 54 | + nodeId$.next(nodeId); |
| 55 | +} |
| 56 | + |
| 57 | +export function setFloatingPlacementAtCursor(placement: Placement) { |
| 58 | + placement$.next(placement); |
| 59 | +} |
| 60 | + |
| 61 | +export function setFloatingStrategyAtCursor(strategy: Strategy) { |
| 62 | + strategy$.next(strategy); |
| 63 | +} |
19 | 64 |
|
20 | | - return () => subscription.unsubscribe(); |
21 | | - } |
22 | | - }, [onOpenChange]); |
| 65 | +export function setFloatingReferenceAtCursor(reference: Element | null) { |
| 66 | + reference$.next(reference); |
| 67 | +} |
| 68 | + |
| 69 | +export function openFloatingAtCursor({ |
| 70 | + nodeId, |
| 71 | + reference, |
| 72 | + placement = "right-start", |
| 73 | + strategy = "absolute", |
| 74 | +}: { |
| 75 | + nodeId: CursorItem; |
| 76 | + reference: Element; |
| 77 | + placement?: Placement; |
| 78 | + strategy?: Strategy; |
| 79 | +}) { |
| 80 | + setFloatingNodeIdAtCursor(nodeId); |
| 81 | + setFloatingPlacementAtCursor(placement); |
| 82 | + setFloatingStrategyAtCursor(strategy); |
| 83 | + setFloatingReferenceAtCursor(reference); |
| 84 | +} |
23 | 85 |
|
24 | | - return context; |
| 86 | +export function closeFloatingAtCursor() { |
| 87 | + setFloatingNodeIdAtCursor(null); |
| 88 | + setFloatingPlacementAtCursor("right-start"); |
| 89 | + setFloatingReferenceAtCursor(null); |
25 | 90 | } |
0 commit comments