Skip to content

packages/core/src/lib/hooks/use-cursor.ts

Read as Markdown

This is the source snapshot used to build these API details. View this revision on GitHub.

Back to reference

1 import { getInteractionRoot } from '../global-state.js';
2 import type { PathGeometry } from '../geometry/path-geometry.js';
3 import {
4   refreshCursorDefault,
5   removeCursorDefault,
6   updateCursorDefault,
7 } from '../events/dispatch.js';
8 import type {
9   PibblCursorDefault,
10   PibblInteractionRegion,
11 } from '../types.js';
12 import { requireHookContext, useHookSlot } from './hook-slot.js';
13 import { createRegion, releaseRegion, updateRegion } from './use-region.js';
14 
15 interface PibblCursorDefaultSlot {
16   cursorDefault: PibblCursorDefault;
17   region: PibblInteractionRegion;
18 }
19 
20 /**
21  * Hook: wires a CSS cursor to the same logical target resolver used by mouse
22  * events. The cursor is released when this hook slot is replaced or removed.
23  *
24  * @param options - Cursor style and optional fill or stroke hit region for the current component.
25  * See {@link PathGeometry} .
26  *
27  * @see {@link PathGeometry}
28  */
29 export function useCursor({
30   path,
31   style,
32   fill = false,
33   lineInteractionWidth = 0,
34 }: {
35   path?: Path2D | PathGeometry;
36   style?: string;
37   fill?: boolean;
38   lineInteractionWidth?: number;
39 }): void {
40   const { pibblInstance } = requireHookContext();
41   const interactionRoot = getInteractionRoot(pibblInstance);
42   const slot = useHookSlot<PibblCursorDefaultSlot>('cursor', teardowns => {
43     const cursorDefault = { style: '' };
44     const region = createRegion(pibblInstance);
45     teardowns.add(() => {
46       removeCursorDefault(interactionRoot, cursorDefault);
47       releaseRegion(pibblInstance, region);
48     });
49     return { cursorDefault, region };
50   });
51 
52   const { cursorDefault, region } = slot.value;
53   if (path) {
54     removeCursorDefault(interactionRoot, cursorDefault);
55     updateRegion(pibblInstance, region, {
56       path,
57       cursor: style,
58       fill,
59       lineInteractionWidth,
60     });
61     return;
62   }
63 
64   releaseRegion(pibblInstance, region);
65   interactionRoot.cursorDefaults.delete(cursorDefault);
66   if (!style) {
67     removeCursorDefault(interactionRoot, cursorDefault);
68     return;
69   }
70 
71   cursorDefault.style = style;
72   interactionRoot.cursorDefaults.add(cursorDefault);
73   updateCursorDefault(interactionRoot, cursorDefault);
74   refreshCursorDefault(interactionRoot);
75 }
76 

Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.