@vllnt/ui 0.2.1-canary.e1bc2b3 → 0.2.1-canary.ee942df

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.
Files changed (137) hide show
  1. package/dist/components/agent-activity/agent-activity.js +311 -0
  2. package/dist/components/agent-activity/index.js +18 -0
  3. package/dist/components/ai-artifact/ai-artifact.js +422 -0
  4. package/dist/components/ai-artifact/index.js +24 -0
  5. package/dist/components/ai-sidebar/ai-sidebar.js +254 -0
  6. package/dist/components/ai-sidebar/index.js +22 -0
  7. package/dist/components/alert-pulse/alert-pulse.js +93 -0
  8. package/dist/components/alert-pulse/index.js +6 -0
  9. package/dist/components/auto-reload/auto-reload.js +367 -0
  10. package/dist/components/auto-reload/index.js +6 -0
  11. package/dist/components/banner/banner.js +155 -0
  12. package/dist/components/banner/index.js +10 -0
  13. package/dist/components/bottom-activity-strip/bottom-activity-strip.js +91 -0
  14. package/dist/components/bottom-activity-strip/index.js +6 -0
  15. package/dist/components/choropleth-map/choropleth-map.js +373 -0
  16. package/dist/components/choropleth-map/index.js +10 -0
  17. package/dist/components/chronological-timeline/chronological-timeline.js +337 -0
  18. package/dist/components/chronological-timeline/index.js +8 -0
  19. package/dist/components/civilization-card/civilization-card.js +258 -0
  20. package/dist/components/civilization-card/index.js +8 -0
  21. package/dist/components/comment-pin/comment-pin.js +104 -0
  22. package/dist/components/comment-pin/index.js +6 -0
  23. package/dist/components/context-lens/context-lens.js +98 -0
  24. package/dist/components/context-lens/index.js +6 -0
  25. package/dist/components/copy-button/copy-button.js +189 -0
  26. package/dist/components/copy-button/index.js +8 -0
  27. package/dist/components/document-sibling-nav/document-sibling-nav.js +111 -0
  28. package/dist/components/document-sibling-nav/index.js +8 -0
  29. package/dist/components/empty-state/empty-state.js +93 -0
  30. package/dist/components/empty-state/index.js +8 -0
  31. package/dist/components/era-comparison/era-comparison.js +198 -0
  32. package/dist/components/era-comparison/index.js +16 -0
  33. package/dist/components/floating-toolbar/floating-toolbar.js +66 -0
  34. package/dist/components/floating-toolbar/index.js +6 -0
  35. package/dist/components/follow-mode/follow-mode.js +89 -0
  36. package/dist/components/follow-mode/index.js +6 -0
  37. package/dist/components/gantt-chart/gantt-chart.js +331 -0
  38. package/dist/components/gantt-chart/index.js +6 -0
  39. package/dist/components/geography-quiz-map/geography-quiz-map.js +343 -0
  40. package/dist/components/geography-quiz-map/index.js +12 -0
  41. package/dist/components/globe-3d/globe-3d.js +417 -0
  42. package/dist/components/globe-3d/index.js +10 -0
  43. package/dist/components/handoff-beacon/handoff-beacon.js +78 -0
  44. package/dist/components/handoff-beacon/index.js +6 -0
  45. package/dist/components/heat-map-overlay/heat-map-overlay.js +215 -0
  46. package/dist/components/heat-map-overlay/index.js +6 -0
  47. package/dist/components/heat-overlay/heat-overlay.js +92 -0
  48. package/dist/components/heat-overlay/index.js +6 -0
  49. package/dist/components/historic-timeline/historic-timeline.js +342 -0
  50. package/dist/components/historic-timeline/index.js +6 -0
  51. package/dist/components/historical-figure-card/historical-figure-card.js +273 -0
  52. package/dist/components/historical-figure-card/index.js +6 -0
  53. package/dist/components/index.js +432 -1
  54. package/dist/components/infinite-plane/index.js +6 -0
  55. package/dist/components/infinite-plane/infinite-plane.js +75 -0
  56. package/dist/components/interactive-timeline/index.js +16 -0
  57. package/dist/components/interactive-timeline/interactive-timeline.js +708 -0
  58. package/dist/components/jarvis-dock/index.js +6 -0
  59. package/dist/components/jarvis-dock/jarvis-dock.js +98 -0
  60. package/dist/components/kbd/index.js +5 -0
  61. package/dist/components/kbd/kbd.js +117 -0
  62. package/dist/components/knowledge-check/index.js +6 -0
  63. package/dist/components/knowledge-check/knowledge-check.js +448 -0
  64. package/dist/components/live-cursor/index.js +6 -0
  65. package/dist/components/live-cursor/live-cursor.js +62 -0
  66. package/dist/components/map-2d/index.js +20 -0
  67. package/dist/components/map-2d/map-2d.js +455 -0
  68. package/dist/components/map-timeline/index.js +16 -0
  69. package/dist/components/map-timeline/map-timeline.js +506 -0
  70. package/dist/components/metric-cluster/index.js +6 -0
  71. package/dist/components/metric-cluster/metric-cluster.js +96 -0
  72. package/dist/components/model-comparison/index.js +12 -0
  73. package/dist/components/model-comparison/model-comparison.js +211 -0
  74. package/dist/components/multi-select-lasso/index.js +6 -0
  75. package/dist/components/multi-select-lasso/multi-select-lasso.js +76 -0
  76. package/dist/components/newsletter-signup/index.js +8 -0
  77. package/dist/components/newsletter-signup/newsletter-signup.js +269 -0
  78. package/dist/components/object-inspector/index.js +6 -0
  79. package/dist/components/object-inspector/object-inspector.js +136 -0
  80. package/dist/components/parallel-timeline/index.js +6 -0
  81. package/dist/components/parallel-timeline/parallel-timeline.js +251 -0
  82. package/dist/components/playback-ghost/index.js +6 -0
  83. package/dist/components/playback-ghost/playback-ghost.js +83 -0
  84. package/dist/components/policy-delivery-panel/index.js +6 -0
  85. package/dist/components/policy-delivery-panel/policy-delivery-panel.js +99 -0
  86. package/dist/components/presence-stack/index.js +6 -0
  87. package/dist/components/presence-stack/presence-stack.js +108 -0
  88. package/dist/components/presence-sync-indicator/index.js +6 -0
  89. package/dist/components/presence-sync-indicator/presence-sync-indicator.js +73 -0
  90. package/dist/components/pricing-table/index.js +8 -0
  91. package/dist/components/pricing-table/pricing-table.js +247 -0
  92. package/dist/components/primary-source-viewer/index.js +26 -0
  93. package/dist/components/primary-source-viewer/primary-source-viewer.js +439 -0
  94. package/dist/components/prompt-templates/index.js +6 -0
  95. package/dist/components/prompt-templates/prompt-templates.js +403 -0
  96. package/dist/components/property-section/index.js +6 -0
  97. package/dist/components/property-section/property-section.js +101 -0
  98. package/dist/components/relationship-inspector/index.js +6 -0
  99. package/dist/components/relationship-inspector/relationship-inspector.js +102 -0
  100. package/dist/components/route-map/index.js +6 -0
  101. package/dist/components/route-map/route-map.js +339 -0
  102. package/dist/components/routing-assignment-panel/index.js +6 -0
  103. package/dist/components/routing-assignment-panel/routing-assignment-panel.js +122 -0
  104. package/dist/components/run-timeline/index.js +6 -0
  105. package/dist/components/run-timeline/run-timeline.js +221 -0
  106. package/dist/components/runtime-overview-panel/index.js +6 -0
  107. package/dist/components/runtime-overview-panel/runtime-overview-panel.js +89 -0
  108. package/dist/components/selection-halo/index.js +6 -0
  109. package/dist/components/selection-halo/selection-halo.js +72 -0
  110. package/dist/components/selection-presence/index.js +6 -0
  111. package/dist/components/selection-presence/selection-presence.js +50 -0
  112. package/dist/components/snap-guides/index.js +6 -0
  113. package/dist/components/snap-guides/snap-guides.js +45 -0
  114. package/dist/components/state-badge-overlay/index.js +6 -0
  115. package/dist/components/state-badge-overlay/state-badge-overlay.js +90 -0
  116. package/dist/components/sticky-metric/index.js +6 -0
  117. package/dist/components/sticky-metric/sticky-metric.js +83 -0
  118. package/dist/components/story-map/index.js +8 -0
  119. package/dist/components/story-map/story-map.js +414 -0
  120. package/dist/components/thread-bubble/index.js +6 -0
  121. package/dist/components/thread-bubble/thread-bubble.js +85 -0
  122. package/dist/components/threshold-ring/index.js +6 -0
  123. package/dist/components/threshold-ring/threshold-ring.js +160 -0
  124. package/dist/components/timeline/index.js +12 -0
  125. package/dist/components/timeline/timeline.js +239 -0
  126. package/dist/components/timeline-scrubber/index.js +6 -0
  127. package/dist/components/timeline-scrubber/timeline-scrubber.js +179 -0
  128. package/dist/components/transaction-list/index.js +14 -0
  129. package/dist/components/transaction-list/transaction-list.js +226 -0
  130. package/dist/components/tree-view/index.js +6 -0
  131. package/dist/components/tree-view/tree-view.js +298 -0
  132. package/dist/components/viewport-bookmarks/index.js +6 -0
  133. package/dist/components/viewport-bookmarks/viewport-bookmarks.js +116 -0
  134. package/dist/components/world-breadcrumbs/index.js +6 -0
  135. package/dist/components/world-breadcrumbs/world-breadcrumbs.js +114 -0
  136. package/dist/index.d.ts +7135 -141
  137. package/package.json +1 -1
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const TONE_DOT = {
8
+ danger: "bg-red-500",
9
+ info: "bg-blue-500",
10
+ neutral: "bg-muted-foreground",
11
+ success: "bg-emerald-500",
12
+ warn: "bg-amber-500"
13
+ };
14
+ const DEFAULT_LABELS = {
15
+ empty: "No recent activity",
16
+ region: "Recent activity"
17
+ };
18
+ const ChipBody = (props) => {
19
+ const { event } = props;
20
+ const tone = event.tone ?? "neutral";
21
+ return /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 whitespace-nowrap", children: [
22
+ /* @__PURE__ */ jsx(
23
+ "span",
24
+ {
25
+ "aria-hidden": "true",
26
+ className: cn("h-1.5 w-1.5 rounded-full", TONE_DOT[tone])
27
+ }
28
+ ),
29
+ /* @__PURE__ */ jsx("span", { className: "text-foreground", children: event.label }),
30
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", "data-strip-event-ts": true, children: event.ts })
31
+ ] });
32
+ };
33
+ const Chip = (props) => {
34
+ const { event } = props;
35
+ const tone = event.tone ?? "neutral";
36
+ if (event.onActivate) {
37
+ const handleClick = () => {
38
+ event.onActivate?.();
39
+ };
40
+ return /* @__PURE__ */ jsx(
41
+ "button",
42
+ {
43
+ className: "flex items-center rounded-full border border-border bg-background px-2 py-1 text-[11px] transition-colors hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
44
+ "data-strip-event": event.id,
45
+ "data-strip-event-tone": tone,
46
+ onClick: handleClick,
47
+ type: "button",
48
+ children: /* @__PURE__ */ jsx(ChipBody, { event })
49
+ }
50
+ );
51
+ }
52
+ return /* @__PURE__ */ jsx(
53
+ "span",
54
+ {
55
+ className: "flex items-center rounded-full border border-border bg-background px-2 py-1 text-[11px]",
56
+ "data-strip-event": event.id,
57
+ "data-strip-event-tone": tone,
58
+ children: /* @__PURE__ */ jsx(ChipBody, { event })
59
+ }
60
+ );
61
+ };
62
+ const BottomActivityStrip = forwardRef((props, ref) => {
63
+ const { className, events, labels, maxEvents, ...rest } = props;
64
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
65
+ const visible = maxEvents === void 0 || maxEvents >= events.length ? events : events.slice(0, maxEvents);
66
+ return /* @__PURE__ */ jsx(
67
+ "section",
68
+ {
69
+ "aria-label": resolvedLabels.region,
70
+ className: cn(
71
+ "flex w-full items-center gap-2 overflow-x-auto rounded-md border border-border bg-background/90 px-2 py-1 text-foreground",
72
+ className
73
+ ),
74
+ "data-bottom-activity-strip": true,
75
+ ref,
76
+ ...rest,
77
+ children: visible.length === 0 ? /* @__PURE__ */ jsx(
78
+ "span",
79
+ {
80
+ className: "px-2 text-[11px] text-muted-foreground",
81
+ "data-strip-state": "empty",
82
+ children: resolvedLabels.empty
83
+ }
84
+ ) : visible.map((event) => /* @__PURE__ */ jsx(Chip, { event }, event.id))
85
+ }
86
+ );
87
+ });
88
+ BottomActivityStrip.displayName = "BottomActivityStrip";
89
+ export {
90
+ BottomActivityStrip
91
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ BottomActivityStrip
3
+ } from "./bottom-activity-strip";
4
+ export {
5
+ BottomActivityStrip
6
+ };
@@ -0,0 +1,373 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ createContext,
5
+ forwardRef,
6
+ useCallback,
7
+ useContext,
8
+ useId,
9
+ useMemo,
10
+ useState
11
+ } from "react";
12
+ import { cn } from "../../lib/utils";
13
+ const VIEWBOX_WIDTH = 1e3;
14
+ const VIEWBOX_HEIGHT = 500;
15
+ const DEFAULT_LABELS = {
16
+ region: "Choropleth map"
17
+ };
18
+ const DEFAULT_SCALE = ["#f1f5f9", "#1d4ed8"];
19
+ const DEFAULT_MISSING = "#e5e7eb";
20
+ const ChoroplethContext = createContext(null);
21
+ function useChoroplethContext() {
22
+ const ctx = useContext(ChoroplethContext);
23
+ if (!ctx) {
24
+ throw new Error("ChoroplethMap subcomponent used outside its root.");
25
+ }
26
+ return ctx;
27
+ }
28
+ function projectEquirectangular(position, width, height) {
29
+ const [lng, lat] = position;
30
+ const x = (lng + 180) / 360 * width;
31
+ const y = (90 - lat) / 180 * height;
32
+ return { x, y };
33
+ }
34
+ function clamp(value, min, max) {
35
+ return Math.min(Math.max(value, min), max);
36
+ }
37
+ function parseHex(color) {
38
+ const match = /^#([\da-f]{6})$/i.exec(color.trim());
39
+ if (!match) return void 0;
40
+ const hex = match[1] ?? "";
41
+ return [
42
+ Number.parseInt(hex.slice(0, 2), 16),
43
+ Number.parseInt(hex.slice(2, 4), 16),
44
+ Number.parseInt(hex.slice(4, 6), 16)
45
+ ];
46
+ }
47
+ function toHex(channel) {
48
+ return clamp(Math.round(channel), 0, 255).toString(16).padStart(2, "0");
49
+ }
50
+ function lerp(a, b, t) {
51
+ return a + (b - a) * t;
52
+ }
53
+ function interpolateColor(stops, t) {
54
+ if (stops.length === 0) return "#000000";
55
+ if (stops.length === 1) return stops[0] ?? "#000000";
56
+ const segments = stops.length - 1;
57
+ const scaledT = clamp(t, 0, 1) * segments;
58
+ const segmentIndex = Math.min(Math.floor(scaledT), segments - 1);
59
+ const localT = scaledT - segmentIndex;
60
+ const lower = stops[segmentIndex];
61
+ const upper = stops[segmentIndex + 1];
62
+ if (!lower || !upper) return stops[0] ?? "#000000";
63
+ const lowerRgb = parseHex(lower);
64
+ const upperRgb = parseHex(upper);
65
+ if (!lowerRgb || !upperRgb) return lower;
66
+ const [lr, lg, lb] = lowerRgb;
67
+ const [ur, ug, ub] = upperRgb;
68
+ const r = lerp(lr, ur, localT);
69
+ const g = lerp(lg, ug, localT);
70
+ const b = lerp(lb, ub, localT);
71
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
72
+ }
73
+ function computeDomain(values) {
74
+ const first = values[0];
75
+ if (first === void 0) return [0, 1];
76
+ const min = values.reduce(
77
+ (accumulator, value) => Math.min(accumulator, value),
78
+ first
79
+ );
80
+ const max = values.reduce(
81
+ (accumulator, value) => Math.max(accumulator, value),
82
+ first
83
+ );
84
+ if (min === max) return [min, max + 1];
85
+ return [min, max];
86
+ }
87
+ function regionPath(region) {
88
+ return region.coordinates.map((coord, index) => {
89
+ const projected = projectEquirectangular(
90
+ coord,
91
+ VIEWBOX_WIDTH,
92
+ VIEWBOX_HEIGHT
93
+ );
94
+ return `${index === 0 ? "M" : "L"}${projected.x.toString()},${projected.y.toString()}`;
95
+ }).join(" ");
96
+ }
97
+ function RegionPath({
98
+ active,
99
+ onSelect,
100
+ region,
101
+ selectedId,
102
+ setHoverFn
103
+ }) {
104
+ const { colorFor, valueFor } = useChoroplethContext();
105
+ const value = valueFor(region.id) ?? void 0;
106
+ const fill = colorFor(value);
107
+ const handleEnter = () => {
108
+ setHoverFn({ id: region.id, value });
109
+ };
110
+ const handleLeave = () => {
111
+ setHoverFn();
112
+ };
113
+ const handleSelect = () => {
114
+ onSelect(region);
115
+ };
116
+ return /* @__PURE__ */ jsx(
117
+ "path",
118
+ {
119
+ "aria-label": `${region.name}${value === void 0 ? " no data" : ` ${value.toString()}`}`,
120
+ className: cn(
121
+ "cursor-pointer outline-none transition-[opacity,filter]",
122
+ active ? "opacity-100" : "opacity-90 hover:opacity-100",
123
+ selectedId === region.id ? "stroke-foreground" : "stroke-background"
124
+ ),
125
+ d: regionPath(region) + " Z",
126
+ "data-region-id": region.id,
127
+ "data-selected": selectedId === region.id ? "true" : void 0,
128
+ "data-value": value,
129
+ fill,
130
+ onBlur: handleLeave,
131
+ onClick: handleSelect,
132
+ onFocus: handleEnter,
133
+ onMouseEnter: handleEnter,
134
+ onMouseLeave: handleLeave,
135
+ strokeWidth: selectedId === region.id ? 2 : 0.75,
136
+ tabIndex: 0
137
+ }
138
+ );
139
+ }
140
+ const ChoroplethTooltip = forwardRef(({ children, className, ...rest }, ref) => {
141
+ const { hover, regionByid } = useChoroplethContext();
142
+ if (!hover) return null;
143
+ const region = regionByid.get(hover.id);
144
+ if (!region) return null;
145
+ return /* @__PURE__ */ jsx(
146
+ "div",
147
+ {
148
+ className: cn(
149
+ "pointer-events-none absolute left-3 top-3 z-10 max-w-xs rounded-md border bg-popover px-2 py-1 text-xs text-popover-foreground shadow-md",
150
+ className
151
+ ),
152
+ "data-tooltip-region-id": region.id,
153
+ ref,
154
+ role: "status",
155
+ ...rest,
156
+ children: children ? children({ region, value: hover.value }) : /* @__PURE__ */ jsxs("span", { children: [
157
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: region.name }),
158
+ hover.value === void 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: " \xB7 no data" }) : /* @__PURE__ */ jsxs("span", { children: [
159
+ " \xB7 ",
160
+ hover.value.toLocaleString()
161
+ ] })
162
+ ] })
163
+ }
164
+ );
165
+ });
166
+ ChoroplethTooltip.displayName = "ChoroplethTooltip";
167
+ const ChoroplethLegend = forwardRef(({ className, title, ...rest }, ref) => {
168
+ const { legend } = useChoroplethContext();
169
+ if (!legend) return null;
170
+ const stops = legend.scale.join(", ");
171
+ return /* @__PURE__ */ jsxs(
172
+ "div",
173
+ {
174
+ className: cn(
175
+ "absolute bottom-3 right-3 z-10 flex flex-col gap-1 rounded-md border bg-background/95 px-2 py-1 text-[11px] text-foreground shadow-sm backdrop-blur",
176
+ className
177
+ ),
178
+ "data-legend": true,
179
+ ref,
180
+ ...rest,
181
+ children: [
182
+ title ? /* @__PURE__ */ jsx("span", { className: "font-medium uppercase tracking-wide text-muted-foreground", children: title }) : null,
183
+ /* @__PURE__ */ jsx(
184
+ "div",
185
+ {
186
+ "aria-hidden": "true",
187
+ className: "h-2 w-32 rounded-full",
188
+ style: { background: `linear-gradient(to right, ${stops})` }
189
+ }
190
+ ),
191
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-muted-foreground", children: [
192
+ /* @__PURE__ */ jsx("span", { children: legend.domain[0].toLocaleString() }),
193
+ /* @__PURE__ */ jsx("span", { children: legend.domain[1].toLocaleString() })
194
+ ] })
195
+ ]
196
+ }
197
+ );
198
+ });
199
+ ChoroplethLegend.displayName = "ChoroplethLegend";
200
+ function DataSummary({ data, regions, titleId }) {
201
+ return /* @__PURE__ */ jsxs("div", { "aria-labelledby": titleId, className: "sr-only", role: "region", children: [
202
+ /* @__PURE__ */ jsx("h3", { id: titleId, children: "Choropleth data summary" }),
203
+ /* @__PURE__ */ jsxs("table", { children: [
204
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
205
+ /* @__PURE__ */ jsx("th", { scope: "col", children: "Region" }),
206
+ /* @__PURE__ */ jsx("th", { scope: "col", children: "Value" })
207
+ ] }) }),
208
+ /* @__PURE__ */ jsx("tbody", { children: regions.map((region) => {
209
+ const value = data[region.id];
210
+ return /* @__PURE__ */ jsxs("tr", { children: [
211
+ /* @__PURE__ */ jsx("td", { children: region.name }),
212
+ /* @__PURE__ */ jsx("td", { children: value === void 0 ? "no data" : value.toLocaleString() })
213
+ ] }, region.id);
214
+ }) })
215
+ ] })
216
+ ] });
217
+ }
218
+ function bucketChildren(children) {
219
+ const list = Array.isArray(children) ? children : [children];
220
+ return list.reduce(
221
+ (accumulator, child) => {
222
+ const name = displayName(child);
223
+ if (name === ChoroplethLegend.displayName) accumulator.legend = child;
224
+ else if (name === ChoroplethTooltip.displayName)
225
+ accumulator.tooltip = child;
226
+ return accumulator;
227
+ },
228
+ { legend: null, tooltip: null }
229
+ );
230
+ }
231
+ function displayName(child) {
232
+ if (typeof child !== "object" || child === null) return void 0;
233
+ if (!("type" in child)) return void 0;
234
+ const type = child.type;
235
+ if (typeof type !== "object" && typeof type !== "function") return void 0;
236
+ const name = type.displayName;
237
+ return typeof name === "string" ? name : void 0;
238
+ }
239
+ function useChoroplethState(arguments_) {
240
+ const { colorScale, data, domain, missingColor, regions } = arguments_;
241
+ const regionByid = useMemo(
242
+ () => new Map(
243
+ regions.map((region) => [region.id, region])
244
+ ),
245
+ [regions]
246
+ );
247
+ const valueFor = useCallback(
248
+ (id) => data[id] ?? null,
249
+ [data]
250
+ );
251
+ const colorFor = useCallback(
252
+ (value) => {
253
+ if (value === void 0) return missingColor;
254
+ const [min, max] = domain;
255
+ const span = max - min;
256
+ const t = span === 0 ? 0.5 : (value - min) / span;
257
+ return interpolateColor(colorScale, t);
258
+ },
259
+ [colorScale, domain, missingColor]
260
+ );
261
+ const [hover, setHover] = useState();
262
+ return useMemo(
263
+ () => ({
264
+ colorFor,
265
+ hover,
266
+ legend: { domain, scale: colorScale },
267
+ regionByid,
268
+ setHover,
269
+ valueFor
270
+ }),
271
+ [colorFor, colorScale, domain, hover, regionByid, valueFor]
272
+ );
273
+ }
274
+ function RegionsLayer({
275
+ onSelect,
276
+ regions,
277
+ selectedId,
278
+ setHoverFn
279
+ }) {
280
+ return /* @__PURE__ */ jsx("g", { children: regions.map((region) => /* @__PURE__ */ jsx(
281
+ RegionPath,
282
+ {
283
+ active: selectedId === region.id,
284
+ onSelect,
285
+ region,
286
+ selectedId,
287
+ setHoverFn
288
+ },
289
+ region.id
290
+ )) });
291
+ }
292
+ const ChoroplethMap = forwardRef(
293
+ (props, ref) => {
294
+ const {
295
+ children,
296
+ className,
297
+ colorScale = DEFAULT_SCALE,
298
+ data,
299
+ domain: domainProperty,
300
+ labels,
301
+ missingColor = DEFAULT_MISSING,
302
+ onSelectRegion,
303
+ regions,
304
+ ...rest
305
+ } = props;
306
+ const titleId = useId();
307
+ const resolvedLabels = useMemo(
308
+ () => ({ ...DEFAULT_LABELS, ...labels }),
309
+ [labels]
310
+ );
311
+ const domain = useMemo(
312
+ () => domainProperty ?? computeDomain(Object.values(data)),
313
+ [data, domainProperty]
314
+ );
315
+ const ctx = useChoroplethState({
316
+ colorScale,
317
+ data,
318
+ domain,
319
+ missingColor,
320
+ regions
321
+ });
322
+ const buckets = useMemo(() => bucketChildren(children), [children]);
323
+ const [selectedId, setSelectedId] = useState();
324
+ const handleSelect = useCallback(
325
+ (region) => {
326
+ setSelectedId(region.id);
327
+ onSelectRegion?.(region);
328
+ },
329
+ [onSelectRegion]
330
+ );
331
+ return /* @__PURE__ */ jsx(ChoroplethContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxs(
332
+ "section",
333
+ {
334
+ "aria-label": resolvedLabels.region,
335
+ className: cn(
336
+ "relative aspect-[2/1] w-full overflow-hidden rounded-2xl border bg-background text-foreground",
337
+ className
338
+ ),
339
+ ref,
340
+ ...rest,
341
+ children: [
342
+ /* @__PURE__ */ jsx(
343
+ "svg",
344
+ {
345
+ "aria-hidden": "true",
346
+ className: "block h-full w-full",
347
+ preserveAspectRatio: "xMidYMid meet",
348
+ viewBox: `0 0 ${VIEWBOX_WIDTH.toString()} ${VIEWBOX_HEIGHT.toString()}`,
349
+ children: /* @__PURE__ */ jsx(
350
+ RegionsLayer,
351
+ {
352
+ onSelect: handleSelect,
353
+ regions,
354
+ selectedId,
355
+ setHoverFn: ctx.setHover
356
+ }
357
+ )
358
+ }
359
+ ),
360
+ buckets.tooltip,
361
+ buckets.legend,
362
+ /* @__PURE__ */ jsx(DataSummary, { data, regions, titleId })
363
+ ]
364
+ }
365
+ ) });
366
+ }
367
+ );
368
+ ChoroplethMap.displayName = "ChoroplethMap";
369
+ export {
370
+ ChoroplethLegend,
371
+ ChoroplethMap,
372
+ ChoroplethTooltip
373
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ ChoroplethLegend,
3
+ ChoroplethMap,
4
+ ChoroplethTooltip
5
+ } from "./choropleth-map";
6
+ export {
7
+ ChoroplethLegend,
8
+ ChoroplethMap,
9
+ ChoroplethTooltip
10
+ };