Skip to content

packages/core/src/features/viz/lib/hover-data.tsx

Read as Markdown

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

Back to reference

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 built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.