packages/core/src/features/viz/lib/hover-data.tsx
This is the source snapshot used to build these API details. View this revision on GitHub.
1 import type { PibblNode } from "@pibbl/core";
2 import { withHooksForbidden } from "@pibbl/core/internal";
3 import type { HoverDataProps, HoverQueryContext } from "./hover-types.js";
4 import type { ResolvedContinuousScale, ScaleId } from "./types.js";
5 import { readScale } from "./scale-context.js";
6 /**
7 * Evaluates an ordinary synchronous query under the current scale scope.
8 *
9 * @param props - Hover query and child renderer receiving its result. See {@link HoverDataProps}.
10 * @returns Content rendered from the current hover query result. See {@link PibblNode}.
11 *
12 * @see {@link HoverDataProps}
13 * @see {@link PibblNode}
14 */
15 export function HoverData<T>({ query, children }: HoverDataProps<T>): PibblNode {
16 if (typeof query !== "function" || typeof children !== "function")
17 throw new TypeError("HoverData requires query and children functions.");
18 const snapshots = new Map<ScaleId, ResolvedContinuousScale>();
19 let active = true;
20 const context: HoverQueryContext = {
21 scale(id) {
22 if (!active)
23 throw new Error(
24 "HoverData query context cannot be retained outside its invocation.",
25 );
26 let snapshot = snapshots.get(id);
27 if (!snapshot) {
28 const value = readScale(id, "HoverData");
29 if (!value) throw new TypeError("HoverData requires a scale ID.");
30 const resolved = value.get();
31 if (resolved.type === "band" || resolved.type === "point")
32 throw new TypeError(
33 "HoverData numeric queries require continuous scales.",
34 );
35 snapshot = resolved;
36 snapshots.set(id, snapshot);
37 }
38 return snapshot;
39 },
40 };
41 let result: T | undefined;
42 try {
43 result = withHooksForbidden(
44 "Pibbl hooks cannot be called inside a HoverData query.",
45 () => query(context),
46 );
47 if (
48 result != null &&
49 (typeof result === "object" || typeof result === "function") &&
50 typeof (result as { then?: unknown }).then === "function"
51 )
52 throw new TypeError(
53 "HoverData query must be synchronous; promises are unsupported.",
54 );
55 } finally {
56 active = false;
57 }
58 return withHooksForbidden(
59 "Pibbl hooks cannot be called inside a HoverData render callback; return a component instead.",
60 () => children(result),
61 );
62 }
63
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.