@kerusiweb/react 2.0.0 → 2.2.0

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.
@@ -0,0 +1,74 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ /**
3
+ * Maximizing the map to fill the screen.
4
+ *
5
+ * The fixed-position layout is the whole feature on iPhone, which has no
6
+ * element full screen. Where the browser offers one it is requested on top,
7
+ * and followed: leaving it with the browser's own Esc un-maximizes the map, so
8
+ * the two never disagree.
9
+ */
10
+ export function useMaximized({ enabled, rootRef, onChange }) {
11
+ const [maximized, setMaximizedState] = useState(false);
12
+ const maximizedRef = useRef(false);
13
+ const nativeFullscreen = useRef(false);
14
+ const settings = useRef({ enabled, onChange });
15
+ settings.current = { enabled, onChange };
16
+ const setMaximized = useCallback((next) => {
17
+ if (next === maximizedRef.current || (next && !settings.current.enabled)) {
18
+ return;
19
+ }
20
+ maximizedRef.current = next;
21
+ setMaximizedState(next);
22
+ settings.current.onChange?.(next);
23
+ // Native full screen is requested here, inside the click that got us
24
+ // here, because browsers only grant it to a user gesture.
25
+ const root = rootRef.current;
26
+ const doc = root?.ownerDocument;
27
+ if (root && doc) {
28
+ if (next && !doc.fullscreenElement) {
29
+ root.requestFullscreen?.()?.catch(() => undefined);
30
+ }
31
+ else if (!next && doc.fullscreenElement === root) {
32
+ doc.exitFullscreen?.()?.catch(() => undefined);
33
+ }
34
+ }
35
+ }, [rootRef]);
36
+ const toggleMaximized = useCallback(() => setMaximized(!maximizedRef.current), [setMaximized]);
37
+ // `maximizable` switched off underneath a maximized map.
38
+ useEffect(() => {
39
+ if (!enabled && maximizedRef.current) {
40
+ setMaximized(false);
41
+ }
42
+ }, [enabled, setMaximized]);
43
+ // While maximized: freeze the page behind, and follow the browser leaving
44
+ // native full screen.
45
+ useEffect(() => {
46
+ const root = rootRef.current;
47
+ if (!maximized || !root) {
48
+ return;
49
+ }
50
+ const doc = root.ownerDocument;
51
+ const previousOverflow = doc.body.style.overflow;
52
+ doc.body.style.overflow = 'hidden';
53
+ const onFullscreenChange = () => {
54
+ if (doc.fullscreenElement === root) {
55
+ nativeFullscreen.current = true;
56
+ }
57
+ else if (nativeFullscreen.current) {
58
+ nativeFullscreen.current = false;
59
+ setMaximized(false);
60
+ }
61
+ };
62
+ doc.addEventListener('fullscreenchange', onFullscreenChange);
63
+ return () => {
64
+ doc.body.style.overflow = previousOverflow;
65
+ doc.removeEventListener('fullscreenchange', onFullscreenChange);
66
+ nativeFullscreen.current = false;
67
+ if (doc.fullscreenElement === root) {
68
+ doc.exitFullscreen?.()?.catch(() => undefined);
69
+ }
70
+ };
71
+ }, [maximized, rootRef, setMaximized]);
72
+ return { maximized, setMaximized, toggleMaximized };
73
+ }
74
+ //# sourceMappingURL=use-maximized.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-maximized.js","sourceRoot":"","sources":["../src/use-maximized.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAiBjE;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAuB;IAC9E,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAEzC,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAAa,EAAE,EAAE;QAChB,IAAI,IAAI,KAAK,YAAY,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACzE,OAAO;QACT,CAAC;QACD,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxB,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;QAElC,qEAAqE;QACrE,0DAA0D;QAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,EAAE,aAAa,CAAC;QAChC,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;gBACnC,IAAI,CAAC,iBAAiB,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACrD,CAAC;iBAAM,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBACnD,GAAG,CAAC,cAAc,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;IACH,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAE/F,yDAAyD;IACzD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACrC,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE5B,0EAA0E;IAC1E,sBAAsB;IACtB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC;QAC/B,MAAM,gBAAgB,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEnC,MAAM,kBAAkB,GAAG,GAAG,EAAE;YAC9B,IAAI,GAAG,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBACnC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC;YAClC,CAAC;iBAAM,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBACpC,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC;gBACjC,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC;QACF,GAAG,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;QAE7D,OAAO,GAAG,EAAE;YACV,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,gBAAgB,CAAC;YAC3C,GAAG,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;YAChE,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC;YACjC,IAAI,GAAG,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBACnC,GAAG,CAAC,cAAc,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAEvC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC;AACtD,CAAC"}
@@ -8,6 +8,8 @@ export interface RovingFocus {
8
8
  moveFocusTo(sectionId: string, seatId: string): void;
9
9
  /** Focuses a seat wherever it is, if it is currently rendered. */
10
10
  focusSeat(seatId: string): void;
11
+ /** A seat's `<g>`, if it is currently rendered. */
12
+ getSeatNode(seatId: string): SVGGElement | null;
11
13
  /** Ref callback each seat `<g>` registers itself through. */
12
14
  registerSeat(seatId: string, node: SVGGElement | null): void;
13
15
  }
