@vesture/react 0.2.9 → 0.3.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.
package/dist/index.js CHANGED
@@ -2598,10 +2598,10 @@ function clampToMidnight3(date) {
2598
2598
  return new Date(date.getFullYear(), date.getMonth(), date.getDate());
2599
2599
  }
2600
2600
  function compareDates(a, b) {
2601
- const x = clampToMidnight3(a).getTime();
2602
- const y = clampToMidnight3(b).getTime();
2603
- if (x < y) return -1;
2604
- if (x > y) return 1;
2601
+ const x2 = clampToMidnight3(a).getTime();
2602
+ const y2 = clampToMidnight3(b).getTime();
2603
+ if (x2 < y2) return -1;
2604
+ if (x2 > y2) return 1;
2605
2605
  return 0;
2606
2606
  }
2607
2607
  function isDisabled2(date, minDate, maxDate, isDateDisabled) {
@@ -3657,8 +3657,8 @@ function TreeView({
3657
3657
  const rowRefs = useRef10(/* @__PURE__ */ new Map());
3658
3658
  const nodeIndex = useMemo4(() => {
3659
3659
  const map = /* @__PURE__ */ new Map();
3660
- function walk(list4, parentId) {
3661
- for (const node of list4) {
3660
+ function walk(list5, parentId) {
3661
+ for (const node of list5) {
3662
3662
  map.set(node.id, { node, parentId });
3663
3663
  const children = getChildren(node, loadedChildren);
3664
3664
  if (children) walk(children, node.id);
@@ -3669,8 +3669,8 @@ function TreeView({
3669
3669
  }, [nodes, loadedChildren]);
3670
3670
  const flatNodes = useMemo4(() => {
3671
3671
  const result = [];
3672
- function walk(list4, depth) {
3673
- for (const node of list4) {
3672
+ function walk(list5, depth) {
3673
+ for (const node of list5) {
3674
3674
  const children = getChildren(node, loadedChildren);
3675
3675
  const nodeHasChildren = children ? children.length > 0 : node.hasChildren === true;
3676
3676
  const isExpanded = expandedSet.has(node.id);
@@ -3935,16 +3935,1668 @@ function TreeView({
3935
3935
  );
3936
3936
  }
3937
3937
 
3938
+ // src/components/CommandPalette/CommandPalette.tsx
3939
+ import { useEffect as useEffect9, useId as useId3, useMemo as useMemo5, useRef as useRef11, useState as useState16 } from "react";
3940
+ import {
3941
+ FloatingFocusManager as FloatingFocusManager6,
3942
+ FloatingOverlay as FloatingOverlay2,
3943
+ FloatingPortal as FloatingPortal8,
3944
+ useDismiss as useDismiss8,
3945
+ useFloating as useFloating8,
3946
+ useInteractions as useInteractions8,
3947
+ useRole as useRole8
3948
+ } from "@floating-ui/react";
3949
+
3950
+ // src/components/CommandPalette/CommandPalette.css.ts
3951
+ var emptyState3 = "CommandPalette_emptyState__14otg5db";
3952
+ var groupHeader = "CommandPalette_groupHeader__14otg5d5";
3953
+ var inputEl2 = "CommandPalette_inputEl__14otg5d2";
3954
+ var list4 = "CommandPalette_list__14otg5d3";
3955
+ var option2 = "CommandPalette_option__14otg5d6";
3956
+ var optionDescription = "CommandPalette_optionDescription__14otg5d9";
3957
+ var optionIcon = "CommandPalette_optionIcon__14otg5d7";
3958
+ var optionLabel = "CommandPalette_optionLabel__14otg5d8";
3959
+ var overlay2 = "CommandPalette_overlay__14otg5d0";
3960
+ var palette = "CommandPalette_palette__14otg5d1";
3961
+ var shortcut = "CommandPalette_shortcut__14otg5da";
3962
+ var virtualSpacer2 = "CommandPalette_virtualSpacer__14otg5d4";
3963
+
3964
+ // src/components/CommandPalette/CommandPalette.tsx
3965
+ import { jsx as jsx42, jsxs as jsxs25 } from "react/jsx-runtime";
3966
+ var DEFAULT_ROW_HEIGHT = 40;
3967
+ var OVERSCAN2 = 5;
3968
+ function defaultFilterCommands(commands, query) {
3969
+ const q = query.trim().toLowerCase();
3970
+ if (!q) return commands;
3971
+ return commands.filter((command) => {
3972
+ const haystack = [command.label, command.group, ...command.keywords ?? []].filter(Boolean).join(" ").toLowerCase();
3973
+ return haystack.includes(q);
3974
+ });
3975
+ }
3976
+ function buildRows(commands) {
3977
+ const rows = [];
3978
+ const itemRowIndices = [];
3979
+ const seenGroups = /* @__PURE__ */ new Set();
3980
+ commands.forEach((command, itemIndex) => {
3981
+ if (command.group && !seenGroups.has(command.group)) {
3982
+ seenGroups.add(command.group);
3983
+ rows.push({ type: "header", key: `__group-${command.group}`, group: command.group });
3984
+ }
3985
+ itemRowIndices[itemIndex] = rows.length;
3986
+ rows.push({ type: "item", key: command.id, command, itemIndex });
3987
+ });
3988
+ return { rows, itemRowIndices };
3989
+ }
3990
+ function CommandPalette({
3991
+ open,
3992
+ onOpenChange,
3993
+ commands,
3994
+ placeholder = "Type a command or search...",
3995
+ emptyMessage = "No matching commands",
3996
+ filterCommands = defaultFilterCommands,
3997
+ virtualizationThreshold = 50,
3998
+ rowHeight = DEFAULT_ROW_HEIGHT,
3999
+ "aria-label": ariaLabel
4000
+ }) {
4001
+ const [query, setQuery] = useState16("");
4002
+ const [activeIndex, setActiveIndex] = useState16(null);
4003
+ const [scrollTop, setScrollTop] = useState16(0);
4004
+ const [viewportHeight, setViewportHeight] = useState16(320);
4005
+ const inputRef = useRef11(null);
4006
+ const listRef = useRef11(null);
4007
+ const listId = useId3();
4008
+ const { refs, context } = useFloating8({ open, onOpenChange });
4009
+ const { getFloatingProps } = useInteractions8([useDismiss8(context), useRole8(context, { role: "dialog" })]);
4010
+ const filteredCommands = useMemo5(() => filterCommands(commands, query), [commands, filterCommands, query]);
4011
+ const { rows, itemRowIndices } = useMemo5(() => buildRows(filteredCommands), [filteredCommands]);
4012
+ const isVirtualized = rows.length >= virtualizationThreshold;
4013
+ useEffect9(() => {
4014
+ if (!open) return;
4015
+ setQuery("");
4016
+ setActiveIndex(null);
4017
+ setScrollTop(0);
4018
+ if (listRef.current) listRef.current.scrollTop = 0;
4019
+ }, [open]);
4020
+ useEffect9(() => {
4021
+ setActiveIndex(null);
4022
+ setScrollTop(0);
4023
+ if (listRef.current) listRef.current.scrollTop = 0;
4024
+ }, [query]);
4025
+ useEffect9(() => {
4026
+ if (!open) return;
4027
+ const node = listRef.current;
4028
+ if (!node) return;
4029
+ if (node.clientHeight > 0) setViewportHeight(node.clientHeight);
4030
+ if (typeof ResizeObserver === "undefined") return;
4031
+ const observer = new ResizeObserver((entries) => {
4032
+ const entry = entries[0];
4033
+ if (entry) setViewportHeight(entry.contentRect.height);
4034
+ });
4035
+ observer.observe(node);
4036
+ return () => observer.disconnect();
4037
+ }, [open]);
4038
+ if (!open) {
4039
+ return null;
4040
+ }
4041
+ const totalHeight = rows.length * rowHeight;
4042
+ const maxScrollTop = Math.max(0, totalHeight - viewportHeight);
4043
+ const effectiveScrollTop = Math.min(scrollTop, maxScrollTop);
4044
+ const visibleCount = Math.ceil(viewportHeight / rowHeight) + OVERSCAN2 * 2;
4045
+ const startIndex = isVirtualized ? Math.max(0, Math.floor(effectiveScrollTop / rowHeight) - OVERSCAN2) : 0;
4046
+ const endIndex = isVirtualized ? Math.min(rows.length, startIndex + visibleCount) : rows.length;
4047
+ const visibleRows = rows.slice(startIndex, endIndex);
4048
+ const scrollRowIntoView = (rowIndex) => {
4049
+ if (!isVirtualized) return;
4050
+ const rowTop = rowIndex * rowHeight;
4051
+ const rowBottom = rowTop + rowHeight;
4052
+ let next = scrollTop;
4053
+ if (rowTop < scrollTop) {
4054
+ next = rowTop;
4055
+ } else if (rowBottom > scrollTop + viewportHeight) {
4056
+ next = rowBottom - viewportHeight;
4057
+ } else {
4058
+ return;
4059
+ }
4060
+ setScrollTop(next);
4061
+ if (listRef.current) listRef.current.scrollTop = next;
4062
+ };
4063
+ const moveActiveIndex = (direction2) => {
4064
+ if (filteredCommands.length === 0) return;
4065
+ let next = activeIndex ?? (direction2 === 1 ? -1 : filteredCommands.length);
4066
+ for (let step = 0; step < filteredCommands.length; step++) {
4067
+ next = (next + direction2 + filteredCommands.length) % filteredCommands.length;
4068
+ if (!filteredCommands[next]?.disabled) {
4069
+ setActiveIndex(next);
4070
+ const rowIndex = itemRowIndices[next];
4071
+ if (rowIndex !== void 0) scrollRowIntoView(rowIndex);
4072
+ return;
4073
+ }
4074
+ }
4075
+ };
4076
+ const selectCommand = (command) => {
4077
+ if (command.disabled) return;
4078
+ command.onSelect();
4079
+ onOpenChange(false);
4080
+ };
4081
+ const handleKeyDown = (event) => {
4082
+ switch (event.key) {
4083
+ case "ArrowDown":
4084
+ event.preventDefault();
4085
+ moveActiveIndex(1);
4086
+ return;
4087
+ case "ArrowUp":
4088
+ event.preventDefault();
4089
+ moveActiveIndex(-1);
4090
+ return;
4091
+ case "Enter": {
4092
+ event.preventDefault();
4093
+ const active = activeIndex !== null ? filteredCommands[activeIndex] : void 0;
4094
+ if (active) selectCommand(active);
4095
+ return;
4096
+ }
4097
+ case "Escape":
4098
+ event.preventDefault();
4099
+ onOpenChange(false);
4100
+ return;
4101
+ default:
4102
+ }
4103
+ };
4104
+ const activeCommand = activeIndex !== null ? filteredCommands[activeIndex] : void 0;
4105
+ const activeOptionId = activeCommand ? `${listId}-option-${activeCommand.id}` : void 0;
4106
+ const renderRow = (row3, rowIndex, rowStyle) => {
4107
+ if (row3.type === "header") {
4108
+ return /* @__PURE__ */ jsx42("div", { role: "presentation", className: groupHeader, style: rowStyle, children: row3.group }, row3.key);
4109
+ }
4110
+ const { command, itemIndex } = row3;
4111
+ const isActive = itemIndex === activeIndex;
4112
+ return /* @__PURE__ */ jsxs25(
4113
+ "div",
4114
+ {
4115
+ id: `${listId}-option-${command.id}`,
4116
+ role: "option",
4117
+ "aria-selected": isActive,
4118
+ "aria-disabled": command.disabled || void 0,
4119
+ "data-active": isActive || void 0,
4120
+ className: option2,
4121
+ style: rowStyle,
4122
+ onMouseDown: (event) => {
4123
+ event.preventDefault();
4124
+ selectCommand(command);
4125
+ },
4126
+ onMouseEnter: () => {
4127
+ if (!command.disabled) setActiveIndex(itemIndex);
4128
+ },
4129
+ children: [
4130
+ command.icon ? /* @__PURE__ */ jsx42("span", { className: optionIcon, children: command.icon }) : null,
4131
+ /* @__PURE__ */ jsxs25("span", { className: optionLabel, children: [
4132
+ command.label,
4133
+ command.description ? /* @__PURE__ */ jsx42("span", { className: optionDescription, children: command.description }) : null
4134
+ ] }),
4135
+ command.shortcut ? /* @__PURE__ */ jsx42("span", { className: shortcut, children: command.shortcut }) : null
4136
+ ]
4137
+ },
4138
+ row3.key
4139
+ );
4140
+ };
4141
+ return /* @__PURE__ */ jsx42(FloatingPortal8, { children: /* @__PURE__ */ jsx42(FloatingOverlay2, { className: overlay2, lockScroll: true, children: /* @__PURE__ */ jsx42(FloatingFocusManager6, { context, initialFocus: inputRef, children: /* @__PURE__ */ jsxs25(
4142
+ "div",
4143
+ {
4144
+ ref: refs.setFloating,
4145
+ className: palette,
4146
+ "aria-label": ariaLabel ?? "Command palette",
4147
+ ...getFloatingProps(),
4148
+ children: [
4149
+ /* @__PURE__ */ jsx42(
4150
+ "input",
4151
+ {
4152
+ ref: inputRef,
4153
+ type: "text",
4154
+ role: "combobox",
4155
+ className: inputEl2,
4156
+ value: query,
4157
+ placeholder,
4158
+ autoComplete: "off",
4159
+ "aria-autocomplete": "list",
4160
+ "aria-expanded": true,
4161
+ "aria-controls": listId,
4162
+ "aria-activedescendant": activeOptionId,
4163
+ onChange: (event) => setQuery(event.target.value),
4164
+ onKeyDown: handleKeyDown
4165
+ }
4166
+ ),
4167
+ /* @__PURE__ */ jsx42(
4168
+ "div",
4169
+ {
4170
+ ref: listRef,
4171
+ id: listId,
4172
+ role: "listbox",
4173
+ className: list4,
4174
+ onScroll: (event) => setScrollTop(event.currentTarget.scrollTop),
4175
+ children: filteredCommands.length === 0 ? /* @__PURE__ */ jsx42("div", { className: emptyState3, children: emptyMessage }) : isVirtualized ? /* @__PURE__ */ jsx42("div", { className: virtualSpacer2, style: { height: totalHeight }, children: visibleRows.map((row3, i) => {
4176
+ const rowIndex = startIndex + i;
4177
+ return renderRow(row3, rowIndex, {
4178
+ position: "absolute",
4179
+ top: rowIndex * rowHeight,
4180
+ left: 0,
4181
+ right: 0,
4182
+ height: rowHeight
4183
+ });
4184
+ }) }) : rows.map((row3, rowIndex) => renderRow(row3, rowIndex))
4185
+ }
4186
+ )
4187
+ ]
4188
+ }
4189
+ ) }) }) });
4190
+ }
4191
+
4192
+ // src/components/CommandPalette/useCommandPaletteShortcut.ts
4193
+ import { useEffect as useEffect10 } from "react";
4194
+ function isMac() {
4195
+ if (typeof navigator === "undefined") return false;
4196
+ return /Mac|iPhone|iPad|iPod/.test(navigator.platform ?? navigator.userAgent ?? "");
4197
+ }
4198
+ function useCommandPaletteShortcut(onOpenChange, options = {}) {
4199
+ const { key = "k", metaKey, ctrlKey } = options;
4200
+ useEffect10(() => {
4201
+ const explicit = metaKey !== void 0 || ctrlKey !== void 0;
4202
+ const useMeta = explicit ? Boolean(metaKey) : isMac();
4203
+ const useCtrl = explicit ? Boolean(ctrlKey) : !isMac();
4204
+ const handleKeyDown = (event) => {
4205
+ if (event.key.toLowerCase() !== key.toLowerCase()) return;
4206
+ if (event.metaKey !== useMeta) return;
4207
+ if (event.ctrlKey !== useCtrl) return;
4208
+ event.preventDefault();
4209
+ onOpenChange(true);
4210
+ };
4211
+ document.addEventListener("keydown", handleKeyDown);
4212
+ return () => document.removeEventListener("keydown", handleKeyDown);
4213
+ }, [onOpenChange, key, metaKey, ctrlKey]);
4214
+ }
4215
+
4216
+ // src/components/charts/LineChart/LineChart.tsx
4217
+ import { AxisBottom, AxisLeft } from "@visx/axis";
4218
+ import { GridRows } from "@visx/grid";
4219
+ import { Group } from "@visx/group";
4220
+ import { LinePath } from "@visx/shape";
4221
+ import { vars as vars4 } from "@vesture/tokens";
4222
+
4223
+ // src/components/charts/LineChart/LineChart.render.ts
4224
+ import { scaleBand, scaleLinear, scaleTime } from "@visx/scale";
4225
+
4226
+ // ../../node_modules/d3-shape/src/constant.js
4227
+ function constant_default(x2) {
4228
+ return function constant() {
4229
+ return x2;
4230
+ };
4231
+ }
4232
+
4233
+ // ../../node_modules/d3-path/src/path.js
4234
+ var pi = Math.PI;
4235
+ var tau = 2 * pi;
4236
+ var epsilon = 1e-6;
4237
+ var tauEpsilon = tau - epsilon;
4238
+ function append(strings) {
4239
+ this._ += strings[0];
4240
+ for (let i = 1, n = strings.length; i < n; ++i) {
4241
+ this._ += arguments[i] + strings[i];
4242
+ }
4243
+ }
4244
+ function appendRound(digits) {
4245
+ let d = Math.floor(digits);
4246
+ if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);
4247
+ if (d > 15) return append;
4248
+ const k = 10 ** d;
4249
+ return function(strings) {
4250
+ this._ += strings[0];
4251
+ for (let i = 1, n = strings.length; i < n; ++i) {
4252
+ this._ += Math.round(arguments[i] * k) / k + strings[i];
4253
+ }
4254
+ };
4255
+ }
4256
+ var Path = class {
4257
+ constructor(digits) {
4258
+ this._x0 = this._y0 = // start of current subpath
4259
+ this._x1 = this._y1 = null;
4260
+ this._ = "";
4261
+ this._append = digits == null ? append : appendRound(digits);
4262
+ }
4263
+ moveTo(x2, y2) {
4264
+ this._append`M${this._x0 = this._x1 = +x2},${this._y0 = this._y1 = +y2}`;
4265
+ }
4266
+ closePath() {
4267
+ if (this._x1 !== null) {
4268
+ this._x1 = this._x0, this._y1 = this._y0;
4269
+ this._append`Z`;
4270
+ }
4271
+ }
4272
+ lineTo(x2, y2) {
4273
+ this._append`L${this._x1 = +x2},${this._y1 = +y2}`;
4274
+ }
4275
+ quadraticCurveTo(x1, y1, x2, y2) {
4276
+ this._append`Q${+x1},${+y1},${this._x1 = +x2},${this._y1 = +y2}`;
4277
+ }
4278
+ bezierCurveTo(x1, y1, x2, y2, x3, y3) {
4279
+ this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x3},${this._y1 = +y3}`;
4280
+ }
4281
+ arcTo(x1, y1, x2, y2, r) {
4282
+ x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
4283
+ if (r < 0) throw new Error(`negative radius: ${r}`);
4284
+ let x0 = this._x1, y0 = this._y1, x21 = x2 - x1, y21 = y2 - y1, x01 = x0 - x1, y01 = y0 - y1, l01_2 = x01 * x01 + y01 * y01;
4285
+ if (this._x1 === null) {
4286
+ this._append`M${this._x1 = x1},${this._y1 = y1}`;
4287
+ } else if (!(l01_2 > epsilon)) ;
4288
+ else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
4289
+ this._append`L${this._x1 = x1},${this._y1 = y1}`;
4290
+ } else {
4291
+ let x20 = x2 - x0, y20 = y2 - y0, l21_2 = x21 * x21 + y21 * y21, l20_2 = x20 * x20 + y20 * y20, l21 = Math.sqrt(l21_2), l01 = Math.sqrt(l01_2), l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), t01 = l / l01, t21 = l / l21;
4292
+ if (Math.abs(t01 - 1) > epsilon) {
4293
+ this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;
4294
+ }
4295
+ this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;
4296
+ }
4297
+ }
4298
+ arc(x2, y2, r, a0, a1, ccw) {
4299
+ x2 = +x2, y2 = +y2, r = +r, ccw = !!ccw;
4300
+ if (r < 0) throw new Error(`negative radius: ${r}`);
4301
+ let dx = r * Math.cos(a0), dy = r * Math.sin(a0), x0 = x2 + dx, y0 = y2 + dy, cw = 1 ^ ccw, da = ccw ? a0 - a1 : a1 - a0;
4302
+ if (this._x1 === null) {
4303
+ this._append`M${x0},${y0}`;
4304
+ } else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
4305
+ this._append`L${x0},${y0}`;
4306
+ }
4307
+ if (!r) return;
4308
+ if (da < 0) da = da % tau + tau;
4309
+ if (da > tauEpsilon) {
4310
+ this._append`A${r},${r},0,1,${cw},${x2 - dx},${y2 - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;
4311
+ } else if (da > epsilon) {
4312
+ this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x2 + r * Math.cos(a1)},${this._y1 = y2 + r * Math.sin(a1)}`;
4313
+ }
4314
+ }
4315
+ rect(x2, y2, w, h) {
4316
+ this._append`M${this._x0 = this._x1 = +x2},${this._y0 = this._y1 = +y2}h${w = +w}v${+h}h${-w}Z`;
4317
+ }
4318
+ toString() {
4319
+ return this._;
4320
+ }
4321
+ };
4322
+ function path() {
4323
+ return new Path();
4324
+ }
4325
+ path.prototype = Path.prototype;
4326
+
4327
+ // ../../node_modules/d3-shape/src/path.js
4328
+ function withPath(shape) {
4329
+ let digits = 3;
4330
+ shape.digits = function(_) {
4331
+ if (!arguments.length) return digits;
4332
+ if (_ == null) {
4333
+ digits = null;
4334
+ } else {
4335
+ const d = Math.floor(_);
4336
+ if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
4337
+ digits = d;
4338
+ }
4339
+ return shape;
4340
+ };
4341
+ return () => new Path(digits);
4342
+ }
4343
+
4344
+ // ../../node_modules/d3-shape/src/array.js
4345
+ var slice = Array.prototype.slice;
4346
+ function array_default(x2) {
4347
+ return typeof x2 === "object" && "length" in x2 ? x2 : Array.from(x2);
4348
+ }
4349
+
4350
+ // ../../node_modules/d3-shape/src/curve/linear.js
4351
+ function Linear(context) {
4352
+ this._context = context;
4353
+ }
4354
+ Linear.prototype = {
4355
+ areaStart: function() {
4356
+ this._line = 0;
4357
+ },
4358
+ areaEnd: function() {
4359
+ this._line = NaN;
4360
+ },
4361
+ lineStart: function() {
4362
+ this._point = 0;
4363
+ },
4364
+ lineEnd: function() {
4365
+ if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
4366
+ this._line = 1 - this._line;
4367
+ },
4368
+ point: function(x2, y2) {
4369
+ x2 = +x2, y2 = +y2;
4370
+ switch (this._point) {
4371
+ case 0:
4372
+ this._point = 1;
4373
+ this._line ? this._context.lineTo(x2, y2) : this._context.moveTo(x2, y2);
4374
+ break;
4375
+ case 1:
4376
+ this._point = 2;
4377
+ // falls through
4378
+ default:
4379
+ this._context.lineTo(x2, y2);
4380
+ break;
4381
+ }
4382
+ }
4383
+ };
4384
+ function linear_default(context) {
4385
+ return new Linear(context);
4386
+ }
4387
+
4388
+ // ../../node_modules/d3-shape/src/point.js
4389
+ function x(p) {
4390
+ return p[0];
4391
+ }
4392
+ function y(p) {
4393
+ return p[1];
4394
+ }
4395
+
4396
+ // ../../node_modules/d3-shape/src/line.js
4397
+ function line_default(x2, y2) {
4398
+ var defined = constant_default(true), context = null, curve = linear_default, output = null, path2 = withPath(line);
4399
+ x2 = typeof x2 === "function" ? x2 : x2 === void 0 ? x : constant_default(x2);
4400
+ y2 = typeof y2 === "function" ? y2 : y2 === void 0 ? y : constant_default(y2);
4401
+ function line(data) {
4402
+ var i, n = (data = array_default(data)).length, d, defined0 = false, buffer;
4403
+ if (context == null) output = curve(buffer = path2());
4404
+ for (i = 0; i <= n; ++i) {
4405
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
4406
+ if (defined0 = !defined0) output.lineStart();
4407
+ else output.lineEnd();
4408
+ }
4409
+ if (defined0) output.point(+x2(d, i, data), +y2(d, i, data));
4410
+ }
4411
+ if (buffer) return output = null, buffer + "" || null;
4412
+ }
4413
+ line.x = function(_) {
4414
+ return arguments.length ? (x2 = typeof _ === "function" ? _ : constant_default(+_), line) : x2;
4415
+ };
4416
+ line.y = function(_) {
4417
+ return arguments.length ? (y2 = typeof _ === "function" ? _ : constant_default(+_), line) : y2;
4418
+ };
4419
+ line.defined = function(_) {
4420
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant_default(!!_), line) : defined;
4421
+ };
4422
+ line.curve = function(_) {
4423
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
4424
+ };
4425
+ line.context = function(_) {
4426
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
4427
+ };
4428
+ return line;
4429
+ }
4430
+
4431
+ // ../../node_modules/d3-shape/src/area.js
4432
+ function area_default(x0, y0, y1) {
4433
+ var x1 = null, defined = constant_default(true), context = null, curve = linear_default, output = null, path2 = withPath(area);
4434
+ x0 = typeof x0 === "function" ? x0 : x0 === void 0 ? x : constant_default(+x0);
4435
+ y0 = typeof y0 === "function" ? y0 : y0 === void 0 ? constant_default(0) : constant_default(+y0);
4436
+ y1 = typeof y1 === "function" ? y1 : y1 === void 0 ? y : constant_default(+y1);
4437
+ function area(data) {
4438
+ var i, j, k, n = (data = array_default(data)).length, d, defined0 = false, buffer, x0z = new Array(n), y0z = new Array(n);
4439
+ if (context == null) output = curve(buffer = path2());
4440
+ for (i = 0; i <= n; ++i) {
4441
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
4442
+ if (defined0 = !defined0) {
4443
+ j = i;
4444
+ output.areaStart();
4445
+ output.lineStart();
4446
+ } else {
4447
+ output.lineEnd();
4448
+ output.lineStart();
4449
+ for (k = i - 1; k >= j; --k) {
4450
+ output.point(x0z[k], y0z[k]);
4451
+ }
4452
+ output.lineEnd();
4453
+ output.areaEnd();
4454
+ }
4455
+ }
4456
+ if (defined0) {
4457
+ x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
4458
+ output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
4459
+ }
4460
+ }
4461
+ if (buffer) return output = null, buffer + "" || null;
4462
+ }
4463
+ function arealine() {
4464
+ return line_default().defined(defined).curve(curve).context(context);
4465
+ }
4466
+ area.x = function(_) {
4467
+ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant_default(+_), x1 = null, area) : x0;
4468
+ };
4469
+ area.x0 = function(_) {
4470
+ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant_default(+_), area) : x0;
4471
+ };
4472
+ area.x1 = function(_) {
4473
+ return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant_default(+_), area) : x1;
4474
+ };
4475
+ area.y = function(_) {
4476
+ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant_default(+_), y1 = null, area) : y0;
4477
+ };
4478
+ area.y0 = function(_) {
4479
+ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant_default(+_), area) : y0;
4480
+ };
4481
+ area.y1 = function(_) {
4482
+ return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant_default(+_), area) : y1;
4483
+ };
4484
+ area.lineX0 = area.lineY0 = function() {
4485
+ return arealine().x(x0).y(y0);
4486
+ };
4487
+ area.lineY1 = function() {
4488
+ return arealine().x(x0).y(y1);
4489
+ };
4490
+ area.lineX1 = function() {
4491
+ return arealine().x(x1).y(y0);
4492
+ };
4493
+ area.defined = function(_) {
4494
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant_default(!!_), area) : defined;
4495
+ };
4496
+ area.curve = function(_) {
4497
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
4498
+ };
4499
+ area.context = function(_) {
4500
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
4501
+ };
4502
+ return area;
4503
+ }
4504
+
4505
+ // src/components/charts/LineChart/LineChart.render.ts
4506
+ import { vars as vars3 } from "@vesture/tokens";
4507
+ var DEFAULT_MARGIN = { top: 16, right: 16, bottom: 32, left: 48 };
4508
+ var SERIES_COLOR_CYCLE = [
4509
+ vars3.chart.series1,
4510
+ vars3.chart.series2,
4511
+ vars3.chart.series3,
4512
+ vars3.chart.series4,
4513
+ vars3.chart.series5,
4514
+ vars3.chart.series6,
4515
+ vars3.chart.series7,
4516
+ vars3.chart.series8
4517
+ ];
4518
+ function getSeriesColor(series, index) {
4519
+ return series.color ?? SERIES_COLOR_CYCLE[index % SERIES_COLOR_CYCLE.length];
4520
+ }
4521
+ function resolveMargin(margin) {
4522
+ return { ...DEFAULT_MARGIN, ...margin };
4523
+ }
4524
+ function inferXScaleType(data) {
4525
+ const first = data[0]?.x;
4526
+ if (first instanceof Date) return "time";
4527
+ if (typeof first === "number") return "linear";
4528
+ return "band";
4529
+ }
4530
+ function numericValue(value) {
4531
+ if (value === void 0) return void 0;
4532
+ const n = value instanceof Date ? value.getTime() : Number(value);
4533
+ return Number.isFinite(n) ? n : void 0;
4534
+ }
4535
+ function buildScales(data, series, width, height, margin, xScaleType, stacked = false) {
4536
+ const innerWidth = Math.max(0, width - margin.left - margin.right);
4537
+ const innerHeight = Math.max(0, height - margin.top - margin.bottom);
4538
+ let xScale;
4539
+ if (xScaleType === "time") {
4540
+ const xValues = data.map((d) => new Date(d.x).getTime());
4541
+ xScale = scaleTime({
4542
+ domain: [Math.min(...xValues), Math.max(...xValues)],
4543
+ range: [0, innerWidth]
4544
+ });
4545
+ } else if (xScaleType === "linear") {
4546
+ const xValues = data.map((d) => Number(d.x));
4547
+ xScale = scaleLinear({
4548
+ domain: [Math.min(...xValues), Math.max(...xValues)],
4549
+ range: [0, innerWidth]
4550
+ });
4551
+ } else {
4552
+ xScale = scaleBand({
4553
+ domain: data.map((d) => String(d.x)),
4554
+ range: [0, innerWidth],
4555
+ padding: 0.2
4556
+ });
4557
+ }
4558
+ const yValues = stacked ? data.map((d) => series.reduce((sum, s) => sum + (numericValue(d[s.key]) ?? 0), 0)) : data.flatMap(
4559
+ (d) => series.map((s) => numericValue(d[s.key])).filter((v) => v !== void 0)
4560
+ );
4561
+ const yMin = stacked ? 0 : yValues.length > 0 ? Math.min(0, ...yValues) : 0;
4562
+ const yMax = yValues.length > 0 ? Math.max(...yValues) : 1;
4563
+ const yScale = scaleLinear({
4564
+ domain: [yMin, yMax],
4565
+ range: [innerHeight, 0],
4566
+ nice: true
4567
+ });
4568
+ return { xScale, yScale, xScaleType, innerWidth, innerHeight, margin };
4569
+ }
4570
+ function getXPixel(scales, x2) {
4571
+ const { xScale, xScaleType } = scales;
4572
+ if (xScaleType === "band") {
4573
+ const pos = xScale(String(x2));
4574
+ if (pos === void 0) return void 0;
4575
+ return pos + xScale.bandwidth() / 2;
4576
+ }
4577
+ if (xScaleType === "time") {
4578
+ return xScale(new Date(x2));
4579
+ }
4580
+ return xScale(Number(x2));
4581
+ }
4582
+ function getYPixel(scales, value) {
4583
+ const n = numericValue(value);
4584
+ if (n === void 0) return void 0;
4585
+ return scales.yScale(n);
4586
+ }
4587
+ var pathGenerator = line_default().x((p) => p.x).y((p) => p.y);
4588
+ function buildLineChartLayout(data, series, width, height, margin, xScaleType) {
4589
+ const resolvedMargin = resolveMargin(margin);
4590
+ const resolvedXScaleType = xScaleType ?? inferXScaleType(data);
4591
+ const scales = buildScales(data, series, width, height, resolvedMargin, resolvedXScaleType);
4592
+ const seriesLayouts = series.map((s, index) => {
4593
+ const points = [];
4594
+ data.forEach((d, dataIndex) => {
4595
+ const x2 = getXPixel(scales, d.x);
4596
+ const y2 = getYPixel(scales, d[s.key]);
4597
+ if (x2 !== void 0 && y2 !== void 0) {
4598
+ points.push({ dataIndex, x: x2, y: y2 });
4599
+ }
4600
+ });
4601
+ return {
4602
+ key: s.key,
4603
+ label: s.label,
4604
+ color: getSeriesColor(s, index),
4605
+ points,
4606
+ path: points.length >= 2 ? pathGenerator(points) ?? "" : ""
4607
+ };
4608
+ });
4609
+ return { scales, seriesLayouts };
4610
+ }
4611
+ function findNearestDataIndex(data, scales, pixelX) {
4612
+ if (data.length === 0) return null;
4613
+ let nearestIndex = 0;
4614
+ let nearestDistance = Infinity;
4615
+ data.forEach((d, index) => {
4616
+ const x2 = getXPixel(scales, d.x);
4617
+ if (x2 === void 0) return;
4618
+ const distance = Math.abs(x2 - pixelX);
4619
+ if (distance < nearestDistance) {
4620
+ nearestDistance = distance;
4621
+ nearestIndex = index;
4622
+ }
4623
+ });
4624
+ return nearestDistance === Infinity ? null : nearestIndex;
4625
+ }
4626
+
4627
+ // src/components/charts/LineChart/LineChart.css.ts
4628
+ var emptyState4 = "chartSurfaces_emptyState__n6njm11";
4629
+ var legend = "chartSurfaces_legend__n6njm15";
4630
+ var legendItem = "chartSurfaces_legendItem__n6njm16";
4631
+ var legendItemHidden = "chartSurfaces_legendItemHidden__n6njm17";
4632
+ var legendSwatch = "chartSurfaces_legendSwatch__n6njm18";
4633
+ var overlayRect = "LineChart_overlayRect__1kfw0no0";
4634
+ var root5 = "chartSurfaces_root__n6njm10";
4635
+ var tooltip2 = "chartSurfaces_tooltip__n6njm12";
4636
+ var tooltipRow = "chartSurfaces_tooltipRow__n6njm13";
4637
+ var tooltipSwatch = "chartSurfaces_tooltipSwatch__n6njm14";
4638
+
4639
+ // src/components/charts/LineChart/LineChart.tsx
4640
+ import { jsx as jsx43, jsxs as jsxs26 } from "react/jsx-runtime";
4641
+ function LineChart({
4642
+ data,
4643
+ series,
4644
+ width,
4645
+ height,
4646
+ margin,
4647
+ xScale
4648
+ }) {
4649
+ if (data.length === 0) {
4650
+ return /* @__PURE__ */ jsx43("div", { className: root5, style: { width, height }, children: /* @__PURE__ */ jsx43("div", { className: emptyState4, style: { width, height }, children: "No data" }) });
4651
+ }
4652
+ const { scales, seriesLayouts } = buildLineChartLayout(data, series, width, height, margin, xScale);
4653
+ const { xScale: scaleX, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
4654
+ return /* @__PURE__ */ jsx43("div", { className: root5, children: /* @__PURE__ */ jsx43("svg", { width, height, role: "img", "aria-label": "Line chart", children: /* @__PURE__ */ jsxs26(Group, { left: resolvedMargin.left, top: resolvedMargin.top, children: [
4655
+ /* @__PURE__ */ jsx43(GridRows, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars4.chart.grid }),
4656
+ seriesLayouts.map((s) => /* @__PURE__ */ jsx43(
4657
+ LinePath,
4658
+ {
4659
+ data: s.points,
4660
+ x: (p) => p.x,
4661
+ y: (p) => p.y,
4662
+ stroke: s.color,
4663
+ strokeWidth: 2,
4664
+ fill: "none"
4665
+ },
4666
+ s.key
4667
+ )),
4668
+ /* @__PURE__ */ jsx43(
4669
+ AxisBottom,
4670
+ {
4671
+ top: innerHeight,
4672
+ scale: scaleX,
4673
+ stroke: vars4.chart.axis,
4674
+ tickStroke: vars4.chart.axis,
4675
+ tickLabelProps: () => ({ fill: vars4.chart.axis, fontSize: 11, textAnchor: "middle" })
4676
+ }
4677
+ ),
4678
+ /* @__PURE__ */ jsx43(
4679
+ AxisLeft,
4680
+ {
4681
+ scale: yScale,
4682
+ stroke: vars4.chart.axis,
4683
+ tickStroke: vars4.chart.axis,
4684
+ tickLabelProps: () => ({ fill: vars4.chart.axis, fontSize: 11, textAnchor: "end", dx: "-0.25em" })
4685
+ }
4686
+ )
4687
+ ] }) }) });
4688
+ }
4689
+
4690
+ // src/components/charts/LineChart/LineChart.interactive.tsx
4691
+ import { useMemo as useMemo6, useState as useState17 } from "react";
4692
+ import { ParentSize } from "@visx/responsive";
4693
+ import { TooltipWithBounds, useTooltip } from "@visx/tooltip";
4694
+ import { jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
4695
+ function InteractiveLineChart({
4696
+ data,
4697
+ series,
4698
+ margin,
4699
+ xScale,
4700
+ height = 320
4701
+ }) {
4702
+ const [hiddenKeys, setHiddenKeys] = useState17(/* @__PURE__ */ new Set());
4703
+ const coloredSeries = useMemo6(
4704
+ () => series.map((s, index) => ({ ...s, color: s.color ?? getSeriesColor(s, index) })),
4705
+ [series]
4706
+ );
4707
+ const visibleSeries = useMemo6(
4708
+ () => coloredSeries.filter((s) => !hiddenKeys.has(s.key)),
4709
+ [coloredSeries, hiddenKeys]
4710
+ );
4711
+ const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip();
4712
+ function toggleSeries(key) {
4713
+ setHiddenKeys((prev) => {
4714
+ const next = new Set(prev);
4715
+ if (next.has(key)) {
4716
+ next.delete(key);
4717
+ } else {
4718
+ next.add(key);
4719
+ }
4720
+ return next;
4721
+ });
4722
+ }
4723
+ return /* @__PURE__ */ jsxs27("div", { className: root5, children: [
4724
+ /* @__PURE__ */ jsx44(ParentSize, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
4725
+ if (width === 0) return null;
4726
+ const { scales } = buildLineChartLayout(data, visibleSeries, width, height, margin, xScale);
4727
+ function handleMouseMove(event) {
4728
+ const bounds = event.currentTarget.getBoundingClientRect();
4729
+ const pixelX = event.clientX - bounds.left;
4730
+ const dataIndex = findNearestDataIndex(data, scales, pixelX);
4731
+ if (dataIndex === null) {
4732
+ hideTooltip();
4733
+ return;
4734
+ }
4735
+ const dataPoint = data[dataIndex];
4736
+ const xPixel = getXPixel(scales, dataPoint.x) ?? pixelX;
4737
+ showTooltip({
4738
+ tooltipData: { dataPoint, visibleSeries },
4739
+ tooltipLeft: scales.margin.left + xPixel,
4740
+ tooltipTop: 0
4741
+ });
4742
+ }
4743
+ return /* @__PURE__ */ jsxs27("div", { style: { position: "relative", width, height }, children: [
4744
+ /* @__PURE__ */ jsx44(
4745
+ LineChart,
4746
+ {
4747
+ data,
4748
+ series: visibleSeries,
4749
+ width,
4750
+ height,
4751
+ margin,
4752
+ xScale
4753
+ }
4754
+ ),
4755
+ /* @__PURE__ */ jsx44(
4756
+ "svg",
4757
+ {
4758
+ width,
4759
+ height,
4760
+ style: { position: "absolute", top: 0, left: 0 },
4761
+ "aria-hidden": "true",
4762
+ children: /* @__PURE__ */ jsx44(
4763
+ "rect",
4764
+ {
4765
+ className: overlayRect,
4766
+ "data-testid": "line-chart-overlay",
4767
+ x: scales.margin.left,
4768
+ y: scales.margin.top,
4769
+ width: scales.innerWidth,
4770
+ height: scales.innerHeight,
4771
+ onMouseMove: handleMouseMove,
4772
+ onMouseLeave: () => hideTooltip()
4773
+ }
4774
+ )
4775
+ }
4776
+ ),
4777
+ tooltipOpen && tooltipData ? /* @__PURE__ */ jsxs27(TooltipWithBounds, { left: tooltipLeft, top: tooltipTop, className: tooltip2, children: [
4778
+ /* @__PURE__ */ jsx44("div", { children: String(tooltipData.dataPoint.x) }),
4779
+ tooltipData.visibleSeries.map((s) => /* @__PURE__ */ jsxs27("div", { className: tooltipRow, children: [
4780
+ /* @__PURE__ */ jsx44("span", { className: tooltipSwatch, style: { background: s.color } }),
4781
+ /* @__PURE__ */ jsxs27("span", { children: [
4782
+ s.label,
4783
+ ": ",
4784
+ String(tooltipData.dataPoint[s.key])
4785
+ ] })
4786
+ ] }, s.key))
4787
+ ] }) : null
4788
+ ] });
4789
+ } }),
4790
+ /* @__PURE__ */ jsx44("div", { className: legend, children: coloredSeries.map((s) => {
4791
+ const hidden = hiddenKeys.has(s.key);
4792
+ return /* @__PURE__ */ jsxs27(
4793
+ "button",
4794
+ {
4795
+ type: "button",
4796
+ className: [legendItem, hidden ? legendItemHidden : null].filter(Boolean).join(" "),
4797
+ onClick: () => toggleSeries(s.key),
4798
+ "aria-pressed": !hidden,
4799
+ children: [
4800
+ /* @__PURE__ */ jsx44("span", { className: legendSwatch, style: { background: s.color } }),
4801
+ s.label
4802
+ ]
4803
+ },
4804
+ s.key
4805
+ );
4806
+ }) })
4807
+ ] });
4808
+ }
4809
+
4810
+ // src/components/charts/BarChart/BarChart.tsx
4811
+ import { AxisBottom as AxisBottom2, AxisLeft as AxisLeft2 } from "@visx/axis";
4812
+ import { GridRows as GridRows2 } from "@visx/grid";
4813
+ import { Group as Group2 } from "@visx/group";
4814
+ import { BarGroup, BarStack } from "@visx/shape";
4815
+ import { vars as vars6 } from "@vesture/tokens";
4816
+
4817
+ // src/components/charts/BarChart/BarChart.render.ts
4818
+ import { scaleBand as scaleBand2, scaleLinear as scaleLinear2 } from "@visx/scale";
4819
+ import { vars as vars5 } from "@vesture/tokens";
4820
+ var DEFAULT_MARGIN2 = { top: 16, right: 16, bottom: 32, left: 48 };
4821
+ var SERIES_COLOR_CYCLE2 = [
4822
+ vars5.chart.series1,
4823
+ vars5.chart.series2,
4824
+ vars5.chart.series3,
4825
+ vars5.chart.series4,
4826
+ vars5.chart.series5,
4827
+ vars5.chart.series6,
4828
+ vars5.chart.series7,
4829
+ vars5.chart.series8
4830
+ ];
4831
+ function getSeriesColor2(series, index) {
4832
+ return series.color ?? SERIES_COLOR_CYCLE2[index % SERIES_COLOR_CYCLE2.length];
4833
+ }
4834
+ function buildSeriesColorMap(series) {
4835
+ const map = {};
4836
+ series.forEach((s, index) => {
4837
+ map[s.key] = getSeriesColor2(s, index);
4838
+ });
4839
+ return map;
4840
+ }
4841
+ function resolveMargin2(margin) {
4842
+ return { ...DEFAULT_MARGIN2, ...margin };
4843
+ }
4844
+ function numericValue2(value) {
4845
+ if (value === void 0) return 0;
4846
+ const n = Number(value);
4847
+ return Number.isFinite(n) ? n : 0;
4848
+ }
4849
+ function buildScales2(data, series, width, height, margin, layout) {
4850
+ const innerWidth = Math.max(0, width - margin.left - margin.right);
4851
+ const innerHeight = Math.max(0, height - margin.top - margin.bottom);
4852
+ const x0Scale = scaleBand2({
4853
+ domain: data.map((d) => d.category),
4854
+ range: [0, innerWidth],
4855
+ padding: 0.2
4856
+ });
4857
+ const x1Scale = layout === "grouped" ? scaleBand2({
4858
+ domain: series.map((s) => s.key),
4859
+ range: [0, x0Scale.bandwidth()],
4860
+ padding: 0.1
4861
+ }) : void 0;
4862
+ const yMax = layout === "stacked" ? Math.max(0, ...data.map((d) => series.reduce((sum, s) => sum + numericValue2(d[s.key]), 0))) : Math.max(0, ...data.flatMap((d) => series.map((s) => numericValue2(d[s.key]))));
4863
+ const yScale = scaleLinear2({
4864
+ domain: [0, yMax > 0 ? yMax : 1],
4865
+ range: [innerHeight, 0],
4866
+ nice: true
4867
+ });
4868
+ return { x0Scale, x1Scale, xScale: x0Scale, yScale, layout, innerWidth, innerHeight, margin };
4869
+ }
4870
+ function buildBarChartLayout(data, series, width, height, margin, layout = "grouped") {
4871
+ const resolvedMargin = resolveMargin2(margin);
4872
+ const scales = buildScales2(data, series, width, height, resolvedMargin, layout);
4873
+ const colorMap = buildSeriesColorMap(series);
4874
+ return { scales, colorMap };
4875
+ }
4876
+
4877
+ // src/components/charts/BarChart/BarChart.css.ts
4878
+ var emptyState5 = "chartSurfaces_emptyState__n6njm11";
4879
+ var legend2 = "chartSurfaces_legend__n6njm15";
4880
+ var legendItem2 = "chartSurfaces_legendItem__n6njm16";
4881
+ var legendItemHidden2 = "chartSurfaces_legendItemHidden__n6njm17";
4882
+ var legendSwatch2 = "chartSurfaces_legendSwatch__n6njm18";
4883
+ var root6 = "chartSurfaces_root__n6njm10";
4884
+ var tooltip3 = "chartSurfaces_tooltip__n6njm12";
4885
+ var tooltipRow2 = "chartSurfaces_tooltipRow__n6njm13";
4886
+ var tooltipSwatch2 = "chartSurfaces_tooltipSwatch__n6njm14";
4887
+
4888
+ // src/components/charts/BarChart/BarChart.tsx
4889
+ import { jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
4890
+ function BarChart({
4891
+ data,
4892
+ series,
4893
+ width,
4894
+ height,
4895
+ margin,
4896
+ layout = "grouped"
4897
+ }) {
4898
+ if (data.length === 0) {
4899
+ return /* @__PURE__ */ jsx45("div", { className: root6, style: { width, height }, children: /* @__PURE__ */ jsx45("div", { className: emptyState5, style: { width, height }, children: "No data" }) });
4900
+ }
4901
+ const { scales, colorMap } = buildBarChartLayout(data, series, width, height, margin, layout);
4902
+ const { x0Scale, x1Scale, xScale, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
4903
+ const keys = series.map((s) => s.key);
4904
+ const color = (key, index) => colorMap[key] ?? SERIES_COLOR_CYCLE2[index % 8];
4905
+ return /* @__PURE__ */ jsx45("div", { className: root6, children: /* @__PURE__ */ jsx45("svg", { width, height, role: "img", "aria-label": "Bar chart", children: /* @__PURE__ */ jsxs28(Group2, { left: resolvedMargin.left, top: resolvedMargin.top, children: [
4906
+ /* @__PURE__ */ jsx45(GridRows2, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars6.chart.grid }),
4907
+ layout === "stacked" ? /* @__PURE__ */ jsx45(BarStack, { data, keys, x: (d) => d.category, xScale, yScale, color }) : /* @__PURE__ */ jsx45(
4908
+ BarGroup,
4909
+ {
4910
+ data,
4911
+ keys,
4912
+ height: innerHeight,
4913
+ x0: (d) => d.category,
4914
+ x0Scale,
4915
+ x1Scale,
4916
+ yScale,
4917
+ color
4918
+ }
4919
+ ),
4920
+ /* @__PURE__ */ jsx45(
4921
+ AxisBottom2,
4922
+ {
4923
+ top: innerHeight,
4924
+ scale: x0Scale,
4925
+ stroke: vars6.chart.axis,
4926
+ tickStroke: vars6.chart.axis,
4927
+ tickLabelProps: () => ({ fill: vars6.chart.axis, fontSize: 11, textAnchor: "middle" })
4928
+ }
4929
+ ),
4930
+ /* @__PURE__ */ jsx45(
4931
+ AxisLeft2,
4932
+ {
4933
+ scale: yScale,
4934
+ stroke: vars6.chart.axis,
4935
+ tickStroke: vars6.chart.axis,
4936
+ tickLabelProps: () => ({ fill: vars6.chart.axis, fontSize: 11, textAnchor: "end", dx: "-0.25em" })
4937
+ }
4938
+ )
4939
+ ] }) }) });
4940
+ }
4941
+
4942
+ // src/components/charts/BarChart/BarChart.interactive.tsx
4943
+ import { useMemo as useMemo7, useState as useState18 } from "react";
4944
+ import { AxisBottom as AxisBottom3, AxisLeft as AxisLeft3 } from "@visx/axis";
4945
+ import { GridRows as GridRows3 } from "@visx/grid";
4946
+ import { Group as Group3 } from "@visx/group";
4947
+ import { ParentSize as ParentSize2 } from "@visx/responsive";
4948
+ import { Bar, BarGroup as BarGroup2, BarStack as BarStack2 } from "@visx/shape";
4949
+ import { TooltipWithBounds as TooltipWithBounds2, useTooltip as useTooltip2 } from "@visx/tooltip";
4950
+ import { vars as vars7 } from "@vesture/tokens";
4951
+ import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
4952
+ function InteractiveBarChart({
4953
+ data,
4954
+ series,
4955
+ margin,
4956
+ layout = "grouped",
4957
+ height = 320
4958
+ }) {
4959
+ const [hiddenKeys, setHiddenKeys] = useState18(/* @__PURE__ */ new Set());
4960
+ const coloredSeries = useMemo7(
4961
+ () => series.map((s, index) => ({ ...s, color: s.color ?? getSeriesColor2(s, index) })),
4962
+ [series]
4963
+ );
4964
+ const visibleSeries = useMemo7(
4965
+ () => coloredSeries.filter((s) => !hiddenKeys.has(s.key)),
4966
+ [coloredSeries, hiddenKeys]
4967
+ );
4968
+ const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip2();
4969
+ function toggleSeries(key) {
4970
+ setHiddenKeys((prev) => {
4971
+ const next = new Set(prev);
4972
+ if (next.has(key)) {
4973
+ next.delete(key);
4974
+ } else {
4975
+ next.add(key);
4976
+ }
4977
+ return next;
4978
+ });
4979
+ }
4980
+ if (data.length === 0) {
4981
+ return /* @__PURE__ */ jsx46("div", { className: root6, style: { height }, children: /* @__PURE__ */ jsx46("div", { className: emptyState5, style: { height }, children: "No data" }) });
4982
+ }
4983
+ return /* @__PURE__ */ jsxs29("div", { className: root6, children: [
4984
+ /* @__PURE__ */ jsx46(ParentSize2, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
4985
+ if (width === 0) return null;
4986
+ const { scales, colorMap } = buildBarChartLayout(data, visibleSeries, width, height, margin, layout);
4987
+ const { x0Scale, x1Scale, xScale, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
4988
+ const keys = visibleSeries.map((s) => s.key);
4989
+ const seriesByKey = new Map(visibleSeries.map((s) => [s.key, s]));
4990
+ const color = (key, index) => colorMap[key] ?? SERIES_COLOR_CYCLE2[index % 8];
4991
+ function handleBarHover(categoryValue, seriesKey, value, event) {
4992
+ const s = seriesByKey.get(seriesKey);
4993
+ if (!s) return;
4994
+ const bounds = event.currentTarget;
4995
+ const x2 = Number(bounds.getAttribute("x") ?? 0);
4996
+ const y2 = Number(bounds.getAttribute("y") ?? 0);
4997
+ const barWidth = Number(bounds.getAttribute("width") ?? 0);
4998
+ showTooltip({
4999
+ tooltipData: { category: categoryValue, series: s, value },
5000
+ tooltipLeft: resolvedMargin.left + x2 + barWidth / 2,
5001
+ tooltipTop: resolvedMargin.top + y2
5002
+ });
5003
+ }
5004
+ return /* @__PURE__ */ jsxs29("div", { style: { position: "relative", width, height }, children: [
5005
+ /* @__PURE__ */ jsx46("svg", { width, height, role: "img", "aria-label": "Bar chart", children: /* @__PURE__ */ jsxs29(Group3, { left: resolvedMargin.left, top: resolvedMargin.top, children: [
5006
+ /* @__PURE__ */ jsx46(GridRows3, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars7.chart.grid }),
5007
+ layout === "stacked" ? /* @__PURE__ */ jsx46(
5008
+ BarStack2,
5009
+ {
5010
+ data,
5011
+ keys,
5012
+ x: (d) => d.category,
5013
+ xScale,
5014
+ yScale,
5015
+ color,
5016
+ children: (barStacks) => barStacks.map(
5017
+ (barStack) => barStack.bars.map((bar) => /* @__PURE__ */ jsx46(
5018
+ Bar,
5019
+ {
5020
+ x: bar.x,
5021
+ y: bar.y,
5022
+ width: bar.width,
5023
+ height: bar.height,
5024
+ fill: bar.color,
5025
+ onMouseEnter: (event) => handleBarHover(
5026
+ bar.bar.data.category,
5027
+ String(barStack.key),
5028
+ Number(bar.bar.data[barStack.key]),
5029
+ event
5030
+ ),
5031
+ onMouseLeave: () => hideTooltip()
5032
+ },
5033
+ `bar-stack-${barStack.index}-${bar.index}`
5034
+ ))
5035
+ )
5036
+ }
5037
+ ) : /* @__PURE__ */ jsx46(
5038
+ BarGroup2,
5039
+ {
5040
+ data,
5041
+ keys,
5042
+ height: innerHeight,
5043
+ x0: (d) => d.category,
5044
+ x0Scale,
5045
+ x1Scale,
5046
+ yScale,
5047
+ color,
5048
+ children: (barGroups) => barGroups.map((barGroup) => /* @__PURE__ */ jsx46(Group3, { left: barGroup.x0, children: barGroup.bars.map((bar) => /* @__PURE__ */ jsx46(
5049
+ Bar,
5050
+ {
5051
+ x: bar.x,
5052
+ y: bar.y,
5053
+ width: bar.width,
5054
+ height: bar.height,
5055
+ fill: bar.color,
5056
+ onMouseEnter: (event) => handleBarHover(data[barGroup.index].category, String(bar.key), bar.value, event),
5057
+ onMouseLeave: () => hideTooltip()
5058
+ },
5059
+ `bar-group-bar-${barGroup.index}-${bar.key}`
5060
+ )) }, `bar-group-${barGroup.index}`))
5061
+ }
5062
+ ),
5063
+ /* @__PURE__ */ jsx46(
5064
+ AxisBottom3,
5065
+ {
5066
+ top: innerHeight,
5067
+ scale: x0Scale,
5068
+ stroke: vars7.chart.axis,
5069
+ tickStroke: vars7.chart.axis,
5070
+ tickLabelProps: () => ({ fill: vars7.chart.axis, fontSize: 11, textAnchor: "middle" })
5071
+ }
5072
+ ),
5073
+ /* @__PURE__ */ jsx46(
5074
+ AxisLeft3,
5075
+ {
5076
+ scale: yScale,
5077
+ stroke: vars7.chart.axis,
5078
+ tickStroke: vars7.chart.axis,
5079
+ tickLabelProps: () => ({
5080
+ fill: vars7.chart.axis,
5081
+ fontSize: 11,
5082
+ textAnchor: "end",
5083
+ dx: "-0.25em"
5084
+ })
5085
+ }
5086
+ )
5087
+ ] }) }),
5088
+ tooltipOpen && tooltipData ? /* @__PURE__ */ jsxs29(TooltipWithBounds2, { left: tooltipLeft, top: tooltipTop, className: tooltip3, children: [
5089
+ /* @__PURE__ */ jsx46("div", { children: tooltipData.category }),
5090
+ /* @__PURE__ */ jsxs29("div", { className: tooltipRow2, children: [
5091
+ /* @__PURE__ */ jsx46("span", { className: tooltipSwatch2, style: { background: tooltipData.series.color } }),
5092
+ /* @__PURE__ */ jsxs29("span", { children: [
5093
+ tooltipData.series.label,
5094
+ ": ",
5095
+ tooltipData.value
5096
+ ] })
5097
+ ] })
5098
+ ] }) : null
5099
+ ] });
5100
+ } }),
5101
+ /* @__PURE__ */ jsx46("div", { className: legend2, children: coloredSeries.map((s) => {
5102
+ const hidden = hiddenKeys.has(s.key);
5103
+ return /* @__PURE__ */ jsxs29(
5104
+ "button",
5105
+ {
5106
+ type: "button",
5107
+ className: [legendItem2, hidden ? legendItemHidden2 : null].filter(Boolean).join(" "),
5108
+ onClick: () => toggleSeries(s.key),
5109
+ "aria-pressed": !hidden,
5110
+ children: [
5111
+ /* @__PURE__ */ jsx46("span", { className: legendSwatch2, style: { background: s.color } }),
5112
+ s.label
5113
+ ]
5114
+ },
5115
+ s.key
5116
+ );
5117
+ }) })
5118
+ ] });
5119
+ }
5120
+
5121
+ // src/components/charts/AreaChart/AreaChart.tsx
5122
+ import { AxisBottom as AxisBottom4, AxisLeft as AxisLeft4 } from "@visx/axis";
5123
+ import { GridRows as GridRows4 } from "@visx/grid";
5124
+ import { Group as Group4 } from "@visx/group";
5125
+ import { Area } from "@visx/shape";
5126
+ import { vars as vars8 } from "@vesture/tokens";
5127
+
5128
+ // src/components/charts/AreaChart/AreaChart.render.ts
5129
+ var OVERLAP_FILL_OPACITY = 0.35;
5130
+ var areaGenerator = area_default().x((p) => p.x).y0((p) => p.y0).y1((p) => p.y1);
5131
+ function buildAreaChartLayout(data, series, width, height, margin, xScaleType, stacked = false) {
5132
+ const resolvedMargin = resolveMargin(margin);
5133
+ const resolvedXScaleType = xScaleType ?? inferXScaleType(data);
5134
+ const scales = buildScales(data, series, width, height, resolvedMargin, resolvedXScaleType, stacked);
5135
+ const cumulative = data.map(() => 0);
5136
+ const seriesLayouts = series.map((s, index) => {
5137
+ const points = [];
5138
+ data.forEach((d, dataIndex) => {
5139
+ const rawValue = numericValue(d[s.key]);
5140
+ if (!stacked && rawValue === void 0) return;
5141
+ const x2 = getXPixel(scales, d.x);
5142
+ if (x2 === void 0) return;
5143
+ const baseline = stacked ? cumulative[dataIndex] : 0;
5144
+ const top = stacked ? baseline + (rawValue ?? 0) : rawValue;
5145
+ if (stacked) cumulative[dataIndex] = top;
5146
+ points.push({ dataIndex, x: x2, y0: scales.yScale(baseline), y1: scales.yScale(top) });
5147
+ });
5148
+ return {
5149
+ key: s.key,
5150
+ label: s.label,
5151
+ color: getSeriesColor(s, index),
5152
+ opacity: stacked ? 1 : OVERLAP_FILL_OPACITY,
5153
+ points,
5154
+ path: points.length >= 2 ? areaGenerator(points) ?? "" : ""
5155
+ };
5156
+ });
5157
+ return { scales, seriesLayouts };
5158
+ }
5159
+
5160
+ // src/components/charts/AreaChart/AreaChart.css.ts
5161
+ var emptyState6 = "chartSurfaces_emptyState__n6njm11";
5162
+ var legend3 = "chartSurfaces_legend__n6njm15";
5163
+ var legendItem3 = "chartSurfaces_legendItem__n6njm16";
5164
+ var legendItemHidden3 = "chartSurfaces_legendItemHidden__n6njm17";
5165
+ var legendSwatch3 = "chartSurfaces_legendSwatch__n6njm18";
5166
+ var overlayRect2 = "AreaChart_overlayRect__1cqtbh30";
5167
+ var root7 = "chartSurfaces_root__n6njm10";
5168
+ var tooltip4 = "chartSurfaces_tooltip__n6njm12";
5169
+ var tooltipRow3 = "chartSurfaces_tooltipRow__n6njm13";
5170
+ var tooltipSwatch3 = "chartSurfaces_tooltipSwatch__n6njm14";
5171
+
5172
+ // src/components/charts/AreaChart/AreaChart.tsx
5173
+ import { jsx as jsx47, jsxs as jsxs30 } from "react/jsx-runtime";
5174
+ function AreaChart({
5175
+ data,
5176
+ series,
5177
+ width,
5178
+ height,
5179
+ margin,
5180
+ xScale,
5181
+ stacked = false
5182
+ }) {
5183
+ if (data.length === 0) {
5184
+ return /* @__PURE__ */ jsx47("div", { className: root7, style: { width, height }, children: /* @__PURE__ */ jsx47("div", { className: emptyState6, style: { width, height }, children: "No data" }) });
5185
+ }
5186
+ const { scales, seriesLayouts } = buildAreaChartLayout(data, series, width, height, margin, xScale, stacked);
5187
+ const { xScale: scaleX, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
5188
+ return /* @__PURE__ */ jsx47("div", { className: root7, children: /* @__PURE__ */ jsx47("svg", { width, height, role: "img", "aria-label": "Area chart", children: /* @__PURE__ */ jsxs30(Group4, { left: resolvedMargin.left, top: resolvedMargin.top, children: [
5189
+ /* @__PURE__ */ jsx47(GridRows4, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars8.chart.grid }),
5190
+ seriesLayouts.map((s) => /* @__PURE__ */ jsx47(
5191
+ Area,
5192
+ {
5193
+ data: s.points,
5194
+ x: (p) => p.x,
5195
+ y0: (p) => p.y0,
5196
+ y1: (p) => p.y1,
5197
+ fill: s.color,
5198
+ fillOpacity: s.opacity,
5199
+ stroke: s.color,
5200
+ strokeWidth: 1.5
5201
+ },
5202
+ s.key
5203
+ )),
5204
+ /* @__PURE__ */ jsx47(
5205
+ AxisBottom4,
5206
+ {
5207
+ top: innerHeight,
5208
+ scale: scaleX,
5209
+ stroke: vars8.chart.axis,
5210
+ tickStroke: vars8.chart.axis,
5211
+ tickLabelProps: () => ({ fill: vars8.chart.axis, fontSize: 11, textAnchor: "middle" })
5212
+ }
5213
+ ),
5214
+ /* @__PURE__ */ jsx47(
5215
+ AxisLeft4,
5216
+ {
5217
+ scale: yScale,
5218
+ stroke: vars8.chart.axis,
5219
+ tickStroke: vars8.chart.axis,
5220
+ tickLabelProps: () => ({ fill: vars8.chart.axis, fontSize: 11, textAnchor: "end", dx: "-0.25em" })
5221
+ }
5222
+ )
5223
+ ] }) }) });
5224
+ }
5225
+
5226
+ // src/components/charts/AreaChart/AreaChart.interactive.tsx
5227
+ import { useMemo as useMemo8, useState as useState19 } from "react";
5228
+ import { ParentSize as ParentSize3 } from "@visx/responsive";
5229
+ import { TooltipWithBounds as TooltipWithBounds3, useTooltip as useTooltip3 } from "@visx/tooltip";
5230
+ import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
5231
+ function InteractiveAreaChart({
5232
+ data,
5233
+ series,
5234
+ margin,
5235
+ xScale,
5236
+ stacked = false,
5237
+ height = 320
5238
+ }) {
5239
+ const [hiddenKeys, setHiddenKeys] = useState19(/* @__PURE__ */ new Set());
5240
+ const coloredSeries = useMemo8(
5241
+ () => series.map((s, index) => ({ ...s, color: s.color ?? getSeriesColor(s, index) })),
5242
+ [series]
5243
+ );
5244
+ const visibleSeries = useMemo8(
5245
+ () => coloredSeries.filter((s) => !hiddenKeys.has(s.key)),
5246
+ [coloredSeries, hiddenKeys]
5247
+ );
5248
+ const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip3();
5249
+ function toggleSeries(key) {
5250
+ setHiddenKeys((prev) => {
5251
+ const next = new Set(prev);
5252
+ if (next.has(key)) {
5253
+ next.delete(key);
5254
+ } else {
5255
+ next.add(key);
5256
+ }
5257
+ return next;
5258
+ });
5259
+ }
5260
+ return /* @__PURE__ */ jsxs31("div", { className: root7, children: [
5261
+ /* @__PURE__ */ jsx48(ParentSize3, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
5262
+ if (width === 0) return null;
5263
+ const { scales } = buildAreaChartLayout(data, visibleSeries, width, height, margin, xScale, stacked);
5264
+ function handleMouseMove(event) {
5265
+ const bounds = event.currentTarget.getBoundingClientRect();
5266
+ const pixelX = event.clientX - bounds.left;
5267
+ const dataIndex = findNearestDataIndex(data, scales, pixelX);
5268
+ if (dataIndex === null) {
5269
+ hideTooltip();
5270
+ return;
5271
+ }
5272
+ const dataPoint = data[dataIndex];
5273
+ const xPixel = getXPixel(scales, dataPoint.x) ?? pixelX;
5274
+ showTooltip({
5275
+ tooltipData: { dataPoint, visibleSeries },
5276
+ tooltipLeft: scales.margin.left + xPixel,
5277
+ tooltipTop: 0
5278
+ });
5279
+ }
5280
+ return /* @__PURE__ */ jsxs31("div", { style: { position: "relative", width, height }, children: [
5281
+ /* @__PURE__ */ jsx48(
5282
+ AreaChart,
5283
+ {
5284
+ data,
5285
+ series: visibleSeries,
5286
+ width,
5287
+ height,
5288
+ margin,
5289
+ xScale,
5290
+ stacked
5291
+ }
5292
+ ),
5293
+ /* @__PURE__ */ jsx48(
5294
+ "svg",
5295
+ {
5296
+ width,
5297
+ height,
5298
+ style: { position: "absolute", top: 0, left: 0 },
5299
+ "aria-hidden": "true",
5300
+ children: /* @__PURE__ */ jsx48(
5301
+ "rect",
5302
+ {
5303
+ className: overlayRect2,
5304
+ "data-testid": "area-chart-overlay",
5305
+ x: scales.margin.left,
5306
+ y: scales.margin.top,
5307
+ width: scales.innerWidth,
5308
+ height: scales.innerHeight,
5309
+ onMouseMove: handleMouseMove,
5310
+ onMouseLeave: () => hideTooltip()
5311
+ }
5312
+ )
5313
+ }
5314
+ ),
5315
+ tooltipOpen && tooltipData ? /* @__PURE__ */ jsxs31(TooltipWithBounds3, { left: tooltipLeft, top: tooltipTop, className: tooltip4, children: [
5316
+ /* @__PURE__ */ jsx48("div", { children: String(tooltipData.dataPoint.x) }),
5317
+ tooltipData.visibleSeries.map((s) => /* @__PURE__ */ jsxs31("div", { className: tooltipRow3, children: [
5318
+ /* @__PURE__ */ jsx48("span", { className: tooltipSwatch3, style: { background: s.color } }),
5319
+ /* @__PURE__ */ jsxs31("span", { children: [
5320
+ s.label,
5321
+ ": ",
5322
+ String(tooltipData.dataPoint[s.key])
5323
+ ] })
5324
+ ] }, s.key))
5325
+ ] }) : null
5326
+ ] });
5327
+ } }),
5328
+ /* @__PURE__ */ jsx48("div", { className: legend3, children: coloredSeries.map((s) => {
5329
+ const hidden = hiddenKeys.has(s.key);
5330
+ return /* @__PURE__ */ jsxs31(
5331
+ "button",
5332
+ {
5333
+ type: "button",
5334
+ className: [legendItem3, hidden ? legendItemHidden3 : null].filter(Boolean).join(" "),
5335
+ onClick: () => toggleSeries(s.key),
5336
+ "aria-pressed": !hidden,
5337
+ children: [
5338
+ /* @__PURE__ */ jsx48("span", { className: legendSwatch3, style: { background: s.color } }),
5339
+ s.label
5340
+ ]
5341
+ },
5342
+ s.key
5343
+ );
5344
+ }) })
5345
+ ] });
5346
+ }
5347
+
5348
+ // src/components/charts/PieChart/PieChart.tsx
5349
+ import { Group as Group5 } from "@visx/group";
5350
+ import { Pie } from "@visx/shape";
5351
+ import { vars as vars10 } from "@vesture/tokens";
5352
+
5353
+ // src/components/charts/PieChart/PieChart.render.ts
5354
+ import { vars as vars9 } from "@vesture/tokens";
5355
+ var SERIES_COLOR_CYCLE3 = [
5356
+ vars9.chart.series1,
5357
+ vars9.chart.series2,
5358
+ vars9.chart.series3,
5359
+ vars9.chart.series4,
5360
+ vars9.chart.series5,
5361
+ vars9.chart.series6,
5362
+ vars9.chart.series7,
5363
+ vars9.chart.series8
5364
+ ];
5365
+ function getSeriesColor3(slice2, index) {
5366
+ return slice2.color ?? SERIES_COLOR_CYCLE3[index % SERIES_COLOR_CYCLE3.length];
5367
+ }
5368
+ function computePercentages(slices) {
5369
+ const total = slices.reduce((sum, s) => sum + s.value, 0);
5370
+ return slices.map((s) => ({ ...s, percentage: total > 0 ? s.value / total * 100 : 0 }));
5371
+ }
5372
+ function colorSlices(data) {
5373
+ return data.map((d, index) => ({ key: d.key, label: d.label, value: d.value, color: getSeriesColor3(d, index) }));
5374
+ }
5375
+ function preparePieSlices(data) {
5376
+ const positive = colorSlices(data).filter((s) => s.value > 0);
5377
+ return computePercentages(positive);
5378
+ }
5379
+ var MIN_LABEL_ARC_LENGTH_PX = 28;
5380
+ function isLabelFittable(startAngle, endAngle, outerRadius) {
5381
+ return (endAngle - startAngle) * outerRadius >= MIN_LABEL_ARC_LENGTH_PX;
5382
+ }
5383
+ function arcBisectorDirection(startAngle, endAngle) {
5384
+ const bisector = (startAngle + endAngle) / 2;
5385
+ return [Math.sin(bisector), -Math.cos(bisector)];
5386
+ }
5387
+
5388
+ // src/components/charts/PieChart/PieChart.css.ts
5389
+ var emptyState7 = "chartSurfaces_emptyState__n6njm11";
5390
+ var legend4 = "chartSurfaces_legend__n6njm15";
5391
+ var legendItem4 = "chartSurfaces_legendItem__n6njm16";
5392
+ var legendItemHidden4 = "chartSurfaces_legendItemHidden__n6njm17";
5393
+ var legendPercentage = "PieChart_legendPercentage__19xd4rn0";
5394
+ var legendSwatch4 = "chartSurfaces_legendSwatch__n6njm18";
5395
+ var root8 = "chartSurfaces_root__n6njm10";
5396
+ var sliceGroup = "PieChart_sliceGroup__19xd4rn1";
5397
+ var tooltip5 = "chartSurfaces_tooltip__n6njm12";
5398
+ var tooltipRow4 = "chartSurfaces_tooltipRow__n6njm13";
5399
+ var tooltipSwatch4 = "chartSurfaces_tooltipSwatch__n6njm14";
5400
+
5401
+ // src/components/charts/PieChart/PieChart.tsx
5402
+ import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
5403
+ var OUTER_PADDING = 8;
5404
+ function PieChart({
5405
+ data,
5406
+ width,
5407
+ height,
5408
+ innerRadius = 0,
5409
+ showLabels = true
5410
+ }) {
5411
+ const slices = preparePieSlices(data);
5412
+ if (slices.length === 0) {
5413
+ return /* @__PURE__ */ jsx49("div", { className: root8, style: { width, height }, children: /* @__PURE__ */ jsx49("div", { className: emptyState7, style: { width, height }, children: "No data" }) });
5414
+ }
5415
+ const outerRadius = Math.max(0, Math.min(width, height) / 2 - OUTER_PADDING);
5416
+ const pieInnerRadius = outerRadius * innerRadius;
5417
+ return /* @__PURE__ */ jsx49("div", { className: root8, children: /* @__PURE__ */ jsx49("svg", { width, height, role: "img", "aria-label": "Pie chart", children: /* @__PURE__ */ jsx49(Group5, { top: height / 2, left: width / 2, children: /* @__PURE__ */ jsx49(
5418
+ Pie,
5419
+ {
5420
+ data: slices,
5421
+ pieValue: (s) => s.value,
5422
+ pieSort: null,
5423
+ outerRadius,
5424
+ innerRadius: pieInnerRadius,
5425
+ children: (pie) => pie.arcs.map((arc) => {
5426
+ const [labelX, labelY] = pie.path.centroid(arc);
5427
+ const showLabel = showLabels && isLabelFittable(arc.startAngle, arc.endAngle, outerRadius);
5428
+ return /* @__PURE__ */ jsxs32("g", { children: [
5429
+ /* @__PURE__ */ jsx49("path", { d: pie.path(arc) ?? "", fill: arc.data.color }),
5430
+ showLabel ? /* @__PURE__ */ jsx49(
5431
+ "text",
5432
+ {
5433
+ x: labelX,
5434
+ y: labelY,
5435
+ textAnchor: "middle",
5436
+ dominantBaseline: "middle",
5437
+ fill: vars10.color.textInverse,
5438
+ fontSize: vars10.font.sizeXs,
5439
+ fontFamily: vars10.font.body,
5440
+ children: `${Math.round(arc.data.percentage)}%`
5441
+ }
5442
+ ) : null
5443
+ ] }, arc.data.key);
5444
+ })
5445
+ }
5446
+ ) }) }) });
5447
+ }
5448
+
5449
+ // src/components/charts/PieChart/PieChart.interactive.tsx
5450
+ import { useMemo as useMemo9, useState as useState20 } from "react";
5451
+ import { Group as Group6 } from "@visx/group";
5452
+ import { ParentSize as ParentSize4 } from "@visx/responsive";
5453
+ import { Pie as Pie2 } from "@visx/shape";
5454
+ import { TooltipWithBounds as TooltipWithBounds4, useTooltip as useTooltip4 } from "@visx/tooltip";
5455
+ import { vars as vars11 } from "@vesture/tokens";
5456
+ import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
5457
+ var OUTER_PADDING2 = 8;
5458
+ var HOVER_OFFSET_PX = 8;
5459
+ function InteractivePieChart({
5460
+ data,
5461
+ innerRadius = 0,
5462
+ showLabels = true,
5463
+ height = 320
5464
+ }) {
5465
+ const [hiddenKeys, setHiddenKeys] = useState20(/* @__PURE__ */ new Set());
5466
+ const [hoveredKey, setHoveredKey] = useState20(null);
5467
+ const coloredSlices = useMemo9(() => colorSlices(data), [data]);
5468
+ const visibleSlices = useMemo9(
5469
+ () => coloredSlices.filter((s) => s.value > 0 && !hiddenKeys.has(s.key)),
5470
+ [coloredSlices, hiddenKeys]
5471
+ );
5472
+ const slices = useMemo9(() => computePercentages(visibleSlices), [visibleSlices]);
5473
+ const percentageByKey = useMemo9(() => new Map(slices.map((s) => [s.key, s.percentage])), [slices]);
5474
+ const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip4();
5475
+ function toggleSlice(key) {
5476
+ setHiddenKeys((prev) => {
5477
+ const next = new Set(prev);
5478
+ if (next.has(key)) {
5479
+ next.delete(key);
5480
+ } else {
5481
+ next.add(key);
5482
+ }
5483
+ return next;
5484
+ });
5485
+ }
5486
+ if (slices.length === 0) {
5487
+ return /* @__PURE__ */ jsx50("div", { className: root8, style: { height }, children: /* @__PURE__ */ jsx50("div", { className: emptyState7, style: { height }, children: "No data" }) });
5488
+ }
5489
+ return /* @__PURE__ */ jsxs33("div", { className: root8, children: [
5490
+ /* @__PURE__ */ jsx50(ParentSize4, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
5491
+ if (width === 0) return null;
5492
+ const outerRadius = Math.max(0, Math.min(width, height) / 2 - OUTER_PADDING2);
5493
+ const pieInnerRadius = outerRadius * innerRadius;
5494
+ function handleSliceHover(datum, centroidX, centroidY) {
5495
+ showTooltip({
5496
+ tooltipData: datum,
5497
+ tooltipLeft: width / 2 + centroidX,
5498
+ tooltipTop: height / 2 + centroidY
5499
+ });
5500
+ setHoveredKey(datum.key);
5501
+ }
5502
+ function handleSliceLeave() {
5503
+ hideTooltip();
5504
+ setHoveredKey(null);
5505
+ }
5506
+ return /* @__PURE__ */ jsxs33("div", { style: { position: "relative", width, height }, children: [
5507
+ /* @__PURE__ */ jsx50("svg", { width, height, role: "img", "aria-label": "Pie chart", children: /* @__PURE__ */ jsx50(Group6, { top: height / 2, left: width / 2, children: /* @__PURE__ */ jsx50(
5508
+ Pie2,
5509
+ {
5510
+ data: slices,
5511
+ pieValue: (s) => s.value,
5512
+ pieSort: null,
5513
+ outerRadius,
5514
+ innerRadius: pieInnerRadius,
5515
+ children: (pie) => pie.arcs.map((arc) => {
5516
+ const [centroidX, centroidY] = pie.path.centroid(arc);
5517
+ const showLabel = showLabels && isLabelFittable(arc.startAngle, arc.endAngle, outerRadius);
5518
+ const isHovered = hoveredKey === arc.data.key;
5519
+ const [dx, dy] = arcBisectorDirection(arc.startAngle, arc.endAngle);
5520
+ const transform = isHovered ? `translate(${dx * HOVER_OFFSET_PX}px, ${dy * HOVER_OFFSET_PX}px)` : void 0;
5521
+ return /* @__PURE__ */ jsxs33("g", { className: sliceGroup, style: { transform }, children: [
5522
+ /* @__PURE__ */ jsx50(
5523
+ "path",
5524
+ {
5525
+ d: pie.path(arc) ?? "",
5526
+ fill: arc.data.color,
5527
+ "data-testid": `pie-slice-${arc.data.key}`,
5528
+ onMouseEnter: () => handleSliceHover(arc.data, centroidX, centroidY),
5529
+ onMouseLeave: handleSliceLeave
5530
+ }
5531
+ ),
5532
+ showLabel ? /* @__PURE__ */ jsx50(
5533
+ "text",
5534
+ {
5535
+ x: centroidX,
5536
+ y: centroidY,
5537
+ textAnchor: "middle",
5538
+ dominantBaseline: "middle",
5539
+ fill: vars11.color.textInverse,
5540
+ fontSize: vars11.font.sizeXs,
5541
+ fontFamily: vars11.font.body,
5542
+ style: { pointerEvents: "none" },
5543
+ children: `${Math.round(arc.data.percentage)}%`
5544
+ }
5545
+ ) : null
5546
+ ] }, arc.data.key);
5547
+ })
5548
+ }
5549
+ ) }) }),
5550
+ tooltipOpen && tooltipData ? /* @__PURE__ */ jsx50(TooltipWithBounds4, { left: tooltipLeft, top: tooltipTop, className: tooltip5, children: /* @__PURE__ */ jsxs33("div", { className: tooltipRow4, children: [
5551
+ /* @__PURE__ */ jsx50("span", { className: tooltipSwatch4, style: { background: tooltipData.color } }),
5552
+ /* @__PURE__ */ jsxs33("span", { children: [
5553
+ tooltipData.label,
5554
+ ": ",
5555
+ tooltipData.value,
5556
+ " (",
5557
+ Math.round(tooltipData.percentage),
5558
+ "%)"
5559
+ ] })
5560
+ ] }) }) : null
5561
+ ] });
5562
+ } }),
5563
+ /* @__PURE__ */ jsx50("div", { className: legend4, children: coloredSlices.filter((s) => s.value > 0).map((s) => {
5564
+ const hidden = hiddenKeys.has(s.key);
5565
+ const percentage = percentageByKey.get(s.key);
5566
+ return /* @__PURE__ */ jsxs33(
5567
+ "button",
5568
+ {
5569
+ type: "button",
5570
+ className: [legendItem4, hidden ? legendItemHidden4 : null].filter(Boolean).join(" "),
5571
+ onClick: () => toggleSlice(s.key),
5572
+ "aria-pressed": !hidden,
5573
+ children: [
5574
+ /* @__PURE__ */ jsx50("span", { className: legendSwatch4, style: { background: s.color } }),
5575
+ s.label,
5576
+ !hidden && percentage !== void 0 ? /* @__PURE__ */ jsxs33("span", { className: legendPercentage, children: [
5577
+ Math.round(percentage),
5578
+ "%"
5579
+ ] }) : null
5580
+ ]
5581
+ },
5582
+ s.key
5583
+ );
5584
+ }) })
5585
+ ] });
5586
+ }
5587
+
3938
5588
  // src/index.ts
3939
- import { vars as vars3, defaultThemeClass, defaultThemeVars } from "@vesture/tokens";
5589
+ import { vars as vars12, defaultThemeClass, defaultThemeVars } from "@vesture/tokens";
3940
5590
  export {
3941
5591
  Accordion2 as Accordion,
3942
5592
  AccordionContent,
3943
5593
  AccordionItem,
3944
5594
  AccordionTrigger,
3945
5595
  Alert,
5596
+ AreaChart,
3946
5597
  Avatar,
3947
5598
  Badge,
5599
+ BarChart,
3948
5600
  Breadcrumbs2 as Breadcrumbs,
3949
5601
  BreadcrumbsItem,
3950
5602
  Button,
@@ -3952,6 +5604,7 @@ export {
3952
5604
  Card,
3953
5605
  Checkbox,
3954
5606
  Combobox,
5607
+ CommandPalette,
3955
5608
  DataGrid,
3956
5609
  DatePicker,
3957
5610
  DateRangePicker,
@@ -3959,10 +5612,16 @@ export {
3959
5612
  DropdownMenu2 as DropdownMenu,
3960
5613
  DropdownMenuItem,
3961
5614
  Input,
5615
+ InteractiveAreaChart,
5616
+ InteractiveBarChart,
5617
+ InteractiveLineChart,
5618
+ InteractivePieChart,
3962
5619
  Label,
5620
+ LineChart,
3963
5621
  Modal,
3964
5622
  NumberInput,
3965
5623
  Pagination,
5624
+ PieChart,
3966
5625
  Popover,
3967
5626
  Progress,
3968
5627
  Radio,
@@ -3981,7 +5640,8 @@ export {
3981
5640
  TreeView,
3982
5641
  defaultThemeClass,
3983
5642
  defaultThemeVars,
5643
+ useCommandPaletteShortcut,
3984
5644
  useToast,
3985
- vars3 as vars
5645
+ vars12 as vars
3986
5646
  };
3987
5647
  //# sourceMappingURL=index.js.map