@@ -23,5 +25,10 @@ export interface RovingFocus {
23
25
  * so they cannot be interpolated into a selector unescaped, and `CSS.escape` is
24
26
  * absent in jsdom and under SSR. A ref map has neither problem.
25
27
  */
26
- export declare function useRovingFocus(renderMap: RenderMap): RovingFocus;
28
+ export declare function useRovingFocus(renderMap: RenderMap,
29
+ /**
30
+ * Stop the browser scrolling a focused seat into view. A zoomable map moves
31
+ * by transform, and a browser scroll on top would fight it.
32
+ */
33
+ preventScroll?: boolean): RovingFocus;
27
34
  //# sourceMappingURL=use-roving-focus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-roving-focus.d.ts","sourceRoot":"","sources":["../src/use-roving-focus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,yFAAyF;IACzF,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,4DAA4D;IAC5D,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACrD,kEAAkE;IAClE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CA8DhE"}
1
+ {"version":3,"file":"use-roving-focus.d.ts","sourceRoot":"","sources":["../src/use-roving-focus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,yFAAyF;IACzF,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,4DAA4D;IAC5D,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACrD,kEAAkE;IAClE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mDAAmD;IACnD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IAChD,6DAA6D;IAC7D,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,SAAS;AACpB;;;GAGG;AACH,aAAa,UAAQ,GACpB,WAAW,CA2Eb"}
@@ -11,9 +11,16 @@ import { useCallback, useEffect, useRef, useState } from 'react';
11
11
  * so they cannot be interpolated into a selector unescaped, and `CSS.escape` is
12
12
  * absent in jsdom and under SSR. A ref map has neither problem.
13
13
  */
14
- export function useRovingFocus(renderMap) {
14
+ export function useRovingFocus(renderMap,
15
+ /**
16
+ * Stop the browser scrolling a focused seat into view. A zoomable map moves
17
+ * by transform, and a browser scroll on top would fight it.
18
+ */
19
+ preventScroll = false) {
15
20
  const [focusedSeatIds, setFocusedSeatIds] = useState({});
16
21
  const nodes = useRef(new Map());
22
+ const preventScrollRef = useRef(preventScroll);
23
+ preventScrollRef.current = preventScroll;
17
24
  /** Set when a keyboard move asks for focus, consumed after the commit. */
18
25
  const pendingFocus = useRef(null);
19
26
  // Keep every section's tab stop pointing at a seat that still exists.
@@ -41,9 +48,16 @@ export function useRovingFocus(renderMap) {
41
48
  nodes.current.delete(seatId);
42
49
  }
43
50
  }, []);
44
- const focusSeat = useCallback((seatId) => {
45
- nodes.current.get(seatId)?.focus?.();
51
+ const focusNode = useCallback((node) => {
52
+ if (preventScrollRef.current) {
53
+ node?.focus?.({ preventScroll: true });
54
+ }
55
+ else {
56
+ node?.focus?.();
57
+ }
46
58
  }, []);
59
+ const focusSeat = useCallback((seatId) => focusNode(nodes.current.get(seatId)), [focusNode]);
60
+ const getSeatNode = useCallback((seatId) => nodes.current.get(seatId) ?? null, []);
47
61
  const setFocusedSeat = useCallback((sectionId, seatId) => {
48
62
  setFocusedSeatIds((all) => (all[sectionId] === seatId ? all : { ...all, [sectionId]: seatId }));
49
63
  }, []);
@@ -58,9 +72,9 @@ export function useRovingFocus(renderMap) {
58
72
  const target = pendingFocus.current;
59
73
  if (target !== null) {
60
74
  pendingFocus.current = null;
61
- nodes.current.get(target)?.focus?.();
75
+ focusNode(nodes.current.get(target));
62
76
  }
63
- }, [focusedSeatIds]);
64
- return { focusedSeatIds, setFocusedSeat, moveFocusTo, focusSeat, registerSeat };
77
+ }, [focusedSeatIds, focusNode]);
78
+ return { focusedSeatIds, setFocusedSeat, moveFocusTo, focusSeat, getSeatNode, registerSeat };
65
79
  }
66
80
  //# sourceMappingURL=use-roving-focus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-roving-focus.js","sourceRoot":"","sources":["../src/use-roving-focus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-roving-focus.js","sourceRoot":"","sources":["../src/use-roving-focus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { KerusiViewport, ViewportLimits } from '@kerusiweb/core';
2
+ import type { RefObject } from 'react';
3
+ export interface UseViewportOptions {
4
+ /** The map's `zoomable` prop. When false nothing is attached and the viewport is fit. */
5
+ enabled: boolean;
6
+ maxZoom: number;
7
+ onViewportChange?: (viewport: KerusiViewport) => void;
8
+ }
9
+ /** The slice of a key event {@link ViewportControls.handleKeyDown} reads. */
10
+ export interface ViewportKeyEvent {
11
+ key: string;
12
+ ctrlKey: boolean;
13
+ metaKey: boolean;
14
+ altKey: boolean;
15
+ target: EventTarget | null;
16
+ }
17
+ export interface ViewportControls {
18
+ viewport: KerusiViewport;
19
+ /** True for a discrete change (button, key, reveal), false while a finger or wheel drives. */
20
+ animated: boolean;
21
+ limits: ViewportLimits;
22
+ /** Attach to the clipping window. */
23
+ viewRef: RefObject<HTMLDivElement | null>;
24
+ /** Attach to the element the transform is applied to. */
25
+ contentRef: RefObject<HTMLDivElement | null>;
26
+ zoomIn(): void;
27
+ zoomOut(): void;
28
+ resetZoom(): void;
29
+ /** Pans a keyboard-focused seat into view. */
30
+ revealSeat(node: Element | null): void;
31
+ /** Applies `+` `-` `0` and, when the viewport has focus, the arrows. True if it acted. */
32
+ handleKeyDown(event: ViewportKeyEvent): boolean;
33
+ }
34
+ /**
35
+ * The zoom and pan of a `zoomable` map.
36
+ *
37
+ * What a wheel tick, a pinch or a key means is `@kerusiweb/core`'s; this hook
38
+ * supplies the React half: state to render from, a ref for the value the
39
+ * native listeners read between renders, and the listeners themselves. They
40
+ * are native, not `onWheel` / `onClick` props, for two reasons React's
41
+ * synthetic events cannot meet: wheel must be non-passive to `preventDefault`
42
+ * a page zoom, and the click that ends a drag must be stopped in the capture
43
+ * phase, before it reaches the seat.
44
+ */
45
+ export declare function useViewport({ enabled, maxZoom, onViewportChange, }: UseViewportOptions): ViewportControls;
46
+ //# sourceMappingURL=use-viewport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-viewport.d.ts","sourceRoot":"","sources":["../src/use-viewport.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAGV,cAAc,EACd,cAAc,EAGf,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,kBAAkB;IACjC,yFAAyF;IACzF,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;CACvD;AAED,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,qCAAqC;IACrC,OAAO,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1C,yDAAyD;IACzD,UAAU,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC7C,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,SAAS,IAAI,IAAI,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IACvC,0FAA0F;IAC1F,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC;CACjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,OAAO,EACP,gBAAgB,GACjB,EAAE,kBAAkB,GAAG,gBAAgB,CA8UvC"}
@@ -0,0 +1,269 @@
1
+ import { clampViewport, FIT_VIEWPORT, fitViewport, IDLE_GESTURE, keyboardViewport, reduceGesture, revealRect, stepViewport, viewportsEqual, wheelZoomFactor, zoomLimits, zoomViewportBy, zoomViewportTo, } from '@kerusiweb/core';
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ /**
4
+ * The zoom and pan of a `zoomable` map.
5
+ *
6
+ * What a wheel tick, a pinch or a key means is `@kerusiweb/core`'s; this hook
7
+ * supplies the React half: state to render from, a ref for the value the
8
+ * native listeners read between renders, and the listeners themselves. They
9
+ * are native, not `onWheel` / `onClick` props, for two reasons React's
10
+ * synthetic events cannot meet: wheel must be non-passive to `preventDefault`
11
+ * a page zoom, and the click that ends a drag must be stopped in the capture
12
+ * phase, before it reaches the seat.
13
+ */
14
+ export function useViewport({ enabled, maxZoom, onViewportChange, }) {
15
+ const limits = useMemo(() => zoomLimits(maxZoom), [maxZoom]);
16
+ const [viewport, setViewport] = useState(FIT_VIEWPORT);
17
+ const [animated, setAnimated] = useState(false);
18
+ const viewRef = useRef(null);
19
+ const contentRef = useRef(null);
20
+ /**
21
+ * The truth between renders. Several wheel events can land before React
22
+ * re-renders, and each must start from the one before.
23
+ */
24
+ const viewportRef = useRef(FIT_VIEWPORT);
25
+ const settings = useRef({ enabled, limits, onViewportChange });
26
+ settings.current = { enabled, limits, onViewportChange };
27
+ const commit = useCallback((next, animate) => {
28
+ if (viewportsEqual(next, viewportRef.current)) {
29
+ return;
30
+ }
31
+ viewportRef.current = next;
32
+ setAnimated(animate);
33
+ setViewport(next);
34
+ settings.current.onViewportChange?.(next);
35
+ }, []);
36
+ /** Sizes in CSS pixels, read when needed: `offset*` ignores the zoom transform. */
37
+ const measure = useCallback(() => {
38
+ const view = viewRef.current;
39
+ const content = contentRef.current;
40
+ if (!view || !content) {
41
+ return null;
42
+ }
43
+ return {
44
+ container: { width: view.clientWidth, height: view.clientHeight },
45
+ content: { width: content.offsetWidth, height: content.offsetHeight },
46
+ };
47
+ }, []);
48
+ const stepZoom = useCallback((direction) => {
49
+ const measured = measure();
50
+ if (measured && settings.current.enabled) {
51
+ commit(stepViewport(viewportRef.current, direction, measured.content, measured.container, settings.current.limits), true);
52
+ }
53
+ }, [commit, measure]);
54
+ const zoomIn = useCallback(() => stepZoom(1), [stepZoom]);
55
+ const zoomOut = useCallback(() => stepZoom(-1), [stepZoom]);
56
+ const resetZoom = useCallback(() => {
57
+ const measured = measure();
58
+ if (measured && settings.current.enabled) {
59
+ commit(fitViewport(measured.content, measured.container, settings.current.limits), true);
60
+ }
61
+ }, [commit, measure]);
62
+ const reclamp = useCallback(() => {
63
+ const measured = measure();
64
+ if (measured && settings.current.enabled) {
65
+ commit(clampViewport(viewportRef.current, measured.content, measured.container, settings.current.limits), false);
66
+ }
67
+ }, [commit, measure]);
68
+ // Re-clamp when the box or the ceiling changes: a rotated phone, a maximized
69
+ // map, a lowered `maxZoom`.
70
+ useEffect(() => {
71
+ if (!enabled) {
72
+ return;
73
+ }
74
+ reclamp();
75
+ const view = viewRef.current;
76
+ if (!view || typeof ResizeObserver === 'undefined') {
77
+ return;
78
+ }
79
+ const observer = new ResizeObserver(() => reclamp());
80
+ observer.observe(view);
81
+ if (contentRef.current) {
82
+ observer.observe(contentRef.current);
83
+ }
84
+ return () => observer.disconnect();
85
+ }, [enabled, limits, reclamp]);
86
+ // Switching `zoomable` off puts the map back as it was.
87
+ useEffect(() => {
88
+ if (!enabled && !viewportsEqual(viewportRef.current, FIT_VIEWPORT)) {
89
+ viewportRef.current = FIT_VIEWPORT;
90
+ setViewport(FIT_VIEWPORT);
91
+ }
92
+ }, [enabled]);
93
+ // --- pointer, wheel and trackpad listeners --------------------------------
94
+ useEffect(() => {
95
+ const view = viewRef.current;
96
+ if (!enabled || !view) {
97
+ return;
98
+ }
99
+ let gesture = IDLE_GESTURE;
100
+ let suppressClick = false;
101
+ let gestureBase = null;
102
+ const containerPoint = (event) => {
103
+ const box = view.getBoundingClientRect();
104
+ return { x: event.clientX - box.left, y: event.clientY - box.top };
105
+ };
106
+ const feed = (event) => {
107
+ const measured = measure();
108
+ if (!measured) {
109
+ return;
110
+ }
111
+ const result = reduceGesture(gesture, event, {
112
+ viewport: viewportRef.current,
113
+ content: measured.content,
114
+ container: measured.container,
115
+ limits: settings.current.limits,
116
+ });
117
+ gesture = result.state;
118
+ // Capture only once a tap has become a gesture: capturing on `down` would
119
+ // retarget the tap's click away from the seat.
120
+ if (result.capture) {
121
+ for (const id of result.state.ids) {
122
+ try {
123
+ view.setPointerCapture(id);
124
+ }
125
+ catch {
126
+ // The pointer already ended, or there is no capture here.
127
+ }
128
+ }
129
+ }
130
+ if (result.viewport !== viewportRef.current) {
131
+ commit(result.viewport, false);
132
+ }
133
+ if (result.suppressClick) {
134
+ // The click a drag ends with arrives right after `pointerup`, before this timer.
135
+ suppressClick = true;
136
+ setTimeout(() => {
137
+ suppressClick = false;
138
+ });
139
+ }
140
+ };
141
+ const onPointerDown = (e) => {
142
+ if (e.pointerType === 'mouse' && e.button !== 0) {
143
+ return;
144
+ }
145
+ suppressClick = false;
146
+ feed({ type: 'down', id: e.pointerId, point: containerPoint(e) });
147
+ };
148
+ const onPointerMove = (e) => {
149
+ if (gesture.ids.length > 0) {
150
+ feed({ type: 'move', id: e.pointerId, point: containerPoint(e) });
151
+ }
152
+ };
153
+ const onPointerUp = (e) => feed({ type: 'up', id: e.pointerId });
154
+ const onPointerCancel = (e) => feed({ type: 'cancel', id: e.pointerId });
155
+ const onClick = (e) => {
156
+ if (suppressClick) {
157
+ suppressClick = false;
158
+ e.stopPropagation();
159
+ e.preventDefault();
160
+ }
161
+ };
162
+ const onWheel = (e) => {
163
+ const factor = wheelZoomFactor(e);
164
+ const measured = measure();
165
+ if (factor === null || !measured) {
166
+ return; // A plain wheel is the page's to scroll.
167
+ }
168
+ e.preventDefault();
169
+ commit(zoomViewportBy(viewportRef.current, factor, containerPoint(e), measured.content, measured.container, settings.current.limits), false);
170
+ };
171
+ // Safari reports a trackpad pinch as gesture events, not Ctrl + wheel.
172
+ const onGestureStart = (e) => {
173
+ e.preventDefault();
174
+ gestureBase = viewportRef.current;
175
+ };
176
+ const onGestureChange = (e) => {
177
+ e.preventDefault();
178
+ const measured = measure();
179
+ const { scale, clientX, clientY } = e;
180
+ if (!gestureBase || !measured) {
181
+ return;
182
+ }
183
+ commit(zoomViewportTo(gestureBase, gestureBase.zoom * scale, containerPoint({ clientX, clientY }), measured.content, measured.container, settings.current.limits), false);
184
+ };
185
+ const onGestureEnd = (e) => {
186
+ e.preventDefault();
187
+ gestureBase = null;
188
+ };
189
+ const listeners = [
190
+ ['pointerdown', onPointerDown, false],
191
+ ['pointermove', onPointerMove, false],
192
+ ['pointerup', onPointerUp, false],
193
+ ['pointercancel', onPointerCancel, false],
194
+ ['wheel', onWheel, { passive: false }],
195
+ ['click', onClick, true],
196
+ ['gesturestart', onGestureStart, { passive: false }],
197
+ ['gesturechange', onGestureChange, { passive: false }],
198
+ ['gestureend', onGestureEnd, { passive: false }],
199
+ ];
200
+ for (const [type, listener, options] of listeners) {
201
+ view.addEventListener(type, listener, options);
202
+ }
203
+ return () => {
204
+ for (const [type, listener, options] of listeners) {
205
+ view.removeEventListener(type, listener, options);
206
+ }
207
+ };
208
+ }, [enabled, commit, measure]);
209
+ // --- keyboard and focus ---------------------------------------------------
210
+ const handleKeyDown = useCallback((event) => {
211
+ const measured = measure();
212
+ if (!settings.current.enabled || !measured) {
213
+ return false;
214
+ }
215
+ const next = keyboardViewport(viewportRef.current, {
216
+ key: event.key,
217
+ ctrlKey: event.ctrlKey,
218
+ metaKey: event.metaKey,
219
+ altKey: event.altKey,
220
+ viewportFocused: event.target === viewRef.current,
221
+ }, measured.content, measured.container, settings.current.limits);
222
+ if (!next) {
223
+ return false;
224
+ }
225
+ commit(next, true);
226
+ return true;
227
+ }, [commit, measure]);
228
+ /**
229
+ * A click or tap also focuses a seat, but should not move the map under the
230
+ * finger, so only a `:focus-visible` focus counts.
231
+ */
232
+ const revealSeat = useCallback((node) => {
233
+ const view = viewRef.current;
234
+ const measured = measure();
235
+ if (!settings.current.enabled || !view || !node || !measured || !focusIsVisible(node)) {
236
+ return;
237
+ }
238
+ const seat = node.getBoundingClientRect();
239
+ const frame = view.getBoundingClientRect();
240
+ commit(revealRect(viewportRef.current, {
241
+ x: seat.left - frame.left,
242
+ y: seat.top - frame.top,
243
+ width: seat.width,
244
+ height: seat.height,
245
+ }, measured.content, measured.container, undefined, settings.current.limits), true);
246
+ }, [commit, measure]);
247
+ return {
248
+ viewport,
249
+ animated,
250
+ limits,
251
+ viewRef,
252
+ contentRef,
253
+ zoomIn,
254
+ zoomOut,
255
+ resetZoom,
256
+ revealSeat,
257
+ handleKeyDown,
258
+ };
259
+ }
260
+ /** `:focus-visible` where the engine knows it; otherwise assume the focus is the keyboard's. */
261
+ function focusIsVisible(node) {
262
+ try {
263
+ return node.matches(':focus-visible');
264
+ }
265
+ catch {
266
+ return true;
267
+ }
268
+ }
269
+ //# sourceMappingURL=use-viewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-viewport.js","sourceRoot":"","sources":["../src/use-viewport.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,52 +1,52 @@
1
- {
2
- "name": "@kerusiweb/react",
3
- "version": "2.0.0",
4
- "description": "A React seat-map component that renders Kerusi Seat Map & Availability Format documents as interactive, accessible inline SVG.",
5
- "keywords": [
6
- "react",
7
- "kerusi",
8
- "seat-map",
9
- "seatmap",
10
- "seat-picker",
11
- "seat-selection",
12
- "svg",
13
- "booking",
14
- "ticketing",
15
- "cinema",
16
- "airline",
17
- "venue"
18
- ],
19
- "license": "MIT",
20
- "author": "Arsyad \"Shad Ahm\" Ahmad",
21
- "repository": {
22
- "type": "git",
23
- "url": "https://github.com/ShadAhm/kerusiweb.git",
24
- "directory": "projects/react"
25
- },
26
- "homepage": "https://github.com/ShadAhm/kerusiweb",
27
- "type": "module",
28
- "sideEffects": [
29
- "*.css"
30
- ],
31
- "exports": {
32
- ".": {
33
- "types": "./dist/public-api.d.ts",
34
- "default": "./dist/public-api.js"
35
- },
36
- "./styles.css": "./styles.css",
37
- "./package.json": "./package.json"
38
- },
39
- "types": "./dist/public-api.d.ts",
40
- "main": "./dist/public-api.js",
41
- "files": [
42
- "dist",
43
- "styles.css"
44
- ],
45
- "peerDependencies": {
46
- "@kerusiweb/core": "^2.0.0",
47
- "react": "^18.3.0 || ^19.0.0"
48
- },
49
- "publishConfig": {
50
- "access": "public"
51
- }
52
- }
1
+ {
2
+ "name": "@kerusiweb/react",
3
+ "version": "2.2.0",
4
+ "description": "A React seat-map component that renders Kerusi Seat Map & Availability Format documents as interactive, accessible inline SVG.",
5
+ "keywords": [
6
+ "react",
7
+ "kerusi",
8
+ "seat-map",
9
+ "seatmap",
10
+ "seat-picker",
11
+ "seat-selection",
12
+ "svg",
13
+ "booking",
14
+ "ticketing",
15
+ "cinema",
16
+ "airline",
17
+ "venue"
18
+ ],
19
+ "license": "MIT",
20
+ "author": "Arsyad \"Shad Ahm\" Ahmad",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/ShadAhm/kerusiweb.git",
24
+ "directory": "projects/react"
25
+ },
26
+ "homepage": "https://github.com/ShadAhm/kerusiweb",
27
+ "type": "module",
28
+ "sideEffects": [
29
+ "*.css"
30
+ ],
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/public-api.d.ts",
34
+ "default": "./dist/public-api.js"
35
+ },
36
+ "./styles.css": "./styles.css",
37
+ "./package.json": "./package.json"
38
+ },
39
+ "types": "./dist/public-api.d.ts",
40
+ "main": "./dist/public-api.js",
41
+ "files": [
42
+ "dist",
43
+ "styles.css"
44
+ ],
45
+ "peerDependencies": {
46
+ "@kerusiweb/core": "^2.2.0",
47
+ "react": "^18.3.0 || ^19.0.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }