@vesture/react 0.2.10 → 0.3.1
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.css +403 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +234 -1
- package/dist/index.js +2022 -8
- package/dist/index.js.map +1 -1
- package/package.json +8 -1
package/dist/index.js
CHANGED
|
@@ -2001,8 +2001,7 @@ var root2 = "Calendar_root__1uy43my0";
|
|
|
2001
2001
|
var weekRow = "Calendar_weekRow__1uy43my5";
|
|
2002
2002
|
var weekdayCell = "Calendar_weekdayCell__1uy43my6";
|
|
2003
2003
|
|
|
2004
|
-
// src/
|
|
2005
|
-
import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2004
|
+
// src/utils/date.ts
|
|
2006
2005
|
function startOfMonth(date) {
|
|
2007
2006
|
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
2008
2007
|
}
|
|
@@ -2038,6 +2037,9 @@ function endOfWeek(date, weekStartsOn) {
|
|
|
2038
2037
|
function dateKey(date) {
|
|
2039
2038
|
return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
|
|
2040
2039
|
}
|
|
2040
|
+
|
|
2041
|
+
// src/components/Calendar/Calendar.tsx
|
|
2042
|
+
import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2041
2043
|
function getCalendarWeeks(month, weekStartsOn) {
|
|
2042
2044
|
const gridStart = startOfWeek(startOfMonth(month), weekStartsOn);
|
|
2043
2045
|
const gridEnd = endOfWeek(endOfMonth(month), weekStartsOn);
|
|
@@ -2598,10 +2600,10 @@ function clampToMidnight3(date) {
|
|
|
2598
2600
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
2599
2601
|
}
|
|
2600
2602
|
function compareDates(a, b) {
|
|
2601
|
-
const
|
|
2602
|
-
const
|
|
2603
|
-
if (
|
|
2604
|
-
if (
|
|
2603
|
+
const x2 = clampToMidnight3(a).getTime();
|
|
2604
|
+
const y2 = clampToMidnight3(b).getTime();
|
|
2605
|
+
if (x2 < y2) return -1;
|
|
2606
|
+
if (x2 > y2) return 1;
|
|
2605
2607
|
return 0;
|
|
2606
2608
|
}
|
|
2607
2609
|
function isDisabled2(date, minDate, maxDate, isDateDisabled) {
|
|
@@ -4213,16 +4215,2021 @@ function useCommandPaletteShortcut(onOpenChange, options = {}) {
|
|
|
4213
4215
|
}, [onOpenChange, key, metaKey, ctrlKey]);
|
|
4214
4216
|
}
|
|
4215
4217
|
|
|
4218
|
+
// src/components/charts/LineChart/LineChart.tsx
|
|
4219
|
+
import { AxisBottom, AxisLeft } from "@visx/axis";
|
|
4220
|
+
import { GridRows } from "@visx/grid";
|
|
4221
|
+
import { Group } from "@visx/group";
|
|
4222
|
+
import { LinePath } from "@visx/shape";
|
|
4223
|
+
import { vars as vars4 } from "@vesture/tokens";
|
|
4224
|
+
|
|
4225
|
+
// src/components/charts/LineChart/LineChart.render.ts
|
|
4226
|
+
import { scaleBand, scaleLinear, scaleTime } from "@visx/scale";
|
|
4227
|
+
|
|
4228
|
+
// ../../node_modules/d3-shape/src/constant.js
|
|
4229
|
+
function constant_default(x2) {
|
|
4230
|
+
return function constant() {
|
|
4231
|
+
return x2;
|
|
4232
|
+
};
|
|
4233
|
+
}
|
|
4234
|
+
|
|
4235
|
+
// ../../node_modules/d3-path/src/path.js
|
|
4236
|
+
var pi = Math.PI;
|
|
4237
|
+
var tau = 2 * pi;
|
|
4238
|
+
var epsilon = 1e-6;
|
|
4239
|
+
var tauEpsilon = tau - epsilon;
|
|
4240
|
+
function append(strings) {
|
|
4241
|
+
this._ += strings[0];
|
|
4242
|
+
for (let i = 1, n = strings.length; i < n; ++i) {
|
|
4243
|
+
this._ += arguments[i] + strings[i];
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
function appendRound(digits) {
|
|
4247
|
+
let d = Math.floor(digits);
|
|
4248
|
+
if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);
|
|
4249
|
+
if (d > 15) return append;
|
|
4250
|
+
const k = 10 ** d;
|
|
4251
|
+
return function(strings) {
|
|
4252
|
+
this._ += strings[0];
|
|
4253
|
+
for (let i = 1, n = strings.length; i < n; ++i) {
|
|
4254
|
+
this._ += Math.round(arguments[i] * k) / k + strings[i];
|
|
4255
|
+
}
|
|
4256
|
+
};
|
|
4257
|
+
}
|
|
4258
|
+
var Path = class {
|
|
4259
|
+
constructor(digits) {
|
|
4260
|
+
this._x0 = this._y0 = // start of current subpath
|
|
4261
|
+
this._x1 = this._y1 = null;
|
|
4262
|
+
this._ = "";
|
|
4263
|
+
this._append = digits == null ? append : appendRound(digits);
|
|
4264
|
+
}
|
|
4265
|
+
moveTo(x2, y2) {
|
|
4266
|
+
this._append`M${this._x0 = this._x1 = +x2},${this._y0 = this._y1 = +y2}`;
|
|
4267
|
+
}
|
|
4268
|
+
closePath() {
|
|
4269
|
+
if (this._x1 !== null) {
|
|
4270
|
+
this._x1 = this._x0, this._y1 = this._y0;
|
|
4271
|
+
this._append`Z`;
|
|
4272
|
+
}
|
|
4273
|
+
}
|
|
4274
|
+
lineTo(x2, y2) {
|
|
4275
|
+
this._append`L${this._x1 = +x2},${this._y1 = +y2}`;
|
|
4276
|
+
}
|
|
4277
|
+
quadraticCurveTo(x1, y1, x2, y2) {
|
|
4278
|
+
this._append`Q${+x1},${+y1},${this._x1 = +x2},${this._y1 = +y2}`;
|
|
4279
|
+
}
|
|
4280
|
+
bezierCurveTo(x1, y1, x2, y2, x3, y3) {
|
|
4281
|
+
this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x3},${this._y1 = +y3}`;
|
|
4282
|
+
}
|
|
4283
|
+
arcTo(x1, y1, x2, y2, r) {
|
|
4284
|
+
x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
|
|
4285
|
+
if (r < 0) throw new Error(`negative radius: ${r}`);
|
|
4286
|
+
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;
|
|
4287
|
+
if (this._x1 === null) {
|
|
4288
|
+
this._append`M${this._x1 = x1},${this._y1 = y1}`;
|
|
4289
|
+
} else if (!(l01_2 > epsilon)) ;
|
|
4290
|
+
else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
|
|
4291
|
+
this._append`L${this._x1 = x1},${this._y1 = y1}`;
|
|
4292
|
+
} else {
|
|
4293
|
+
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;
|
|
4294
|
+
if (Math.abs(t01 - 1) > epsilon) {
|
|
4295
|
+
this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;
|
|
4296
|
+
}
|
|
4297
|
+
this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
arc(x2, y2, r, a0, a1, ccw) {
|
|
4301
|
+
x2 = +x2, y2 = +y2, r = +r, ccw = !!ccw;
|
|
4302
|
+
if (r < 0) throw new Error(`negative radius: ${r}`);
|
|
4303
|
+
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;
|
|
4304
|
+
if (this._x1 === null) {
|
|
4305
|
+
this._append`M${x0},${y0}`;
|
|
4306
|
+
} else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
|
|
4307
|
+
this._append`L${x0},${y0}`;
|
|
4308
|
+
}
|
|
4309
|
+
if (!r) return;
|
|
4310
|
+
if (da < 0) da = da % tau + tau;
|
|
4311
|
+
if (da > tauEpsilon) {
|
|
4312
|
+
this._append`A${r},${r},0,1,${cw},${x2 - dx},${y2 - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;
|
|
4313
|
+
} else if (da > epsilon) {
|
|
4314
|
+
this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x2 + r * Math.cos(a1)},${this._y1 = y2 + r * Math.sin(a1)}`;
|
|
4315
|
+
}
|
|
4316
|
+
}
|
|
4317
|
+
rect(x2, y2, w, h) {
|
|
4318
|
+
this._append`M${this._x0 = this._x1 = +x2},${this._y0 = this._y1 = +y2}h${w = +w}v${+h}h${-w}Z`;
|
|
4319
|
+
}
|
|
4320
|
+
toString() {
|
|
4321
|
+
return this._;
|
|
4322
|
+
}
|
|
4323
|
+
};
|
|
4324
|
+
function path() {
|
|
4325
|
+
return new Path();
|
|
4326
|
+
}
|
|
4327
|
+
path.prototype = Path.prototype;
|
|
4328
|
+
|
|
4329
|
+
// ../../node_modules/d3-shape/src/path.js
|
|
4330
|
+
function withPath(shape) {
|
|
4331
|
+
let digits = 3;
|
|
4332
|
+
shape.digits = function(_) {
|
|
4333
|
+
if (!arguments.length) return digits;
|
|
4334
|
+
if (_ == null) {
|
|
4335
|
+
digits = null;
|
|
4336
|
+
} else {
|
|
4337
|
+
const d = Math.floor(_);
|
|
4338
|
+
if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
|
|
4339
|
+
digits = d;
|
|
4340
|
+
}
|
|
4341
|
+
return shape;
|
|
4342
|
+
};
|
|
4343
|
+
return () => new Path(digits);
|
|
4344
|
+
}
|
|
4345
|
+
|
|
4346
|
+
// ../../node_modules/d3-shape/src/array.js
|
|
4347
|
+
var slice = Array.prototype.slice;
|
|
4348
|
+
function array_default(x2) {
|
|
4349
|
+
return typeof x2 === "object" && "length" in x2 ? x2 : Array.from(x2);
|
|
4350
|
+
}
|
|
4351
|
+
|
|
4352
|
+
// ../../node_modules/d3-shape/src/curve/linear.js
|
|
4353
|
+
function Linear(context) {
|
|
4354
|
+
this._context = context;
|
|
4355
|
+
}
|
|
4356
|
+
Linear.prototype = {
|
|
4357
|
+
areaStart: function() {
|
|
4358
|
+
this._line = 0;
|
|
4359
|
+
},
|
|
4360
|
+
areaEnd: function() {
|
|
4361
|
+
this._line = NaN;
|
|
4362
|
+
},
|
|
4363
|
+
lineStart: function() {
|
|
4364
|
+
this._point = 0;
|
|
4365
|
+
},
|
|
4366
|
+
lineEnd: function() {
|
|
4367
|
+
if (this._line || this._line !== 0 && this._point === 1) this._context.closePath();
|
|
4368
|
+
this._line = 1 - this._line;
|
|
4369
|
+
},
|
|
4370
|
+
point: function(x2, y2) {
|
|
4371
|
+
x2 = +x2, y2 = +y2;
|
|
4372
|
+
switch (this._point) {
|
|
4373
|
+
case 0:
|
|
4374
|
+
this._point = 1;
|
|
4375
|
+
this._line ? this._context.lineTo(x2, y2) : this._context.moveTo(x2, y2);
|
|
4376
|
+
break;
|
|
4377
|
+
case 1:
|
|
4378
|
+
this._point = 2;
|
|
4379
|
+
// falls through
|
|
4380
|
+
default:
|
|
4381
|
+
this._context.lineTo(x2, y2);
|
|
4382
|
+
break;
|
|
4383
|
+
}
|
|
4384
|
+
}
|
|
4385
|
+
};
|
|
4386
|
+
function linear_default(context) {
|
|
4387
|
+
return new Linear(context);
|
|
4388
|
+
}
|
|
4389
|
+
|
|
4390
|
+
// ../../node_modules/d3-shape/src/point.js
|
|
4391
|
+
function x(p) {
|
|
4392
|
+
return p[0];
|
|
4393
|
+
}
|
|
4394
|
+
function y(p) {
|
|
4395
|
+
return p[1];
|
|
4396
|
+
}
|
|
4397
|
+
|
|
4398
|
+
// ../../node_modules/d3-shape/src/line.js
|
|
4399
|
+
function line_default(x2, y2) {
|
|
4400
|
+
var defined = constant_default(true), context = null, curve = linear_default, output = null, path2 = withPath(line);
|
|
4401
|
+
x2 = typeof x2 === "function" ? x2 : x2 === void 0 ? x : constant_default(x2);
|
|
4402
|
+
y2 = typeof y2 === "function" ? y2 : y2 === void 0 ? y : constant_default(y2);
|
|
4403
|
+
function line(data) {
|
|
4404
|
+
var i, n = (data = array_default(data)).length, d, defined0 = false, buffer;
|
|
4405
|
+
if (context == null) output = curve(buffer = path2());
|
|
4406
|
+
for (i = 0; i <= n; ++i) {
|
|
4407
|
+
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
|
|
4408
|
+
if (defined0 = !defined0) output.lineStart();
|
|
4409
|
+
else output.lineEnd();
|
|
4410
|
+
}
|
|
4411
|
+
if (defined0) output.point(+x2(d, i, data), +y2(d, i, data));
|
|
4412
|
+
}
|
|
4413
|
+
if (buffer) return output = null, buffer + "" || null;
|
|
4414
|
+
}
|
|
4415
|
+
line.x = function(_) {
|
|
4416
|
+
return arguments.length ? (x2 = typeof _ === "function" ? _ : constant_default(+_), line) : x2;
|
|
4417
|
+
};
|
|
4418
|
+
line.y = function(_) {
|
|
4419
|
+
return arguments.length ? (y2 = typeof _ === "function" ? _ : constant_default(+_), line) : y2;
|
|
4420
|
+
};
|
|
4421
|
+
line.defined = function(_) {
|
|
4422
|
+
return arguments.length ? (defined = typeof _ === "function" ? _ : constant_default(!!_), line) : defined;
|
|
4423
|
+
};
|
|
4424
|
+
line.curve = function(_) {
|
|
4425
|
+
return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
|
|
4426
|
+
};
|
|
4427
|
+
line.context = function(_) {
|
|
4428
|
+
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
|
|
4429
|
+
};
|
|
4430
|
+
return line;
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4433
|
+
// ../../node_modules/d3-shape/src/area.js
|
|
4434
|
+
function area_default(x0, y0, y1) {
|
|
4435
|
+
var x1 = null, defined = constant_default(true), context = null, curve = linear_default, output = null, path2 = withPath(area);
|
|
4436
|
+
x0 = typeof x0 === "function" ? x0 : x0 === void 0 ? x : constant_default(+x0);
|
|
4437
|
+
y0 = typeof y0 === "function" ? y0 : y0 === void 0 ? constant_default(0) : constant_default(+y0);
|
|
4438
|
+
y1 = typeof y1 === "function" ? y1 : y1 === void 0 ? y : constant_default(+y1);
|
|
4439
|
+
function area(data) {
|
|
4440
|
+
var i, j, k, n = (data = array_default(data)).length, d, defined0 = false, buffer, x0z = new Array(n), y0z = new Array(n);
|
|
4441
|
+
if (context == null) output = curve(buffer = path2());
|
|
4442
|
+
for (i = 0; i <= n; ++i) {
|
|
4443
|
+
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
|
|
4444
|
+
if (defined0 = !defined0) {
|
|
4445
|
+
j = i;
|
|
4446
|
+
output.areaStart();
|
|
4447
|
+
output.lineStart();
|
|
4448
|
+
} else {
|
|
4449
|
+
output.lineEnd();
|
|
4450
|
+
output.lineStart();
|
|
4451
|
+
for (k = i - 1; k >= j; --k) {
|
|
4452
|
+
output.point(x0z[k], y0z[k]);
|
|
4453
|
+
}
|
|
4454
|
+
output.lineEnd();
|
|
4455
|
+
output.areaEnd();
|
|
4456
|
+
}
|
|
4457
|
+
}
|
|
4458
|
+
if (defined0) {
|
|
4459
|
+
x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
|
|
4460
|
+
output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
if (buffer) return output = null, buffer + "" || null;
|
|
4464
|
+
}
|
|
4465
|
+
function arealine() {
|
|
4466
|
+
return line_default().defined(defined).curve(curve).context(context);
|
|
4467
|
+
}
|
|
4468
|
+
area.x = function(_) {
|
|
4469
|
+
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant_default(+_), x1 = null, area) : x0;
|
|
4470
|
+
};
|
|
4471
|
+
area.x0 = function(_) {
|
|
4472
|
+
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant_default(+_), area) : x0;
|
|
4473
|
+
};
|
|
4474
|
+
area.x1 = function(_) {
|
|
4475
|
+
return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant_default(+_), area) : x1;
|
|
4476
|
+
};
|
|
4477
|
+
area.y = function(_) {
|
|
4478
|
+
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant_default(+_), y1 = null, area) : y0;
|
|
4479
|
+
};
|
|
4480
|
+
area.y0 = function(_) {
|
|
4481
|
+
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant_default(+_), area) : y0;
|
|
4482
|
+
};
|
|
4483
|
+
area.y1 = function(_) {
|
|
4484
|
+
return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant_default(+_), area) : y1;
|
|
4485
|
+
};
|
|
4486
|
+
area.lineX0 = area.lineY0 = function() {
|
|
4487
|
+
return arealine().x(x0).y(y0);
|
|
4488
|
+
};
|
|
4489
|
+
area.lineY1 = function() {
|
|
4490
|
+
return arealine().x(x0).y(y1);
|
|
4491
|
+
};
|
|
4492
|
+
area.lineX1 = function() {
|
|
4493
|
+
return arealine().x(x1).y(y0);
|
|
4494
|
+
};
|
|
4495
|
+
area.defined = function(_) {
|
|
4496
|
+
return arguments.length ? (defined = typeof _ === "function" ? _ : constant_default(!!_), area) : defined;
|
|
4497
|
+
};
|
|
4498
|
+
area.curve = function(_) {
|
|
4499
|
+
return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
|
|
4500
|
+
};
|
|
4501
|
+
area.context = function(_) {
|
|
4502
|
+
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
|
|
4503
|
+
};
|
|
4504
|
+
return area;
|
|
4505
|
+
}
|
|
4506
|
+
|
|
4507
|
+
// src/components/charts/LineChart/LineChart.render.ts
|
|
4508
|
+
import { vars as vars3 } from "@vesture/tokens";
|
|
4509
|
+
var DEFAULT_MARGIN = { top: 16, right: 16, bottom: 32, left: 48 };
|
|
4510
|
+
var SERIES_COLOR_CYCLE = [
|
|
4511
|
+
vars3.chart.series1,
|
|
4512
|
+
vars3.chart.series2,
|
|
4513
|
+
vars3.chart.series3,
|
|
4514
|
+
vars3.chart.series4,
|
|
4515
|
+
vars3.chart.series5,
|
|
4516
|
+
vars3.chart.series6,
|
|
4517
|
+
vars3.chart.series7,
|
|
4518
|
+
vars3.chart.series8
|
|
4519
|
+
];
|
|
4520
|
+
function getSeriesColor(series, index) {
|
|
4521
|
+
return series.color ?? SERIES_COLOR_CYCLE[index % SERIES_COLOR_CYCLE.length];
|
|
4522
|
+
}
|
|
4523
|
+
function resolveMargin(margin) {
|
|
4524
|
+
return { ...DEFAULT_MARGIN, ...margin };
|
|
4525
|
+
}
|
|
4526
|
+
function inferXScaleType(data) {
|
|
4527
|
+
const first = data[0]?.x;
|
|
4528
|
+
if (first instanceof Date) return "time";
|
|
4529
|
+
if (typeof first === "number") return "linear";
|
|
4530
|
+
return "band";
|
|
4531
|
+
}
|
|
4532
|
+
function numericValue(value) {
|
|
4533
|
+
if (value === void 0) return void 0;
|
|
4534
|
+
const n = value instanceof Date ? value.getTime() : Number(value);
|
|
4535
|
+
return Number.isFinite(n) ? n : void 0;
|
|
4536
|
+
}
|
|
4537
|
+
function buildScales(data, series, width, height, margin, xScaleType, stacked = false) {
|
|
4538
|
+
const innerWidth = Math.max(0, width - margin.left - margin.right);
|
|
4539
|
+
const innerHeight = Math.max(0, height - margin.top - margin.bottom);
|
|
4540
|
+
let xScale;
|
|
4541
|
+
if (xScaleType === "time") {
|
|
4542
|
+
const xValues = data.map((d) => new Date(d.x).getTime());
|
|
4543
|
+
xScale = scaleTime({
|
|
4544
|
+
domain: [Math.min(...xValues), Math.max(...xValues)],
|
|
4545
|
+
range: [0, innerWidth]
|
|
4546
|
+
});
|
|
4547
|
+
} else if (xScaleType === "linear") {
|
|
4548
|
+
const xValues = data.map((d) => Number(d.x));
|
|
4549
|
+
xScale = scaleLinear({
|
|
4550
|
+
domain: [Math.min(...xValues), Math.max(...xValues)],
|
|
4551
|
+
range: [0, innerWidth]
|
|
4552
|
+
});
|
|
4553
|
+
} else {
|
|
4554
|
+
xScale = scaleBand({
|
|
4555
|
+
domain: data.map((d) => String(d.x)),
|
|
4556
|
+
range: [0, innerWidth],
|
|
4557
|
+
padding: 0.2
|
|
4558
|
+
});
|
|
4559
|
+
}
|
|
4560
|
+
const yValues = stacked ? data.map((d) => series.reduce((sum, s) => sum + (numericValue(d[s.key]) ?? 0), 0)) : data.flatMap(
|
|
4561
|
+
(d) => series.map((s) => numericValue(d[s.key])).filter((v) => v !== void 0)
|
|
4562
|
+
);
|
|
4563
|
+
const yMin = stacked ? 0 : yValues.length > 0 ? Math.min(0, ...yValues) : 0;
|
|
4564
|
+
const yMax = yValues.length > 0 ? Math.max(...yValues) : 1;
|
|
4565
|
+
const yScale = scaleLinear({
|
|
4566
|
+
domain: [yMin, yMax],
|
|
4567
|
+
range: [innerHeight, 0],
|
|
4568
|
+
nice: true
|
|
4569
|
+
});
|
|
4570
|
+
return { xScale, yScale, xScaleType, innerWidth, innerHeight, margin };
|
|
4571
|
+
}
|
|
4572
|
+
function getXPixel(scales, x2) {
|
|
4573
|
+
const { xScale, xScaleType } = scales;
|
|
4574
|
+
if (xScaleType === "band") {
|
|
4575
|
+
const pos = xScale(String(x2));
|
|
4576
|
+
if (pos === void 0) return void 0;
|
|
4577
|
+
return pos + xScale.bandwidth() / 2;
|
|
4578
|
+
}
|
|
4579
|
+
if (xScaleType === "time") {
|
|
4580
|
+
return xScale(new Date(x2));
|
|
4581
|
+
}
|
|
4582
|
+
return xScale(Number(x2));
|
|
4583
|
+
}
|
|
4584
|
+
function getYPixel(scales, value) {
|
|
4585
|
+
const n = numericValue(value);
|
|
4586
|
+
if (n === void 0) return void 0;
|
|
4587
|
+
return scales.yScale(n);
|
|
4588
|
+
}
|
|
4589
|
+
var pathGenerator = line_default().x((p) => p.x).y((p) => p.y);
|
|
4590
|
+
function buildLineChartLayout(data, series, width, height, margin, xScaleType) {
|
|
4591
|
+
const resolvedMargin = resolveMargin(margin);
|
|
4592
|
+
const resolvedXScaleType = xScaleType ?? inferXScaleType(data);
|
|
4593
|
+
const scales = buildScales(data, series, width, height, resolvedMargin, resolvedXScaleType);
|
|
4594
|
+
const seriesLayouts = series.map((s, index) => {
|
|
4595
|
+
const points = [];
|
|
4596
|
+
data.forEach((d, dataIndex) => {
|
|
4597
|
+
const x2 = getXPixel(scales, d.x);
|
|
4598
|
+
const y2 = getYPixel(scales, d[s.key]);
|
|
4599
|
+
if (x2 !== void 0 && y2 !== void 0) {
|
|
4600
|
+
points.push({ dataIndex, x: x2, y: y2 });
|
|
4601
|
+
}
|
|
4602
|
+
});
|
|
4603
|
+
return {
|
|
4604
|
+
key: s.key,
|
|
4605
|
+
label: s.label,
|
|
4606
|
+
color: getSeriesColor(s, index),
|
|
4607
|
+
points,
|
|
4608
|
+
path: points.length >= 2 ? pathGenerator(points) ?? "" : ""
|
|
4609
|
+
};
|
|
4610
|
+
});
|
|
4611
|
+
return { scales, seriesLayouts };
|
|
4612
|
+
}
|
|
4613
|
+
function findNearestDataIndex(data, scales, pixelX) {
|
|
4614
|
+
if (data.length === 0) return null;
|
|
4615
|
+
let nearestIndex = 0;
|
|
4616
|
+
let nearestDistance = Infinity;
|
|
4617
|
+
data.forEach((d, index) => {
|
|
4618
|
+
const x2 = getXPixel(scales, d.x);
|
|
4619
|
+
if (x2 === void 0) return;
|
|
4620
|
+
const distance = Math.abs(x2 - pixelX);
|
|
4621
|
+
if (distance < nearestDistance) {
|
|
4622
|
+
nearestDistance = distance;
|
|
4623
|
+
nearestIndex = index;
|
|
4624
|
+
}
|
|
4625
|
+
});
|
|
4626
|
+
return nearestDistance === Infinity ? null : nearestIndex;
|
|
4627
|
+
}
|
|
4628
|
+
|
|
4629
|
+
// src/components/charts/LineChart/LineChart.css.ts
|
|
4630
|
+
var emptyState4 = "chartSurfaces_emptyState__n6njm11";
|
|
4631
|
+
var legend = "chartSurfaces_legend__n6njm15";
|
|
4632
|
+
var legendItem = "chartSurfaces_legendItem__n6njm16";
|
|
4633
|
+
var legendItemHidden = "chartSurfaces_legendItemHidden__n6njm17";
|
|
4634
|
+
var legendSwatch = "chartSurfaces_legendSwatch__n6njm18";
|
|
4635
|
+
var overlayRect = "LineChart_overlayRect__1kfw0no0";
|
|
4636
|
+
var root5 = "chartSurfaces_root__n6njm10";
|
|
4637
|
+
var tooltip2 = "chartSurfaces_tooltip__n6njm12";
|
|
4638
|
+
var tooltipRow = "chartSurfaces_tooltipRow__n6njm13";
|
|
4639
|
+
var tooltipSwatch = "chartSurfaces_tooltipSwatch__n6njm14";
|
|
4640
|
+
|
|
4641
|
+
// src/components/charts/LineChart/LineChart.tsx
|
|
4642
|
+
import { jsx as jsx43, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
4643
|
+
function LineChart({
|
|
4644
|
+
data,
|
|
4645
|
+
series,
|
|
4646
|
+
width,
|
|
4647
|
+
height,
|
|
4648
|
+
margin,
|
|
4649
|
+
xScale
|
|
4650
|
+
}) {
|
|
4651
|
+
if (data.length === 0) {
|
|
4652
|
+
return /* @__PURE__ */ jsx43("div", { className: root5, style: { width, height }, children: /* @__PURE__ */ jsx43("div", { className: emptyState4, style: { width, height }, children: "No data" }) });
|
|
4653
|
+
}
|
|
4654
|
+
const { scales, seriesLayouts } = buildLineChartLayout(data, series, width, height, margin, xScale);
|
|
4655
|
+
const { xScale: scaleX, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
|
|
4656
|
+
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: [
|
|
4657
|
+
/* @__PURE__ */ jsx43(GridRows, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars4.chart.grid }),
|
|
4658
|
+
seriesLayouts.map((s) => /* @__PURE__ */ jsx43(
|
|
4659
|
+
LinePath,
|
|
4660
|
+
{
|
|
4661
|
+
data: s.points,
|
|
4662
|
+
x: (p) => p.x,
|
|
4663
|
+
y: (p) => p.y,
|
|
4664
|
+
stroke: s.color,
|
|
4665
|
+
strokeWidth: 2,
|
|
4666
|
+
fill: "none"
|
|
4667
|
+
},
|
|
4668
|
+
s.key
|
|
4669
|
+
)),
|
|
4670
|
+
/* @__PURE__ */ jsx43(
|
|
4671
|
+
AxisBottom,
|
|
4672
|
+
{
|
|
4673
|
+
top: innerHeight,
|
|
4674
|
+
scale: scaleX,
|
|
4675
|
+
stroke: vars4.chart.axis,
|
|
4676
|
+
tickStroke: vars4.chart.axis,
|
|
4677
|
+
tickLabelProps: () => ({ fill: vars4.chart.axis, fontSize: 11, textAnchor: "middle" })
|
|
4678
|
+
}
|
|
4679
|
+
),
|
|
4680
|
+
/* @__PURE__ */ jsx43(
|
|
4681
|
+
AxisLeft,
|
|
4682
|
+
{
|
|
4683
|
+
scale: yScale,
|
|
4684
|
+
stroke: vars4.chart.axis,
|
|
4685
|
+
tickStroke: vars4.chart.axis,
|
|
4686
|
+
tickLabelProps: () => ({ fill: vars4.chart.axis, fontSize: 11, textAnchor: "end", dx: "-0.25em" })
|
|
4687
|
+
}
|
|
4688
|
+
)
|
|
4689
|
+
] }) }) });
|
|
4690
|
+
}
|
|
4691
|
+
|
|
4692
|
+
// src/components/charts/LineChart/LineChart.interactive.tsx
|
|
4693
|
+
import { useMemo as useMemo6, useState as useState17 } from "react";
|
|
4694
|
+
import { ParentSize } from "@visx/responsive";
|
|
4695
|
+
import { TooltipWithBounds, useTooltip } from "@visx/tooltip";
|
|
4696
|
+
import { jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
4697
|
+
function InteractiveLineChart({
|
|
4698
|
+
data,
|
|
4699
|
+
series,
|
|
4700
|
+
margin,
|
|
4701
|
+
xScale,
|
|
4702
|
+
height = 320
|
|
4703
|
+
}) {
|
|
4704
|
+
const [hiddenKeys, setHiddenKeys] = useState17(/* @__PURE__ */ new Set());
|
|
4705
|
+
const coloredSeries = useMemo6(
|
|
4706
|
+
() => series.map((s, index) => ({ ...s, color: s.color ?? getSeriesColor(s, index) })),
|
|
4707
|
+
[series]
|
|
4708
|
+
);
|
|
4709
|
+
const visibleSeries = useMemo6(
|
|
4710
|
+
() => coloredSeries.filter((s) => !hiddenKeys.has(s.key)),
|
|
4711
|
+
[coloredSeries, hiddenKeys]
|
|
4712
|
+
);
|
|
4713
|
+
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip();
|
|
4714
|
+
function toggleSeries(key) {
|
|
4715
|
+
setHiddenKeys((prev) => {
|
|
4716
|
+
const next = new Set(prev);
|
|
4717
|
+
if (next.has(key)) {
|
|
4718
|
+
next.delete(key);
|
|
4719
|
+
} else {
|
|
4720
|
+
next.add(key);
|
|
4721
|
+
}
|
|
4722
|
+
return next;
|
|
4723
|
+
});
|
|
4724
|
+
}
|
|
4725
|
+
return /* @__PURE__ */ jsxs27("div", { className: root5, children: [
|
|
4726
|
+
/* @__PURE__ */ jsx44(ParentSize, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
|
|
4727
|
+
if (width === 0) return null;
|
|
4728
|
+
const { scales } = buildLineChartLayout(data, visibleSeries, width, height, margin, xScale);
|
|
4729
|
+
function handleMouseMove(event) {
|
|
4730
|
+
const bounds = event.currentTarget.getBoundingClientRect();
|
|
4731
|
+
const pixelX = event.clientX - bounds.left;
|
|
4732
|
+
const dataIndex = findNearestDataIndex(data, scales, pixelX);
|
|
4733
|
+
if (dataIndex === null) {
|
|
4734
|
+
hideTooltip();
|
|
4735
|
+
return;
|
|
4736
|
+
}
|
|
4737
|
+
const dataPoint = data[dataIndex];
|
|
4738
|
+
const xPixel = getXPixel(scales, dataPoint.x) ?? pixelX;
|
|
4739
|
+
showTooltip({
|
|
4740
|
+
tooltipData: { dataPoint, visibleSeries },
|
|
4741
|
+
tooltipLeft: scales.margin.left + xPixel,
|
|
4742
|
+
tooltipTop: 0
|
|
4743
|
+
});
|
|
4744
|
+
}
|
|
4745
|
+
return /* @__PURE__ */ jsxs27("div", { style: { position: "relative", width, height }, children: [
|
|
4746
|
+
/* @__PURE__ */ jsx44(
|
|
4747
|
+
LineChart,
|
|
4748
|
+
{
|
|
4749
|
+
data,
|
|
4750
|
+
series: visibleSeries,
|
|
4751
|
+
width,
|
|
4752
|
+
height,
|
|
4753
|
+
margin,
|
|
4754
|
+
xScale
|
|
4755
|
+
}
|
|
4756
|
+
),
|
|
4757
|
+
/* @__PURE__ */ jsx44(
|
|
4758
|
+
"svg",
|
|
4759
|
+
{
|
|
4760
|
+
width,
|
|
4761
|
+
height,
|
|
4762
|
+
style: { position: "absolute", top: 0, left: 0 },
|
|
4763
|
+
"aria-hidden": "true",
|
|
4764
|
+
children: /* @__PURE__ */ jsx44(
|
|
4765
|
+
"rect",
|
|
4766
|
+
{
|
|
4767
|
+
className: overlayRect,
|
|
4768
|
+
"data-testid": "line-chart-overlay",
|
|
4769
|
+
x: scales.margin.left,
|
|
4770
|
+
y: scales.margin.top,
|
|
4771
|
+
width: scales.innerWidth,
|
|
4772
|
+
height: scales.innerHeight,
|
|
4773
|
+
onMouseMove: handleMouseMove,
|
|
4774
|
+
onMouseLeave: () => hideTooltip()
|
|
4775
|
+
}
|
|
4776
|
+
)
|
|
4777
|
+
}
|
|
4778
|
+
),
|
|
4779
|
+
tooltipOpen && tooltipData ? /* @__PURE__ */ jsxs27(TooltipWithBounds, { left: tooltipLeft, top: tooltipTop, className: tooltip2, children: [
|
|
4780
|
+
/* @__PURE__ */ jsx44("div", { children: String(tooltipData.dataPoint.x) }),
|
|
4781
|
+
tooltipData.visibleSeries.map((s) => /* @__PURE__ */ jsxs27("div", { className: tooltipRow, children: [
|
|
4782
|
+
/* @__PURE__ */ jsx44("span", { className: tooltipSwatch, style: { background: s.color } }),
|
|
4783
|
+
/* @__PURE__ */ jsxs27("span", { children: [
|
|
4784
|
+
s.label,
|
|
4785
|
+
": ",
|
|
4786
|
+
String(tooltipData.dataPoint[s.key])
|
|
4787
|
+
] })
|
|
4788
|
+
] }, s.key))
|
|
4789
|
+
] }) : null
|
|
4790
|
+
] });
|
|
4791
|
+
} }),
|
|
4792
|
+
/* @__PURE__ */ jsx44("div", { className: legend, children: coloredSeries.map((s) => {
|
|
4793
|
+
const hidden = hiddenKeys.has(s.key);
|
|
4794
|
+
return /* @__PURE__ */ jsxs27(
|
|
4795
|
+
"button",
|
|
4796
|
+
{
|
|
4797
|
+
type: "button",
|
|
4798
|
+
className: [legendItem, hidden ? legendItemHidden : null].filter(Boolean).join(" "),
|
|
4799
|
+
onClick: () => toggleSeries(s.key),
|
|
4800
|
+
"aria-pressed": !hidden,
|
|
4801
|
+
children: [
|
|
4802
|
+
/* @__PURE__ */ jsx44("span", { className: legendSwatch, style: { background: s.color } }),
|
|
4803
|
+
s.label
|
|
4804
|
+
]
|
|
4805
|
+
},
|
|
4806
|
+
s.key
|
|
4807
|
+
);
|
|
4808
|
+
}) })
|
|
4809
|
+
] });
|
|
4810
|
+
}
|
|
4811
|
+
|
|
4812
|
+
// src/components/charts/BarChart/BarChart.tsx
|
|
4813
|
+
import { AxisBottom as AxisBottom2, AxisLeft as AxisLeft2 } from "@visx/axis";
|
|
4814
|
+
import { GridRows as GridRows2 } from "@visx/grid";
|
|
4815
|
+
import { Group as Group2 } from "@visx/group";
|
|
4816
|
+
import { BarGroup, BarStack } from "@visx/shape";
|
|
4817
|
+
import { vars as vars6 } from "@vesture/tokens";
|
|
4818
|
+
|
|
4819
|
+
// src/components/charts/BarChart/BarChart.render.ts
|
|
4820
|
+
import { scaleBand as scaleBand2, scaleLinear as scaleLinear2 } from "@visx/scale";
|
|
4821
|
+
import { vars as vars5 } from "@vesture/tokens";
|
|
4822
|
+
var DEFAULT_MARGIN2 = { top: 16, right: 16, bottom: 32, left: 48 };
|
|
4823
|
+
var SERIES_COLOR_CYCLE2 = [
|
|
4824
|
+
vars5.chart.series1,
|
|
4825
|
+
vars5.chart.series2,
|
|
4826
|
+
vars5.chart.series3,
|
|
4827
|
+
vars5.chart.series4,
|
|
4828
|
+
vars5.chart.series5,
|
|
4829
|
+
vars5.chart.series6,
|
|
4830
|
+
vars5.chart.series7,
|
|
4831
|
+
vars5.chart.series8
|
|
4832
|
+
];
|
|
4833
|
+
function getSeriesColor2(series, index) {
|
|
4834
|
+
return series.color ?? SERIES_COLOR_CYCLE2[index % SERIES_COLOR_CYCLE2.length];
|
|
4835
|
+
}
|
|
4836
|
+
function buildSeriesColorMap(series) {
|
|
4837
|
+
const map = {};
|
|
4838
|
+
series.forEach((s, index) => {
|
|
4839
|
+
map[s.key] = getSeriesColor2(s, index);
|
|
4840
|
+
});
|
|
4841
|
+
return map;
|
|
4842
|
+
}
|
|
4843
|
+
function resolveMargin2(margin) {
|
|
4844
|
+
return { ...DEFAULT_MARGIN2, ...margin };
|
|
4845
|
+
}
|
|
4846
|
+
function numericValue2(value) {
|
|
4847
|
+
if (value === void 0) return 0;
|
|
4848
|
+
const n = Number(value);
|
|
4849
|
+
return Number.isFinite(n) ? n : 0;
|
|
4850
|
+
}
|
|
4851
|
+
function buildScales2(data, series, width, height, margin, layout) {
|
|
4852
|
+
const innerWidth = Math.max(0, width - margin.left - margin.right);
|
|
4853
|
+
const innerHeight = Math.max(0, height - margin.top - margin.bottom);
|
|
4854
|
+
const x0Scale = scaleBand2({
|
|
4855
|
+
domain: data.map((d) => d.category),
|
|
4856
|
+
range: [0, innerWidth],
|
|
4857
|
+
padding: 0.2
|
|
4858
|
+
});
|
|
4859
|
+
const x1Scale = layout === "grouped" ? scaleBand2({
|
|
4860
|
+
domain: series.map((s) => s.key),
|
|
4861
|
+
range: [0, x0Scale.bandwidth()],
|
|
4862
|
+
padding: 0.1
|
|
4863
|
+
}) : void 0;
|
|
4864
|
+
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]))));
|
|
4865
|
+
const yScale = scaleLinear2({
|
|
4866
|
+
domain: [0, yMax > 0 ? yMax : 1],
|
|
4867
|
+
range: [innerHeight, 0],
|
|
4868
|
+
nice: true
|
|
4869
|
+
});
|
|
4870
|
+
return { x0Scale, x1Scale, xScale: x0Scale, yScale, layout, innerWidth, innerHeight, margin };
|
|
4871
|
+
}
|
|
4872
|
+
function buildBarChartLayout(data, series, width, height, margin, layout = "grouped") {
|
|
4873
|
+
const resolvedMargin = resolveMargin2(margin);
|
|
4874
|
+
const scales = buildScales2(data, series, width, height, resolvedMargin, layout);
|
|
4875
|
+
const colorMap = buildSeriesColorMap(series);
|
|
4876
|
+
return { scales, colorMap };
|
|
4877
|
+
}
|
|
4878
|
+
|
|
4879
|
+
// src/components/charts/BarChart/BarChart.css.ts
|
|
4880
|
+
var emptyState5 = "chartSurfaces_emptyState__n6njm11";
|
|
4881
|
+
var legend2 = "chartSurfaces_legend__n6njm15";
|
|
4882
|
+
var legendItem2 = "chartSurfaces_legendItem__n6njm16";
|
|
4883
|
+
var legendItemHidden2 = "chartSurfaces_legendItemHidden__n6njm17";
|
|
4884
|
+
var legendSwatch2 = "chartSurfaces_legendSwatch__n6njm18";
|
|
4885
|
+
var root6 = "chartSurfaces_root__n6njm10";
|
|
4886
|
+
var tooltip3 = "chartSurfaces_tooltip__n6njm12";
|
|
4887
|
+
var tooltipRow2 = "chartSurfaces_tooltipRow__n6njm13";
|
|
4888
|
+
var tooltipSwatch2 = "chartSurfaces_tooltipSwatch__n6njm14";
|
|
4889
|
+
|
|
4890
|
+
// src/components/charts/BarChart/BarChart.tsx
|
|
4891
|
+
import { jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
4892
|
+
function BarChart({
|
|
4893
|
+
data,
|
|
4894
|
+
series,
|
|
4895
|
+
width,
|
|
4896
|
+
height,
|
|
4897
|
+
margin,
|
|
4898
|
+
layout = "grouped"
|
|
4899
|
+
}) {
|
|
4900
|
+
if (data.length === 0) {
|
|
4901
|
+
return /* @__PURE__ */ jsx45("div", { className: root6, style: { width, height }, children: /* @__PURE__ */ jsx45("div", { className: emptyState5, style: { width, height }, children: "No data" }) });
|
|
4902
|
+
}
|
|
4903
|
+
const { scales, colorMap } = buildBarChartLayout(data, series, width, height, margin, layout);
|
|
4904
|
+
const { x0Scale, x1Scale, xScale, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
|
|
4905
|
+
const keys = series.map((s) => s.key);
|
|
4906
|
+
const color = (key, index) => colorMap[key] ?? SERIES_COLOR_CYCLE2[index % 8];
|
|
4907
|
+
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: [
|
|
4908
|
+
/* @__PURE__ */ jsx45(GridRows2, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars6.chart.grid }),
|
|
4909
|
+
layout === "stacked" ? /* @__PURE__ */ jsx45(BarStack, { data, keys, x: (d) => d.category, xScale, yScale, color }) : /* @__PURE__ */ jsx45(
|
|
4910
|
+
BarGroup,
|
|
4911
|
+
{
|
|
4912
|
+
data,
|
|
4913
|
+
keys,
|
|
4914
|
+
height: innerHeight,
|
|
4915
|
+
x0: (d) => d.category,
|
|
4916
|
+
x0Scale,
|
|
4917
|
+
x1Scale,
|
|
4918
|
+
yScale,
|
|
4919
|
+
color
|
|
4920
|
+
}
|
|
4921
|
+
),
|
|
4922
|
+
/* @__PURE__ */ jsx45(
|
|
4923
|
+
AxisBottom2,
|
|
4924
|
+
{
|
|
4925
|
+
top: innerHeight,
|
|
4926
|
+
scale: x0Scale,
|
|
4927
|
+
stroke: vars6.chart.axis,
|
|
4928
|
+
tickStroke: vars6.chart.axis,
|
|
4929
|
+
tickLabelProps: () => ({ fill: vars6.chart.axis, fontSize: 11, textAnchor: "middle" })
|
|
4930
|
+
}
|
|
4931
|
+
),
|
|
4932
|
+
/* @__PURE__ */ jsx45(
|
|
4933
|
+
AxisLeft2,
|
|
4934
|
+
{
|
|
4935
|
+
scale: yScale,
|
|
4936
|
+
stroke: vars6.chart.axis,
|
|
4937
|
+
tickStroke: vars6.chart.axis,
|
|
4938
|
+
tickLabelProps: () => ({ fill: vars6.chart.axis, fontSize: 11, textAnchor: "end", dx: "-0.25em" })
|
|
4939
|
+
}
|
|
4940
|
+
)
|
|
4941
|
+
] }) }) });
|
|
4942
|
+
}
|
|
4943
|
+
|
|
4944
|
+
// src/components/charts/BarChart/BarChart.interactive.tsx
|
|
4945
|
+
import { useMemo as useMemo7, useState as useState18 } from "react";
|
|
4946
|
+
import { AxisBottom as AxisBottom3, AxisLeft as AxisLeft3 } from "@visx/axis";
|
|
4947
|
+
import { GridRows as GridRows3 } from "@visx/grid";
|
|
4948
|
+
import { Group as Group3 } from "@visx/group";
|
|
4949
|
+
import { ParentSize as ParentSize2 } from "@visx/responsive";
|
|
4950
|
+
import { Bar, BarGroup as BarGroup2, BarStack as BarStack2 } from "@visx/shape";
|
|
4951
|
+
import { TooltipWithBounds as TooltipWithBounds2, useTooltip as useTooltip2 } from "@visx/tooltip";
|
|
4952
|
+
import { vars as vars7 } from "@vesture/tokens";
|
|
4953
|
+
import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
4954
|
+
function InteractiveBarChart({
|
|
4955
|
+
data,
|
|
4956
|
+
series,
|
|
4957
|
+
margin,
|
|
4958
|
+
layout = "grouped",
|
|
4959
|
+
height = 320
|
|
4960
|
+
}) {
|
|
4961
|
+
const [hiddenKeys, setHiddenKeys] = useState18(/* @__PURE__ */ new Set());
|
|
4962
|
+
const coloredSeries = useMemo7(
|
|
4963
|
+
() => series.map((s, index) => ({ ...s, color: s.color ?? getSeriesColor2(s, index) })),
|
|
4964
|
+
[series]
|
|
4965
|
+
);
|
|
4966
|
+
const visibleSeries = useMemo7(
|
|
4967
|
+
() => coloredSeries.filter((s) => !hiddenKeys.has(s.key)),
|
|
4968
|
+
[coloredSeries, hiddenKeys]
|
|
4969
|
+
);
|
|
4970
|
+
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip2();
|
|
4971
|
+
function toggleSeries(key) {
|
|
4972
|
+
setHiddenKeys((prev) => {
|
|
4973
|
+
const next = new Set(prev);
|
|
4974
|
+
if (next.has(key)) {
|
|
4975
|
+
next.delete(key);
|
|
4976
|
+
} else {
|
|
4977
|
+
next.add(key);
|
|
4978
|
+
}
|
|
4979
|
+
return next;
|
|
4980
|
+
});
|
|
4981
|
+
}
|
|
4982
|
+
if (data.length === 0) {
|
|
4983
|
+
return /* @__PURE__ */ jsx46("div", { className: root6, style: { height }, children: /* @__PURE__ */ jsx46("div", { className: emptyState5, style: { height }, children: "No data" }) });
|
|
4984
|
+
}
|
|
4985
|
+
return /* @__PURE__ */ jsxs29("div", { className: root6, children: [
|
|
4986
|
+
/* @__PURE__ */ jsx46(ParentSize2, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
|
|
4987
|
+
if (width === 0) return null;
|
|
4988
|
+
const { scales, colorMap } = buildBarChartLayout(data, visibleSeries, width, height, margin, layout);
|
|
4989
|
+
const { x0Scale, x1Scale, xScale, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
|
|
4990
|
+
const keys = visibleSeries.map((s) => s.key);
|
|
4991
|
+
const seriesByKey = new Map(visibleSeries.map((s) => [s.key, s]));
|
|
4992
|
+
const color = (key, index) => colorMap[key] ?? SERIES_COLOR_CYCLE2[index % 8];
|
|
4993
|
+
function handleBarHover(categoryValue, seriesKey, value, event) {
|
|
4994
|
+
const s = seriesByKey.get(seriesKey);
|
|
4995
|
+
if (!s) return;
|
|
4996
|
+
const bounds = event.currentTarget;
|
|
4997
|
+
const x2 = Number(bounds.getAttribute("x") ?? 0);
|
|
4998
|
+
const y2 = Number(bounds.getAttribute("y") ?? 0);
|
|
4999
|
+
const barWidth = Number(bounds.getAttribute("width") ?? 0);
|
|
5000
|
+
showTooltip({
|
|
5001
|
+
tooltipData: { category: categoryValue, series: s, value },
|
|
5002
|
+
tooltipLeft: resolvedMargin.left + x2 + barWidth / 2,
|
|
5003
|
+
tooltipTop: resolvedMargin.top + y2
|
|
5004
|
+
});
|
|
5005
|
+
}
|
|
5006
|
+
return /* @__PURE__ */ jsxs29("div", { style: { position: "relative", width, height }, children: [
|
|
5007
|
+
/* @__PURE__ */ jsx46("svg", { width, height, role: "img", "aria-label": "Bar chart", children: /* @__PURE__ */ jsxs29(Group3, { left: resolvedMargin.left, top: resolvedMargin.top, children: [
|
|
5008
|
+
/* @__PURE__ */ jsx46(GridRows3, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars7.chart.grid }),
|
|
5009
|
+
layout === "stacked" ? /* @__PURE__ */ jsx46(
|
|
5010
|
+
BarStack2,
|
|
5011
|
+
{
|
|
5012
|
+
data,
|
|
5013
|
+
keys,
|
|
5014
|
+
x: (d) => d.category,
|
|
5015
|
+
xScale,
|
|
5016
|
+
yScale,
|
|
5017
|
+
color,
|
|
5018
|
+
children: (barStacks) => barStacks.map(
|
|
5019
|
+
(barStack) => barStack.bars.map((bar) => /* @__PURE__ */ jsx46(
|
|
5020
|
+
Bar,
|
|
5021
|
+
{
|
|
5022
|
+
x: bar.x,
|
|
5023
|
+
y: bar.y,
|
|
5024
|
+
width: bar.width,
|
|
5025
|
+
height: bar.height,
|
|
5026
|
+
fill: bar.color,
|
|
5027
|
+
onMouseEnter: (event) => handleBarHover(
|
|
5028
|
+
bar.bar.data.category,
|
|
5029
|
+
String(barStack.key),
|
|
5030
|
+
Number(bar.bar.data[barStack.key]),
|
|
5031
|
+
event
|
|
5032
|
+
),
|
|
5033
|
+
onMouseLeave: () => hideTooltip()
|
|
5034
|
+
},
|
|
5035
|
+
`bar-stack-${barStack.index}-${bar.index}`
|
|
5036
|
+
))
|
|
5037
|
+
)
|
|
5038
|
+
}
|
|
5039
|
+
) : /* @__PURE__ */ jsx46(
|
|
5040
|
+
BarGroup2,
|
|
5041
|
+
{
|
|
5042
|
+
data,
|
|
5043
|
+
keys,
|
|
5044
|
+
height: innerHeight,
|
|
5045
|
+
x0: (d) => d.category,
|
|
5046
|
+
x0Scale,
|
|
5047
|
+
x1Scale,
|
|
5048
|
+
yScale,
|
|
5049
|
+
color,
|
|
5050
|
+
children: (barGroups) => barGroups.map((barGroup) => /* @__PURE__ */ jsx46(Group3, { left: barGroup.x0, children: barGroup.bars.map((bar) => /* @__PURE__ */ jsx46(
|
|
5051
|
+
Bar,
|
|
5052
|
+
{
|
|
5053
|
+
x: bar.x,
|
|
5054
|
+
y: bar.y,
|
|
5055
|
+
width: bar.width,
|
|
5056
|
+
height: bar.height,
|
|
5057
|
+
fill: bar.color,
|
|
5058
|
+
onMouseEnter: (event) => handleBarHover(data[barGroup.index].category, String(bar.key), bar.value, event),
|
|
5059
|
+
onMouseLeave: () => hideTooltip()
|
|
5060
|
+
},
|
|
5061
|
+
`bar-group-bar-${barGroup.index}-${bar.key}`
|
|
5062
|
+
)) }, `bar-group-${barGroup.index}`))
|
|
5063
|
+
}
|
|
5064
|
+
),
|
|
5065
|
+
/* @__PURE__ */ jsx46(
|
|
5066
|
+
AxisBottom3,
|
|
5067
|
+
{
|
|
5068
|
+
top: innerHeight,
|
|
5069
|
+
scale: x0Scale,
|
|
5070
|
+
stroke: vars7.chart.axis,
|
|
5071
|
+
tickStroke: vars7.chart.axis,
|
|
5072
|
+
tickLabelProps: () => ({ fill: vars7.chart.axis, fontSize: 11, textAnchor: "middle" })
|
|
5073
|
+
}
|
|
5074
|
+
),
|
|
5075
|
+
/* @__PURE__ */ jsx46(
|
|
5076
|
+
AxisLeft3,
|
|
5077
|
+
{
|
|
5078
|
+
scale: yScale,
|
|
5079
|
+
stroke: vars7.chart.axis,
|
|
5080
|
+
tickStroke: vars7.chart.axis,
|
|
5081
|
+
tickLabelProps: () => ({
|
|
5082
|
+
fill: vars7.chart.axis,
|
|
5083
|
+
fontSize: 11,
|
|
5084
|
+
textAnchor: "end",
|
|
5085
|
+
dx: "-0.25em"
|
|
5086
|
+
})
|
|
5087
|
+
}
|
|
5088
|
+
)
|
|
5089
|
+
] }) }),
|
|
5090
|
+
tooltipOpen && tooltipData ? /* @__PURE__ */ jsxs29(TooltipWithBounds2, { left: tooltipLeft, top: tooltipTop, className: tooltip3, children: [
|
|
5091
|
+
/* @__PURE__ */ jsx46("div", { children: tooltipData.category }),
|
|
5092
|
+
/* @__PURE__ */ jsxs29("div", { className: tooltipRow2, children: [
|
|
5093
|
+
/* @__PURE__ */ jsx46("span", { className: tooltipSwatch2, style: { background: tooltipData.series.color } }),
|
|
5094
|
+
/* @__PURE__ */ jsxs29("span", { children: [
|
|
5095
|
+
tooltipData.series.label,
|
|
5096
|
+
": ",
|
|
5097
|
+
tooltipData.value
|
|
5098
|
+
] })
|
|
5099
|
+
] })
|
|
5100
|
+
] }) : null
|
|
5101
|
+
] });
|
|
5102
|
+
} }),
|
|
5103
|
+
/* @__PURE__ */ jsx46("div", { className: legend2, children: coloredSeries.map((s) => {
|
|
5104
|
+
const hidden = hiddenKeys.has(s.key);
|
|
5105
|
+
return /* @__PURE__ */ jsxs29(
|
|
5106
|
+
"button",
|
|
5107
|
+
{
|
|
5108
|
+
type: "button",
|
|
5109
|
+
className: [legendItem2, hidden ? legendItemHidden2 : null].filter(Boolean).join(" "),
|
|
5110
|
+
onClick: () => toggleSeries(s.key),
|
|
5111
|
+
"aria-pressed": !hidden,
|
|
5112
|
+
children: [
|
|
5113
|
+
/* @__PURE__ */ jsx46("span", { className: legendSwatch2, style: { background: s.color } }),
|
|
5114
|
+
s.label
|
|
5115
|
+
]
|
|
5116
|
+
},
|
|
5117
|
+
s.key
|
|
5118
|
+
);
|
|
5119
|
+
}) })
|
|
5120
|
+
] });
|
|
5121
|
+
}
|
|
5122
|
+
|
|
5123
|
+
// src/components/charts/AreaChart/AreaChart.tsx
|
|
5124
|
+
import { AxisBottom as AxisBottom4, AxisLeft as AxisLeft4 } from "@visx/axis";
|
|
5125
|
+
import { GridRows as GridRows4 } from "@visx/grid";
|
|
5126
|
+
import { Group as Group4 } from "@visx/group";
|
|
5127
|
+
import { Area } from "@visx/shape";
|
|
5128
|
+
import { vars as vars8 } from "@vesture/tokens";
|
|
5129
|
+
|
|
5130
|
+
// src/components/charts/AreaChart/AreaChart.render.ts
|
|
5131
|
+
var OVERLAP_FILL_OPACITY = 0.35;
|
|
5132
|
+
var areaGenerator = area_default().x((p) => p.x).y0((p) => p.y0).y1((p) => p.y1);
|
|
5133
|
+
function buildAreaChartLayout(data, series, width, height, margin, xScaleType, stacked = false) {
|
|
5134
|
+
const resolvedMargin = resolveMargin(margin);
|
|
5135
|
+
const resolvedXScaleType = xScaleType ?? inferXScaleType(data);
|
|
5136
|
+
const scales = buildScales(data, series, width, height, resolvedMargin, resolvedXScaleType, stacked);
|
|
5137
|
+
const cumulative = data.map(() => 0);
|
|
5138
|
+
const seriesLayouts = series.map((s, index) => {
|
|
5139
|
+
const points = [];
|
|
5140
|
+
data.forEach((d, dataIndex) => {
|
|
5141
|
+
const rawValue = numericValue(d[s.key]);
|
|
5142
|
+
if (!stacked && rawValue === void 0) return;
|
|
5143
|
+
const x2 = getXPixel(scales, d.x);
|
|
5144
|
+
if (x2 === void 0) return;
|
|
5145
|
+
const baseline = stacked ? cumulative[dataIndex] : 0;
|
|
5146
|
+
const top = stacked ? baseline + (rawValue ?? 0) : rawValue;
|
|
5147
|
+
if (stacked) cumulative[dataIndex] = top;
|
|
5148
|
+
points.push({ dataIndex, x: x2, y0: scales.yScale(baseline), y1: scales.yScale(top) });
|
|
5149
|
+
});
|
|
5150
|
+
return {
|
|
5151
|
+
key: s.key,
|
|
5152
|
+
label: s.label,
|
|
5153
|
+
color: getSeriesColor(s, index),
|
|
5154
|
+
opacity: stacked ? 1 : OVERLAP_FILL_OPACITY,
|
|
5155
|
+
points,
|
|
5156
|
+
path: points.length >= 2 ? areaGenerator(points) ?? "" : ""
|
|
5157
|
+
};
|
|
5158
|
+
});
|
|
5159
|
+
return { scales, seriesLayouts };
|
|
5160
|
+
}
|
|
5161
|
+
|
|
5162
|
+
// src/components/charts/AreaChart/AreaChart.css.ts
|
|
5163
|
+
var emptyState6 = "chartSurfaces_emptyState__n6njm11";
|
|
5164
|
+
var legend3 = "chartSurfaces_legend__n6njm15";
|
|
5165
|
+
var legendItem3 = "chartSurfaces_legendItem__n6njm16";
|
|
5166
|
+
var legendItemHidden3 = "chartSurfaces_legendItemHidden__n6njm17";
|
|
5167
|
+
var legendSwatch3 = "chartSurfaces_legendSwatch__n6njm18";
|
|
5168
|
+
var overlayRect2 = "AreaChart_overlayRect__1cqtbh30";
|
|
5169
|
+
var root7 = "chartSurfaces_root__n6njm10";
|
|
5170
|
+
var tooltip4 = "chartSurfaces_tooltip__n6njm12";
|
|
5171
|
+
var tooltipRow3 = "chartSurfaces_tooltipRow__n6njm13";
|
|
5172
|
+
var tooltipSwatch3 = "chartSurfaces_tooltipSwatch__n6njm14";
|
|
5173
|
+
|
|
5174
|
+
// src/components/charts/AreaChart/AreaChart.tsx
|
|
5175
|
+
import { jsx as jsx47, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5176
|
+
function AreaChart({
|
|
5177
|
+
data,
|
|
5178
|
+
series,
|
|
5179
|
+
width,
|
|
5180
|
+
height,
|
|
5181
|
+
margin,
|
|
5182
|
+
xScale,
|
|
5183
|
+
stacked = false
|
|
5184
|
+
}) {
|
|
5185
|
+
if (data.length === 0) {
|
|
5186
|
+
return /* @__PURE__ */ jsx47("div", { className: root7, style: { width, height }, children: /* @__PURE__ */ jsx47("div", { className: emptyState6, style: { width, height }, children: "No data" }) });
|
|
5187
|
+
}
|
|
5188
|
+
const { scales, seriesLayouts } = buildAreaChartLayout(data, series, width, height, margin, xScale, stacked);
|
|
5189
|
+
const { xScale: scaleX, yScale, innerWidth, innerHeight, margin: resolvedMargin } = scales;
|
|
5190
|
+
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: [
|
|
5191
|
+
/* @__PURE__ */ jsx47(GridRows4, { scale: yScale, width: innerWidth, height: innerHeight, stroke: vars8.chart.grid }),
|
|
5192
|
+
seriesLayouts.map((s) => /* @__PURE__ */ jsx47(
|
|
5193
|
+
Area,
|
|
5194
|
+
{
|
|
5195
|
+
data: s.points,
|
|
5196
|
+
x: (p) => p.x,
|
|
5197
|
+
y0: (p) => p.y0,
|
|
5198
|
+
y1: (p) => p.y1,
|
|
5199
|
+
fill: s.color,
|
|
5200
|
+
fillOpacity: s.opacity,
|
|
5201
|
+
stroke: s.color,
|
|
5202
|
+
strokeWidth: 1.5
|
|
5203
|
+
},
|
|
5204
|
+
s.key
|
|
5205
|
+
)),
|
|
5206
|
+
/* @__PURE__ */ jsx47(
|
|
5207
|
+
AxisBottom4,
|
|
5208
|
+
{
|
|
5209
|
+
top: innerHeight,
|
|
5210
|
+
scale: scaleX,
|
|
5211
|
+
stroke: vars8.chart.axis,
|
|
5212
|
+
tickStroke: vars8.chart.axis,
|
|
5213
|
+
tickLabelProps: () => ({ fill: vars8.chart.axis, fontSize: 11, textAnchor: "middle" })
|
|
5214
|
+
}
|
|
5215
|
+
),
|
|
5216
|
+
/* @__PURE__ */ jsx47(
|
|
5217
|
+
AxisLeft4,
|
|
5218
|
+
{
|
|
5219
|
+
scale: yScale,
|
|
5220
|
+
stroke: vars8.chart.axis,
|
|
5221
|
+
tickStroke: vars8.chart.axis,
|
|
5222
|
+
tickLabelProps: () => ({ fill: vars8.chart.axis, fontSize: 11, textAnchor: "end", dx: "-0.25em" })
|
|
5223
|
+
}
|
|
5224
|
+
)
|
|
5225
|
+
] }) }) });
|
|
5226
|
+
}
|
|
5227
|
+
|
|
5228
|
+
// src/components/charts/AreaChart/AreaChart.interactive.tsx
|
|
5229
|
+
import { useMemo as useMemo8, useState as useState19 } from "react";
|
|
5230
|
+
import { ParentSize as ParentSize3 } from "@visx/responsive";
|
|
5231
|
+
import { TooltipWithBounds as TooltipWithBounds3, useTooltip as useTooltip3 } from "@visx/tooltip";
|
|
5232
|
+
import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5233
|
+
function InteractiveAreaChart({
|
|
5234
|
+
data,
|
|
5235
|
+
series,
|
|
5236
|
+
margin,
|
|
5237
|
+
xScale,
|
|
5238
|
+
stacked = false,
|
|
5239
|
+
height = 320
|
|
5240
|
+
}) {
|
|
5241
|
+
const [hiddenKeys, setHiddenKeys] = useState19(/* @__PURE__ */ new Set());
|
|
5242
|
+
const coloredSeries = useMemo8(
|
|
5243
|
+
() => series.map((s, index) => ({ ...s, color: s.color ?? getSeriesColor(s, index) })),
|
|
5244
|
+
[series]
|
|
5245
|
+
);
|
|
5246
|
+
const visibleSeries = useMemo8(
|
|
5247
|
+
() => coloredSeries.filter((s) => !hiddenKeys.has(s.key)),
|
|
5248
|
+
[coloredSeries, hiddenKeys]
|
|
5249
|
+
);
|
|
5250
|
+
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip3();
|
|
5251
|
+
function toggleSeries(key) {
|
|
5252
|
+
setHiddenKeys((prev) => {
|
|
5253
|
+
const next = new Set(prev);
|
|
5254
|
+
if (next.has(key)) {
|
|
5255
|
+
next.delete(key);
|
|
5256
|
+
} else {
|
|
5257
|
+
next.add(key);
|
|
5258
|
+
}
|
|
5259
|
+
return next;
|
|
5260
|
+
});
|
|
5261
|
+
}
|
|
5262
|
+
return /* @__PURE__ */ jsxs31("div", { className: root7, children: [
|
|
5263
|
+
/* @__PURE__ */ jsx48(ParentSize3, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
|
|
5264
|
+
if (width === 0) return null;
|
|
5265
|
+
const { scales } = buildAreaChartLayout(data, visibleSeries, width, height, margin, xScale, stacked);
|
|
5266
|
+
function handleMouseMove(event) {
|
|
5267
|
+
const bounds = event.currentTarget.getBoundingClientRect();
|
|
5268
|
+
const pixelX = event.clientX - bounds.left;
|
|
5269
|
+
const dataIndex = findNearestDataIndex(data, scales, pixelX);
|
|
5270
|
+
if (dataIndex === null) {
|
|
5271
|
+
hideTooltip();
|
|
5272
|
+
return;
|
|
5273
|
+
}
|
|
5274
|
+
const dataPoint = data[dataIndex];
|
|
5275
|
+
const xPixel = getXPixel(scales, dataPoint.x) ?? pixelX;
|
|
5276
|
+
showTooltip({
|
|
5277
|
+
tooltipData: { dataPoint, visibleSeries },
|
|
5278
|
+
tooltipLeft: scales.margin.left + xPixel,
|
|
5279
|
+
tooltipTop: 0
|
|
5280
|
+
});
|
|
5281
|
+
}
|
|
5282
|
+
return /* @__PURE__ */ jsxs31("div", { style: { position: "relative", width, height }, children: [
|
|
5283
|
+
/* @__PURE__ */ jsx48(
|
|
5284
|
+
AreaChart,
|
|
5285
|
+
{
|
|
5286
|
+
data,
|
|
5287
|
+
series: visibleSeries,
|
|
5288
|
+
width,
|
|
5289
|
+
height,
|
|
5290
|
+
margin,
|
|
5291
|
+
xScale,
|
|
5292
|
+
stacked
|
|
5293
|
+
}
|
|
5294
|
+
),
|
|
5295
|
+
/* @__PURE__ */ jsx48(
|
|
5296
|
+
"svg",
|
|
5297
|
+
{
|
|
5298
|
+
width,
|
|
5299
|
+
height,
|
|
5300
|
+
style: { position: "absolute", top: 0, left: 0 },
|
|
5301
|
+
"aria-hidden": "true",
|
|
5302
|
+
children: /* @__PURE__ */ jsx48(
|
|
5303
|
+
"rect",
|
|
5304
|
+
{
|
|
5305
|
+
className: overlayRect2,
|
|
5306
|
+
"data-testid": "area-chart-overlay",
|
|
5307
|
+
x: scales.margin.left,
|
|
5308
|
+
y: scales.margin.top,
|
|
5309
|
+
width: scales.innerWidth,
|
|
5310
|
+
height: scales.innerHeight,
|
|
5311
|
+
onMouseMove: handleMouseMove,
|
|
5312
|
+
onMouseLeave: () => hideTooltip()
|
|
5313
|
+
}
|
|
5314
|
+
)
|
|
5315
|
+
}
|
|
5316
|
+
),
|
|
5317
|
+
tooltipOpen && tooltipData ? /* @__PURE__ */ jsxs31(TooltipWithBounds3, { left: tooltipLeft, top: tooltipTop, className: tooltip4, children: [
|
|
5318
|
+
/* @__PURE__ */ jsx48("div", { children: String(tooltipData.dataPoint.x) }),
|
|
5319
|
+
tooltipData.visibleSeries.map((s) => /* @__PURE__ */ jsxs31("div", { className: tooltipRow3, children: [
|
|
5320
|
+
/* @__PURE__ */ jsx48("span", { className: tooltipSwatch3, style: { background: s.color } }),
|
|
5321
|
+
/* @__PURE__ */ jsxs31("span", { children: [
|
|
5322
|
+
s.label,
|
|
5323
|
+
": ",
|
|
5324
|
+
String(tooltipData.dataPoint[s.key])
|
|
5325
|
+
] })
|
|
5326
|
+
] }, s.key))
|
|
5327
|
+
] }) : null
|
|
5328
|
+
] });
|
|
5329
|
+
} }),
|
|
5330
|
+
/* @__PURE__ */ jsx48("div", { className: legend3, children: coloredSeries.map((s) => {
|
|
5331
|
+
const hidden = hiddenKeys.has(s.key);
|
|
5332
|
+
return /* @__PURE__ */ jsxs31(
|
|
5333
|
+
"button",
|
|
5334
|
+
{
|
|
5335
|
+
type: "button",
|
|
5336
|
+
className: [legendItem3, hidden ? legendItemHidden3 : null].filter(Boolean).join(" "),
|
|
5337
|
+
onClick: () => toggleSeries(s.key),
|
|
5338
|
+
"aria-pressed": !hidden,
|
|
5339
|
+
children: [
|
|
5340
|
+
/* @__PURE__ */ jsx48("span", { className: legendSwatch3, style: { background: s.color } }),
|
|
5341
|
+
s.label
|
|
5342
|
+
]
|
|
5343
|
+
},
|
|
5344
|
+
s.key
|
|
5345
|
+
);
|
|
5346
|
+
}) })
|
|
5347
|
+
] });
|
|
5348
|
+
}
|
|
5349
|
+
|
|
5350
|
+
// src/components/charts/PieChart/PieChart.tsx
|
|
5351
|
+
import { Group as Group5 } from "@visx/group";
|
|
5352
|
+
import { Pie } from "@visx/shape";
|
|
5353
|
+
import { vars as vars10 } from "@vesture/tokens";
|
|
5354
|
+
|
|
5355
|
+
// src/components/charts/PieChart/PieChart.render.ts
|
|
5356
|
+
import { vars as vars9 } from "@vesture/tokens";
|
|
5357
|
+
var SERIES_COLOR_CYCLE3 = [
|
|
5358
|
+
vars9.chart.series1,
|
|
5359
|
+
vars9.chart.series2,
|
|
5360
|
+
vars9.chart.series3,
|
|
5361
|
+
vars9.chart.series4,
|
|
5362
|
+
vars9.chart.series5,
|
|
5363
|
+
vars9.chart.series6,
|
|
5364
|
+
vars9.chart.series7,
|
|
5365
|
+
vars9.chart.series8
|
|
5366
|
+
];
|
|
5367
|
+
function getSeriesColor3(slice2, index) {
|
|
5368
|
+
return slice2.color ?? SERIES_COLOR_CYCLE3[index % SERIES_COLOR_CYCLE3.length];
|
|
5369
|
+
}
|
|
5370
|
+
function computePercentages(slices) {
|
|
5371
|
+
const total = slices.reduce((sum, s) => sum + s.value, 0);
|
|
5372
|
+
return slices.map((s) => ({ ...s, percentage: total > 0 ? s.value / total * 100 : 0 }));
|
|
5373
|
+
}
|
|
5374
|
+
function colorSlices(data) {
|
|
5375
|
+
return data.map((d, index) => ({ key: d.key, label: d.label, value: d.value, color: getSeriesColor3(d, index) }));
|
|
5376
|
+
}
|
|
5377
|
+
function preparePieSlices(data) {
|
|
5378
|
+
const positive = colorSlices(data).filter((s) => s.value > 0);
|
|
5379
|
+
return computePercentages(positive);
|
|
5380
|
+
}
|
|
5381
|
+
var MIN_LABEL_ARC_LENGTH_PX = 28;
|
|
5382
|
+
function isLabelFittable(startAngle, endAngle, outerRadius) {
|
|
5383
|
+
return (endAngle - startAngle) * outerRadius >= MIN_LABEL_ARC_LENGTH_PX;
|
|
5384
|
+
}
|
|
5385
|
+
function arcBisectorDirection(startAngle, endAngle) {
|
|
5386
|
+
const bisector = (startAngle + endAngle) / 2;
|
|
5387
|
+
return [Math.sin(bisector), -Math.cos(bisector)];
|
|
5388
|
+
}
|
|
5389
|
+
|
|
5390
|
+
// src/components/charts/PieChart/PieChart.css.ts
|
|
5391
|
+
var emptyState7 = "chartSurfaces_emptyState__n6njm11";
|
|
5392
|
+
var legend4 = "chartSurfaces_legend__n6njm15";
|
|
5393
|
+
var legendItem4 = "chartSurfaces_legendItem__n6njm16";
|
|
5394
|
+
var legendItemHidden4 = "chartSurfaces_legendItemHidden__n6njm17";
|
|
5395
|
+
var legendPercentage = "PieChart_legendPercentage__19xd4rn0";
|
|
5396
|
+
var legendSwatch4 = "chartSurfaces_legendSwatch__n6njm18";
|
|
5397
|
+
var root8 = "chartSurfaces_root__n6njm10";
|
|
5398
|
+
var sliceGroup = "PieChart_sliceGroup__19xd4rn1";
|
|
5399
|
+
var tooltip5 = "chartSurfaces_tooltip__n6njm12";
|
|
5400
|
+
var tooltipRow4 = "chartSurfaces_tooltipRow__n6njm13";
|
|
5401
|
+
var tooltipSwatch4 = "chartSurfaces_tooltipSwatch__n6njm14";
|
|
5402
|
+
|
|
5403
|
+
// src/components/charts/PieChart/PieChart.tsx
|
|
5404
|
+
import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5405
|
+
var OUTER_PADDING = 8;
|
|
5406
|
+
function PieChart({
|
|
5407
|
+
data,
|
|
5408
|
+
width,
|
|
5409
|
+
height,
|
|
5410
|
+
innerRadius = 0,
|
|
5411
|
+
showLabels = true
|
|
5412
|
+
}) {
|
|
5413
|
+
const slices = preparePieSlices(data);
|
|
5414
|
+
if (slices.length === 0) {
|
|
5415
|
+
return /* @__PURE__ */ jsx49("div", { className: root8, style: { width, height }, children: /* @__PURE__ */ jsx49("div", { className: emptyState7, style: { width, height }, children: "No data" }) });
|
|
5416
|
+
}
|
|
5417
|
+
const outerRadius = Math.max(0, Math.min(width, height) / 2 - OUTER_PADDING);
|
|
5418
|
+
const pieInnerRadius = outerRadius * innerRadius;
|
|
5419
|
+
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(
|
|
5420
|
+
Pie,
|
|
5421
|
+
{
|
|
5422
|
+
data: slices,
|
|
5423
|
+
pieValue: (s) => s.value,
|
|
5424
|
+
pieSort: null,
|
|
5425
|
+
outerRadius,
|
|
5426
|
+
innerRadius: pieInnerRadius,
|
|
5427
|
+
children: (pie) => pie.arcs.map((arc) => {
|
|
5428
|
+
const [labelX, labelY] = pie.path.centroid(arc);
|
|
5429
|
+
const showLabel = showLabels && isLabelFittable(arc.startAngle, arc.endAngle, outerRadius);
|
|
5430
|
+
return /* @__PURE__ */ jsxs32("g", { children: [
|
|
5431
|
+
/* @__PURE__ */ jsx49("path", { d: pie.path(arc) ?? "", fill: arc.data.color }),
|
|
5432
|
+
showLabel ? /* @__PURE__ */ jsx49(
|
|
5433
|
+
"text",
|
|
5434
|
+
{
|
|
5435
|
+
x: labelX,
|
|
5436
|
+
y: labelY,
|
|
5437
|
+
textAnchor: "middle",
|
|
5438
|
+
dominantBaseline: "middle",
|
|
5439
|
+
fill: vars10.color.textInverse,
|
|
5440
|
+
fontSize: vars10.font.sizeXs,
|
|
5441
|
+
fontFamily: vars10.font.body,
|
|
5442
|
+
children: `${Math.round(arc.data.percentage)}%`
|
|
5443
|
+
}
|
|
5444
|
+
) : null
|
|
5445
|
+
] }, arc.data.key);
|
|
5446
|
+
})
|
|
5447
|
+
}
|
|
5448
|
+
) }) }) });
|
|
5449
|
+
}
|
|
5450
|
+
|
|
5451
|
+
// src/components/charts/PieChart/PieChart.interactive.tsx
|
|
5452
|
+
import { useMemo as useMemo9, useState as useState20 } from "react";
|
|
5453
|
+
import { Group as Group6 } from "@visx/group";
|
|
5454
|
+
import { ParentSize as ParentSize4 } from "@visx/responsive";
|
|
5455
|
+
import { Pie as Pie2 } from "@visx/shape";
|
|
5456
|
+
import { TooltipWithBounds as TooltipWithBounds4, useTooltip as useTooltip4 } from "@visx/tooltip";
|
|
5457
|
+
import { vars as vars11 } from "@vesture/tokens";
|
|
5458
|
+
import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5459
|
+
var OUTER_PADDING2 = 8;
|
|
5460
|
+
var HOVER_OFFSET_PX = 8;
|
|
5461
|
+
function InteractivePieChart({
|
|
5462
|
+
data,
|
|
5463
|
+
innerRadius = 0,
|
|
5464
|
+
showLabels = true,
|
|
5465
|
+
height = 320
|
|
5466
|
+
}) {
|
|
5467
|
+
const [hiddenKeys, setHiddenKeys] = useState20(/* @__PURE__ */ new Set());
|
|
5468
|
+
const [hoveredKey, setHoveredKey] = useState20(null);
|
|
5469
|
+
const coloredSlices = useMemo9(() => colorSlices(data), [data]);
|
|
5470
|
+
const visibleSlices = useMemo9(
|
|
5471
|
+
() => coloredSlices.filter((s) => s.value > 0 && !hiddenKeys.has(s.key)),
|
|
5472
|
+
[coloredSlices, hiddenKeys]
|
|
5473
|
+
);
|
|
5474
|
+
const slices = useMemo9(() => computePercentages(visibleSlices), [visibleSlices]);
|
|
5475
|
+
const percentageByKey = useMemo9(() => new Map(slices.map((s) => [s.key, s.percentage])), [slices]);
|
|
5476
|
+
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip4();
|
|
5477
|
+
function toggleSlice(key) {
|
|
5478
|
+
setHiddenKeys((prev) => {
|
|
5479
|
+
const next = new Set(prev);
|
|
5480
|
+
if (next.has(key)) {
|
|
5481
|
+
next.delete(key);
|
|
5482
|
+
} else {
|
|
5483
|
+
next.add(key);
|
|
5484
|
+
}
|
|
5485
|
+
return next;
|
|
5486
|
+
});
|
|
5487
|
+
}
|
|
5488
|
+
if (slices.length === 0) {
|
|
5489
|
+
return /* @__PURE__ */ jsx50("div", { className: root8, style: { height }, children: /* @__PURE__ */ jsx50("div", { className: emptyState7, style: { height }, children: "No data" }) });
|
|
5490
|
+
}
|
|
5491
|
+
return /* @__PURE__ */ jsxs33("div", { className: root8, children: [
|
|
5492
|
+
/* @__PURE__ */ jsx50(ParentSize4, { initialSize: { width: 600, height }, style: { height }, children: ({ width }) => {
|
|
5493
|
+
if (width === 0) return null;
|
|
5494
|
+
const outerRadius = Math.max(0, Math.min(width, height) / 2 - OUTER_PADDING2);
|
|
5495
|
+
const pieInnerRadius = outerRadius * innerRadius;
|
|
5496
|
+
function handleSliceHover(datum, centroidX, centroidY) {
|
|
5497
|
+
showTooltip({
|
|
5498
|
+
tooltipData: datum,
|
|
5499
|
+
tooltipLeft: width / 2 + centroidX,
|
|
5500
|
+
tooltipTop: height / 2 + centroidY
|
|
5501
|
+
});
|
|
5502
|
+
setHoveredKey(datum.key);
|
|
5503
|
+
}
|
|
5504
|
+
function handleSliceLeave() {
|
|
5505
|
+
hideTooltip();
|
|
5506
|
+
setHoveredKey(null);
|
|
5507
|
+
}
|
|
5508
|
+
return /* @__PURE__ */ jsxs33("div", { style: { position: "relative", width, height }, children: [
|
|
5509
|
+
/* @__PURE__ */ jsx50("svg", { width, height, role: "img", "aria-label": "Pie chart", children: /* @__PURE__ */ jsx50(Group6, { top: height / 2, left: width / 2, children: /* @__PURE__ */ jsx50(
|
|
5510
|
+
Pie2,
|
|
5511
|
+
{
|
|
5512
|
+
data: slices,
|
|
5513
|
+
pieValue: (s) => s.value,
|
|
5514
|
+
pieSort: null,
|
|
5515
|
+
outerRadius,
|
|
5516
|
+
innerRadius: pieInnerRadius,
|
|
5517
|
+
children: (pie) => pie.arcs.map((arc) => {
|
|
5518
|
+
const [centroidX, centroidY] = pie.path.centroid(arc);
|
|
5519
|
+
const showLabel = showLabels && isLabelFittable(arc.startAngle, arc.endAngle, outerRadius);
|
|
5520
|
+
const isHovered = hoveredKey === arc.data.key;
|
|
5521
|
+
const [dx, dy] = arcBisectorDirection(arc.startAngle, arc.endAngle);
|
|
5522
|
+
const transform = isHovered ? `translate(${dx * HOVER_OFFSET_PX}px, ${dy * HOVER_OFFSET_PX}px)` : void 0;
|
|
5523
|
+
return /* @__PURE__ */ jsxs33("g", { className: sliceGroup, style: { transform }, children: [
|
|
5524
|
+
/* @__PURE__ */ jsx50(
|
|
5525
|
+
"path",
|
|
5526
|
+
{
|
|
5527
|
+
d: pie.path(arc) ?? "",
|
|
5528
|
+
fill: arc.data.color,
|
|
5529
|
+
"data-testid": `pie-slice-${arc.data.key}`,
|
|
5530
|
+
onMouseEnter: () => handleSliceHover(arc.data, centroidX, centroidY),
|
|
5531
|
+
onMouseLeave: handleSliceLeave
|
|
5532
|
+
}
|
|
5533
|
+
),
|
|
5534
|
+
showLabel ? /* @__PURE__ */ jsx50(
|
|
5535
|
+
"text",
|
|
5536
|
+
{
|
|
5537
|
+
x: centroidX,
|
|
5538
|
+
y: centroidY,
|
|
5539
|
+
textAnchor: "middle",
|
|
5540
|
+
dominantBaseline: "middle",
|
|
5541
|
+
fill: vars11.color.textInverse,
|
|
5542
|
+
fontSize: vars11.font.sizeXs,
|
|
5543
|
+
fontFamily: vars11.font.body,
|
|
5544
|
+
style: { pointerEvents: "none" },
|
|
5545
|
+
children: `${Math.round(arc.data.percentage)}%`
|
|
5546
|
+
}
|
|
5547
|
+
) : null
|
|
5548
|
+
] }, arc.data.key);
|
|
5549
|
+
})
|
|
5550
|
+
}
|
|
5551
|
+
) }) }),
|
|
5552
|
+
tooltipOpen && tooltipData ? /* @__PURE__ */ jsx50(TooltipWithBounds4, { left: tooltipLeft, top: tooltipTop, className: tooltip5, children: /* @__PURE__ */ jsxs33("div", { className: tooltipRow4, children: [
|
|
5553
|
+
/* @__PURE__ */ jsx50("span", { className: tooltipSwatch4, style: { background: tooltipData.color } }),
|
|
5554
|
+
/* @__PURE__ */ jsxs33("span", { children: [
|
|
5555
|
+
tooltipData.label,
|
|
5556
|
+
": ",
|
|
5557
|
+
tooltipData.value,
|
|
5558
|
+
" (",
|
|
5559
|
+
Math.round(tooltipData.percentage),
|
|
5560
|
+
"%)"
|
|
5561
|
+
] })
|
|
5562
|
+
] }) }) : null
|
|
5563
|
+
] });
|
|
5564
|
+
} }),
|
|
5565
|
+
/* @__PURE__ */ jsx50("div", { className: legend4, children: coloredSlices.filter((s) => s.value > 0).map((s) => {
|
|
5566
|
+
const hidden = hiddenKeys.has(s.key);
|
|
5567
|
+
const percentage = percentageByKey.get(s.key);
|
|
5568
|
+
return /* @__PURE__ */ jsxs33(
|
|
5569
|
+
"button",
|
|
5570
|
+
{
|
|
5571
|
+
type: "button",
|
|
5572
|
+
className: [legendItem4, hidden ? legendItemHidden4 : null].filter(Boolean).join(" "),
|
|
5573
|
+
onClick: () => toggleSlice(s.key),
|
|
5574
|
+
"aria-pressed": !hidden,
|
|
5575
|
+
children: [
|
|
5576
|
+
/* @__PURE__ */ jsx50("span", { className: legendSwatch4, style: { background: s.color } }),
|
|
5577
|
+
s.label,
|
|
5578
|
+
!hidden && percentage !== void 0 ? /* @__PURE__ */ jsxs33("span", { className: legendPercentage, children: [
|
|
5579
|
+
Math.round(percentage),
|
|
5580
|
+
"%"
|
|
5581
|
+
] }) : null
|
|
5582
|
+
]
|
|
5583
|
+
},
|
|
5584
|
+
s.key
|
|
5585
|
+
);
|
|
5586
|
+
}) })
|
|
5587
|
+
] });
|
|
5588
|
+
}
|
|
5589
|
+
|
|
5590
|
+
// src/components/Scheduler/Scheduler.tsx
|
|
5591
|
+
import { useMemo as useMemo10, useRef as useRef12, useState as useState21 } from "react";
|
|
5592
|
+
|
|
5593
|
+
// src/components/Scheduler/Scheduler.css.ts
|
|
5594
|
+
var allDayCell = "Scheduler_allDayCell__1to95h2c";
|
|
5595
|
+
var allDayEventBlock = "Scheduler_allDayEventBlock__1to95h2o";
|
|
5596
|
+
var allDayGutter = "Scheduler_allDayGutter__1to95h2b";
|
|
5597
|
+
var allDayRow = "Scheduler_allDayRow__1to95h2a";
|
|
5598
|
+
var dayColumn = "Scheduler_dayColumn__1to95h2g";
|
|
5599
|
+
var dayHeaderCell = "Scheduler_dayHeaderCell__1to95h28";
|
|
5600
|
+
var dayHeaderDateNumber = "Scheduler_dayHeaderDateNumber__1to95h29";
|
|
5601
|
+
var dayHeaderGutter = "Scheduler_dayHeaderGutter__1to95h27";
|
|
5602
|
+
var dayHeaderRow = "Scheduler_dayHeaderRow__1to95h26";
|
|
5603
|
+
var dragPreview = "Scheduler_dragPreview__1to95h2l";
|
|
5604
|
+
var dragPreviewLabel = "Scheduler_dragPreviewLabel__1to95h2m";
|
|
5605
|
+
var eventBlock = "Scheduler_eventBlock__1to95h2j";
|
|
5606
|
+
var eventTime = "Scheduler_eventTime__1to95h2q";
|
|
5607
|
+
var eventTitle = "Scheduler_eventTitle__1to95h2p";
|
|
5608
|
+
var header2 = "Scheduler_header__1to95h21";
|
|
5609
|
+
var headerNav = "Scheduler_headerNav__1to95h22";
|
|
5610
|
+
var hourLabel = "Scheduler_hourLabel__1to95h2f";
|
|
5611
|
+
var navButton2 = "Scheduler_navButton__1to95h23";
|
|
5612
|
+
var nowLine = "Scheduler_nowLine__1to95h2h";
|
|
5613
|
+
var nowLineDot = "Scheduler_nowLineDot__1to95h2i";
|
|
5614
|
+
var rangeLabel = "Scheduler_rangeLabel__1to95h25";
|
|
5615
|
+
var resizeHandle2 = "Scheduler_resizeHandle__1to95h2k";
|
|
5616
|
+
var root9 = "Scheduler_root__1to95h20";
|
|
5617
|
+
var scrollArea = "Scheduler_scrollArea__1to95h2d";
|
|
5618
|
+
var timeGutter = "Scheduler_timeGutter__1to95h2e";
|
|
5619
|
+
var todayButton = "Scheduler_todayButton__1to95h24";
|
|
5620
|
+
var visuallyHidden = "Scheduler_visuallyHidden__1to95h2n";
|
|
5621
|
+
|
|
5622
|
+
// src/components/Scheduler/scheduler-layout.ts
|
|
5623
|
+
import { vars as vars12 } from "@vesture/tokens";
|
|
5624
|
+
var SLOT_HEIGHT_PX = 24;
|
|
5625
|
+
function layoutOverlappingEvents(events) {
|
|
5626
|
+
if (events.length === 0) return [];
|
|
5627
|
+
const sorted = [...events].sort((a, b) => {
|
|
5628
|
+
const startDiff = a.start.getTime() - b.start.getTime();
|
|
5629
|
+
if (startDiff !== 0) return startDiff;
|
|
5630
|
+
return a.end.getTime() - b.end.getTime();
|
|
5631
|
+
});
|
|
5632
|
+
const results = /* @__PURE__ */ new Map();
|
|
5633
|
+
let cluster = [];
|
|
5634
|
+
let clusterEnd = -Infinity;
|
|
5635
|
+
const flushCluster = () => {
|
|
5636
|
+
if (cluster.length === 0) return;
|
|
5637
|
+
const columnEndTimes = [];
|
|
5638
|
+
for (const event of cluster) {
|
|
5639
|
+
const startTime = event.start.getTime();
|
|
5640
|
+
let columnIndex = columnEndTimes.findIndex((end) => end <= startTime);
|
|
5641
|
+
if (columnIndex === -1) {
|
|
5642
|
+
columnIndex = columnEndTimes.length;
|
|
5643
|
+
columnEndTimes.push(event.end.getTime());
|
|
5644
|
+
} else {
|
|
5645
|
+
columnEndTimes[columnIndex] = event.end.getTime();
|
|
5646
|
+
}
|
|
5647
|
+
results.set(event.id, { id: event.id, columnIndex, columnCount: 0 });
|
|
5648
|
+
}
|
|
5649
|
+
const columnCount = columnEndTimes.length;
|
|
5650
|
+
for (const event of cluster) {
|
|
5651
|
+
results.get(event.id).columnCount = columnCount;
|
|
5652
|
+
}
|
|
5653
|
+
cluster = [];
|
|
5654
|
+
};
|
|
5655
|
+
for (const event of sorted) {
|
|
5656
|
+
const startTime = event.start.getTime();
|
|
5657
|
+
const endTime = event.end.getTime();
|
|
5658
|
+
if (cluster.length === 0 || startTime < clusterEnd) {
|
|
5659
|
+
cluster.push(event);
|
|
5660
|
+
clusterEnd = Math.max(clusterEnd, endTime);
|
|
5661
|
+
} else {
|
|
5662
|
+
flushCluster();
|
|
5663
|
+
cluster.push(event);
|
|
5664
|
+
clusterEnd = endTime;
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
flushCluster();
|
|
5668
|
+
return events.map((event) => results.get(event.id));
|
|
5669
|
+
}
|
|
5670
|
+
function getVerticalMetrics(start, end, startHour, endHour) {
|
|
5671
|
+
const rangeStartMinutes = startHour * 60;
|
|
5672
|
+
const rangeEndMinutes = endHour * 60;
|
|
5673
|
+
const totalMinutes = rangeEndMinutes - rangeStartMinutes;
|
|
5674
|
+
if (totalMinutes <= 0) return null;
|
|
5675
|
+
const startMinutes = start.getHours() * 60 + start.getMinutes();
|
|
5676
|
+
const endMinutes = end.getHours() * 60 + end.getMinutes();
|
|
5677
|
+
const clippedStart = Math.max(startMinutes, rangeStartMinutes);
|
|
5678
|
+
const clippedEnd = Math.min(endMinutes, rangeEndMinutes);
|
|
5679
|
+
if (clippedEnd <= clippedStart) return null;
|
|
5680
|
+
return {
|
|
5681
|
+
top: (clippedStart - rangeStartMinutes) / totalMinutes * 100,
|
|
5682
|
+
height: (clippedEnd - clippedStart) / totalMinutes * 100
|
|
5683
|
+
};
|
|
5684
|
+
}
|
|
5685
|
+
function pixelDeltaToSnappedMinutes(deltaPx, slotDuration) {
|
|
5686
|
+
const rawSlots = deltaPx / SLOT_HEIGHT_PX;
|
|
5687
|
+
return Math.round(rawSlots) * slotDuration;
|
|
5688
|
+
}
|
|
5689
|
+
function minutesOfDay(date) {
|
|
5690
|
+
return date.getHours() * 60 + date.getMinutes();
|
|
5691
|
+
}
|
|
5692
|
+
function combineDayAndMinutes(day, minutesOfDayValue) {
|
|
5693
|
+
const result = new Date(day.getFullYear(), day.getMonth(), day.getDate());
|
|
5694
|
+
result.setMinutes(minutesOfDayValue);
|
|
5695
|
+
return result;
|
|
5696
|
+
}
|
|
5697
|
+
function computeMoveResult(params) {
|
|
5698
|
+
const { originalStart, originalEnd, targetDay, deltaYPx, slotDuration, startHour, endHour } = params;
|
|
5699
|
+
const durationMinutes = (originalEnd.getTime() - originalStart.getTime()) / 6e4;
|
|
5700
|
+
const deltaMinutes = pixelDeltaToSnappedMinutes(deltaYPx, slotDuration);
|
|
5701
|
+
const rawStartMinutes = minutesOfDay(originalStart) + deltaMinutes;
|
|
5702
|
+
const rangeStart = startHour * 60;
|
|
5703
|
+
const rangeEnd = endHour * 60;
|
|
5704
|
+
const maxStart = Math.max(rangeStart, rangeEnd - durationMinutes);
|
|
5705
|
+
const clampedStartMinutes = Math.min(Math.max(rawStartMinutes, rangeStart), maxStart);
|
|
5706
|
+
const start = combineDayAndMinutes(targetDay, clampedStartMinutes);
|
|
5707
|
+
const end = new Date(start.getTime() + durationMinutes * 6e4);
|
|
5708
|
+
return { start, end };
|
|
5709
|
+
}
|
|
5710
|
+
function computeResizeResult(params) {
|
|
5711
|
+
const { originalStart, originalEnd, deltaYPx, slotDuration, minEventDuration, endHour } = params;
|
|
5712
|
+
const deltaMinutes = pixelDeltaToSnappedMinutes(deltaYPx, slotDuration);
|
|
5713
|
+
const rawEndMinutes = minutesOfDay(originalEnd) + deltaMinutes;
|
|
5714
|
+
const startMinutes = minutesOfDay(originalStart);
|
|
5715
|
+
const rangeEnd = endHour * 60;
|
|
5716
|
+
const clampedEndMinutes = Math.min(
|
|
5717
|
+
Math.max(rawEndMinutes, startMinutes + minEventDuration),
|
|
5718
|
+
rangeEnd
|
|
5719
|
+
);
|
|
5720
|
+
const end = combineDayAndMinutes(originalStart, clampedEndMinutes);
|
|
5721
|
+
return { end };
|
|
5722
|
+
}
|
|
5723
|
+
var SERIES_COLOR_CYCLE4 = [
|
|
5724
|
+
vars12.chart.series1,
|
|
5725
|
+
vars12.chart.series2,
|
|
5726
|
+
vars12.chart.series3,
|
|
5727
|
+
vars12.chart.series4,
|
|
5728
|
+
vars12.chart.series5,
|
|
5729
|
+
vars12.chart.series6,
|
|
5730
|
+
vars12.chart.series7,
|
|
5731
|
+
vars12.chart.series8
|
|
5732
|
+
];
|
|
5733
|
+
function hashStringToIndex(value, bucketCount) {
|
|
5734
|
+
let hash = 5381;
|
|
5735
|
+
for (let i = 0; i < value.length; i++) {
|
|
5736
|
+
hash = hash * 33 ^ value.charCodeAt(i);
|
|
5737
|
+
}
|
|
5738
|
+
return Math.abs(hash) % bucketCount;
|
|
5739
|
+
}
|
|
5740
|
+
function getEventColor(id, override) {
|
|
5741
|
+
if (override) return override;
|
|
5742
|
+
return SERIES_COLOR_CYCLE4[hashStringToIndex(id, SERIES_COLOR_CYCLE4.length)];
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5745
|
+
// src/components/Scheduler/Scheduler.tsx
|
|
5746
|
+
import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
5747
|
+
function formatEventTime(date, locale) {
|
|
5748
|
+
return new Intl.DateTimeFormat(locale, {
|
|
5749
|
+
hour: "numeric",
|
|
5750
|
+
minute: "2-digit"
|
|
5751
|
+
}).format(date);
|
|
5752
|
+
}
|
|
5753
|
+
function Scheduler({
|
|
5754
|
+
events,
|
|
5755
|
+
date,
|
|
5756
|
+
onDateChange,
|
|
5757
|
+
weekStartsOn = 1,
|
|
5758
|
+
startHour = 0,
|
|
5759
|
+
endHour = 24,
|
|
5760
|
+
slotDuration = 30,
|
|
5761
|
+
onEventClick,
|
|
5762
|
+
onEventChange,
|
|
5763
|
+
editable = false,
|
|
5764
|
+
minEventDuration,
|
|
5765
|
+
selectedEventId,
|
|
5766
|
+
locale = "en-US",
|
|
5767
|
+
className
|
|
5768
|
+
}) {
|
|
5769
|
+
const weekStart = useMemo10(
|
|
5770
|
+
() => startOfWeek(clampToMidnight(date), weekStartsOn),
|
|
5771
|
+
[date, weekStartsOn]
|
|
5772
|
+
);
|
|
5773
|
+
const days = useMemo10(
|
|
5774
|
+
() => Array.from({ length: 7 }, (_, i) => addDays(weekStart, i)),
|
|
5775
|
+
[weekStart]
|
|
5776
|
+
);
|
|
5777
|
+
const today = useMemo10(() => clampToMidnight(/* @__PURE__ */ new Date()), []);
|
|
5778
|
+
const now = useMemo10(() => /* @__PURE__ */ new Date(), []);
|
|
5779
|
+
const weekdayFormatter = useMemo10(
|
|
5780
|
+
() => new Intl.DateTimeFormat(locale, { weekday: "short" }),
|
|
5781
|
+
[locale]
|
|
5782
|
+
);
|
|
5783
|
+
const dayNumberFormatter = useMemo10(
|
|
5784
|
+
() => new Intl.DateTimeFormat(locale, { day: "numeric" }),
|
|
5785
|
+
[locale]
|
|
5786
|
+
);
|
|
5787
|
+
const monthDayFormatter = useMemo10(
|
|
5788
|
+
() => new Intl.DateTimeFormat(locale, { month: "short", day: "numeric" }),
|
|
5789
|
+
[locale]
|
|
5790
|
+
);
|
|
5791
|
+
const yearFormatter = useMemo10(
|
|
5792
|
+
() => new Intl.DateTimeFormat(locale, { year: "numeric" }),
|
|
5793
|
+
[locale]
|
|
5794
|
+
);
|
|
5795
|
+
const hourFormatter = useMemo10(
|
|
5796
|
+
() => new Intl.DateTimeFormat(locale, { hour: "numeric" }),
|
|
5797
|
+
[locale]
|
|
5798
|
+
);
|
|
5799
|
+
const weekdayLongFormatter = useMemo10(
|
|
5800
|
+
() => new Intl.DateTimeFormat(locale, { weekday: "long" }),
|
|
5801
|
+
[locale]
|
|
5802
|
+
);
|
|
5803
|
+
const weekEnd = days[6];
|
|
5804
|
+
const rangeLabelText = `${monthDayFormatter.format(weekStart)} \u2013 ${monthDayFormatter.format(weekEnd)}, ${yearFormatter.format(weekEnd)}`;
|
|
5805
|
+
const totalMinutes = (endHour - startHour) * 60;
|
|
5806
|
+
const slotsCount = Math.max(1, Math.ceil(totalMinutes / slotDuration));
|
|
5807
|
+
const totalHeightPx = slotsCount * SLOT_HEIGHT_PX;
|
|
5808
|
+
const resolvedMinEventDuration = minEventDuration ?? slotDuration;
|
|
5809
|
+
const hourMarks = useMemo10(() => {
|
|
5810
|
+
const marks = [];
|
|
5811
|
+
for (let hour = startHour; hour <= endHour; hour++) {
|
|
5812
|
+
const labelDate = new Date(2e3, 0, 1, hour === 24 ? 0 : hour, 0);
|
|
5813
|
+
marks.push({
|
|
5814
|
+
hour,
|
|
5815
|
+
label: hourFormatter.format(labelDate),
|
|
5816
|
+
top: (hour - startHour) * 60 / totalMinutes * 100
|
|
5817
|
+
});
|
|
5818
|
+
}
|
|
5819
|
+
return marks;
|
|
5820
|
+
}, [startHour, endHour, totalMinutes, hourFormatter]);
|
|
5821
|
+
const nowMinutes = now.getHours() * 60 + now.getMinutes();
|
|
5822
|
+
const showNowLine = nowMinutes >= startHour * 60 && nowMinutes < endHour * 60;
|
|
5823
|
+
const nowTop = (nowMinutes - startHour * 60) / totalMinutes * 100;
|
|
5824
|
+
const allDayEventsByDay = useMemo10(
|
|
5825
|
+
() => days.map(
|
|
5826
|
+
(day) => events.filter((event) => event.allDay && isSameDay(event.start, day))
|
|
5827
|
+
),
|
|
5828
|
+
[days, events]
|
|
5829
|
+
);
|
|
5830
|
+
const timedEventsByDay = useMemo10(
|
|
5831
|
+
() => days.map((day) => {
|
|
5832
|
+
const dayEvents = events.filter(
|
|
5833
|
+
(event) => !event.allDay && isSameDay(event.start, day)
|
|
5834
|
+
);
|
|
5835
|
+
const layout = layoutOverlappingEvents(
|
|
5836
|
+
dayEvents.map((event) => ({
|
|
5837
|
+
id: event.id,
|
|
5838
|
+
start: event.start,
|
|
5839
|
+
end: event.end
|
|
5840
|
+
}))
|
|
5841
|
+
);
|
|
5842
|
+
const layoutById = new Map(layout.map((l) => [l.id, l]));
|
|
5843
|
+
return dayEvents.map((event) => {
|
|
5844
|
+
const metrics = getVerticalMetrics(
|
|
5845
|
+
event.start,
|
|
5846
|
+
event.end,
|
|
5847
|
+
startHour,
|
|
5848
|
+
endHour
|
|
5849
|
+
);
|
|
5850
|
+
if (!metrics) return null;
|
|
5851
|
+
const placement = layoutById.get(event.id);
|
|
5852
|
+
return { event, metrics, placement };
|
|
5853
|
+
}).filter(
|
|
5854
|
+
(entry) => entry !== null
|
|
5855
|
+
);
|
|
5856
|
+
}),
|
|
5857
|
+
[days, events, startHour, endHour]
|
|
5858
|
+
);
|
|
5859
|
+
const [drag, setDrag] = useState21(null);
|
|
5860
|
+
const [announcement, setAnnouncement] = useState21("");
|
|
5861
|
+
const suppressClickRef = useRef12(false);
|
|
5862
|
+
const dayColumnRefs = useRef12([]);
|
|
5863
|
+
const announceMove = (event, start, end) => {
|
|
5864
|
+
setAnnouncement(
|
|
5865
|
+
`${event.title} moved to ${weekdayLongFormatter.format(start)}, ${formatEventTime(start, locale)} to ${formatEventTime(end, locale)}.`
|
|
5866
|
+
);
|
|
5867
|
+
};
|
|
5868
|
+
const announceResize = (event, end) => {
|
|
5869
|
+
setAnnouncement(
|
|
5870
|
+
`${event.title} resized to end at ${formatEventTime(end, locale)}.`
|
|
5871
|
+
);
|
|
5872
|
+
};
|
|
5873
|
+
const handleEventActivate = (event) => {
|
|
5874
|
+
if (suppressClickRef.current) {
|
|
5875
|
+
suppressClickRef.current = false;
|
|
5876
|
+
return;
|
|
5877
|
+
}
|
|
5878
|
+
onEventClick?.(event);
|
|
5879
|
+
};
|
|
5880
|
+
const handleMovePointerDown = (event, dayIndex) => (pointerEvent) => {
|
|
5881
|
+
if (!editable) return;
|
|
5882
|
+
pointerEvent.preventDefault();
|
|
5883
|
+
const target = pointerEvent.currentTarget;
|
|
5884
|
+
try {
|
|
5885
|
+
target.setPointerCapture(pointerEvent.pointerId);
|
|
5886
|
+
} catch {
|
|
5887
|
+
}
|
|
5888
|
+
target.focus();
|
|
5889
|
+
setDrag({
|
|
5890
|
+
kind: "move",
|
|
5891
|
+
event,
|
|
5892
|
+
pointerId: pointerEvent.pointerId,
|
|
5893
|
+
startClientX: pointerEvent.clientX,
|
|
5894
|
+
startClientY: pointerEvent.clientY,
|
|
5895
|
+
startDayIndex: dayIndex,
|
|
5896
|
+
currentDayIndex: dayIndex,
|
|
5897
|
+
currentStart: event.start,
|
|
5898
|
+
currentEnd: event.end,
|
|
5899
|
+
moved: false
|
|
5900
|
+
});
|
|
5901
|
+
};
|
|
5902
|
+
const handleResizePointerDown = (event, dayIndex) => (pointerEvent) => {
|
|
5903
|
+
if (!editable) return;
|
|
5904
|
+
pointerEvent.preventDefault();
|
|
5905
|
+
pointerEvent.stopPropagation();
|
|
5906
|
+
const target = pointerEvent.currentTarget;
|
|
5907
|
+
try {
|
|
5908
|
+
target.setPointerCapture(pointerEvent.pointerId);
|
|
5909
|
+
} catch {
|
|
5910
|
+
}
|
|
5911
|
+
setDrag({
|
|
5912
|
+
kind: "resize",
|
|
5913
|
+
event,
|
|
5914
|
+
pointerId: pointerEvent.pointerId,
|
|
5915
|
+
startClientX: pointerEvent.clientX,
|
|
5916
|
+
startClientY: pointerEvent.clientY,
|
|
5917
|
+
startDayIndex: dayIndex,
|
|
5918
|
+
currentDayIndex: dayIndex,
|
|
5919
|
+
currentStart: event.start,
|
|
5920
|
+
currentEnd: event.end,
|
|
5921
|
+
moved: false
|
|
5922
|
+
});
|
|
5923
|
+
};
|
|
5924
|
+
const handleDragPointerMove = (pointerEvent) => {
|
|
5925
|
+
if (!drag || pointerEvent.pointerId !== drag.pointerId) return;
|
|
5926
|
+
pointerEvent.stopPropagation();
|
|
5927
|
+
const deltaY = pointerEvent.clientY - drag.startClientY;
|
|
5928
|
+
if (drag.kind === "move") {
|
|
5929
|
+
const deltaX = pointerEvent.clientX - drag.startClientX;
|
|
5930
|
+
const columnWidth = dayColumnRefs.current[drag.startDayIndex]?.getBoundingClientRect().width ?? 0;
|
|
5931
|
+
const dayDelta = columnWidth > 0 ? Math.round(deltaX / columnWidth) : 0;
|
|
5932
|
+
const targetDayIndex = Math.min(6, Math.max(0, drag.startDayIndex + dayDelta));
|
|
5933
|
+
const targetDay = days[targetDayIndex];
|
|
5934
|
+
const { start, end } = computeMoveResult({
|
|
5935
|
+
originalStart: drag.event.start,
|
|
5936
|
+
originalEnd: drag.event.end,
|
|
5937
|
+
targetDay,
|
|
5938
|
+
deltaYPx: deltaY,
|
|
5939
|
+
slotDuration,
|
|
5940
|
+
startHour,
|
|
5941
|
+
endHour
|
|
5942
|
+
});
|
|
5943
|
+
const moved = targetDayIndex !== drag.startDayIndex || start.getTime() !== drag.event.start.getTime();
|
|
5944
|
+
setDrag({ ...drag, currentDayIndex: targetDayIndex, currentStart: start, currentEnd: end, moved });
|
|
5945
|
+
} else {
|
|
5946
|
+
const { end } = computeResizeResult({
|
|
5947
|
+
originalStart: drag.event.start,
|
|
5948
|
+
originalEnd: drag.event.end,
|
|
5949
|
+
deltaYPx: deltaY,
|
|
5950
|
+
slotDuration,
|
|
5951
|
+
minEventDuration: resolvedMinEventDuration,
|
|
5952
|
+
endHour
|
|
5953
|
+
});
|
|
5954
|
+
const moved = end.getTime() !== drag.event.end.getTime();
|
|
5955
|
+
setDrag({ ...drag, currentEnd: end, moved });
|
|
5956
|
+
}
|
|
5957
|
+
};
|
|
5958
|
+
const handleDragPointerUp = (pointerEvent) => {
|
|
5959
|
+
if (!drag || pointerEvent.pointerId !== drag.pointerId) return;
|
|
5960
|
+
pointerEvent.stopPropagation();
|
|
5961
|
+
const finished = drag;
|
|
5962
|
+
setDrag(null);
|
|
5963
|
+
if (finished.kind === "move") {
|
|
5964
|
+
if (!finished.moved) {
|
|
5965
|
+
suppressClickRef.current = true;
|
|
5966
|
+
onEventClick?.(finished.event);
|
|
5967
|
+
return;
|
|
5968
|
+
}
|
|
5969
|
+
onEventChange?.(finished.event, finished.currentStart, finished.currentEnd);
|
|
5970
|
+
announceMove(finished.event, finished.currentStart, finished.currentEnd);
|
|
5971
|
+
return;
|
|
5972
|
+
}
|
|
5973
|
+
if (!finished.moved) return;
|
|
5974
|
+
onEventChange?.(finished.event, finished.currentStart, finished.currentEnd);
|
|
5975
|
+
announceResize(finished.event, finished.currentEnd);
|
|
5976
|
+
};
|
|
5977
|
+
const handleDragPointerCancel = (pointerEvent) => {
|
|
5978
|
+
if (!drag || pointerEvent.pointerId !== drag.pointerId) return;
|
|
5979
|
+
pointerEvent.stopPropagation();
|
|
5980
|
+
setDrag(null);
|
|
5981
|
+
};
|
|
5982
|
+
const handleEventKeyDown = (keyboardEvent, event, dayIndex) => {
|
|
5983
|
+
if (!editable) return;
|
|
5984
|
+
if (keyboardEvent.shiftKey && (keyboardEvent.key === "ArrowDown" || keyboardEvent.key === "ArrowUp")) {
|
|
5985
|
+
keyboardEvent.preventDefault();
|
|
5986
|
+
const direction2 = keyboardEvent.key === "ArrowDown" ? 1 : -1;
|
|
5987
|
+
const { end } = computeResizeResult({
|
|
5988
|
+
originalStart: event.start,
|
|
5989
|
+
originalEnd: event.end,
|
|
5990
|
+
deltaYPx: direction2 * SLOT_HEIGHT_PX,
|
|
5991
|
+
slotDuration,
|
|
5992
|
+
minEventDuration: resolvedMinEventDuration,
|
|
5993
|
+
endHour
|
|
5994
|
+
});
|
|
5995
|
+
if (end.getTime() === event.end.getTime()) return;
|
|
5996
|
+
onEventChange?.(event, event.start, end);
|
|
5997
|
+
announceResize(event, end);
|
|
5998
|
+
return;
|
|
5999
|
+
}
|
|
6000
|
+
switch (keyboardEvent.key) {
|
|
6001
|
+
case "ArrowUp":
|
|
6002
|
+
case "ArrowDown": {
|
|
6003
|
+
keyboardEvent.preventDefault();
|
|
6004
|
+
const direction2 = keyboardEvent.key === "ArrowDown" ? 1 : -1;
|
|
6005
|
+
const { start, end } = computeMoveResult({
|
|
6006
|
+
originalStart: event.start,
|
|
6007
|
+
originalEnd: event.end,
|
|
6008
|
+
targetDay: days[dayIndex],
|
|
6009
|
+
deltaYPx: direction2 * SLOT_HEIGHT_PX,
|
|
6010
|
+
slotDuration,
|
|
6011
|
+
startHour,
|
|
6012
|
+
endHour
|
|
6013
|
+
});
|
|
6014
|
+
if (start.getTime() === event.start.getTime()) return;
|
|
6015
|
+
onEventChange?.(event, start, end);
|
|
6016
|
+
announceMove(event, start, end);
|
|
6017
|
+
break;
|
|
6018
|
+
}
|
|
6019
|
+
case "ArrowLeft":
|
|
6020
|
+
case "ArrowRight": {
|
|
6021
|
+
keyboardEvent.preventDefault();
|
|
6022
|
+
const direction2 = keyboardEvent.key === "ArrowRight" ? 1 : -1;
|
|
6023
|
+
const targetDayIndex = Math.min(6, Math.max(0, dayIndex + direction2));
|
|
6024
|
+
if (targetDayIndex === dayIndex) return;
|
|
6025
|
+
const { start, end } = computeMoveResult({
|
|
6026
|
+
originalStart: event.start,
|
|
6027
|
+
originalEnd: event.end,
|
|
6028
|
+
targetDay: days[targetDayIndex],
|
|
6029
|
+
deltaYPx: 0,
|
|
6030
|
+
slotDuration,
|
|
6031
|
+
startHour,
|
|
6032
|
+
endHour
|
|
6033
|
+
});
|
|
6034
|
+
onEventChange?.(event, start, end);
|
|
6035
|
+
announceMove(event, start, end);
|
|
6036
|
+
break;
|
|
6037
|
+
}
|
|
6038
|
+
default:
|
|
6039
|
+
return;
|
|
6040
|
+
}
|
|
6041
|
+
};
|
|
6042
|
+
const dragPreviewMetrics = drag && drag.kind === "move" ? getVerticalMetrics(drag.currentStart, drag.currentEnd, startHour, endHour) : null;
|
|
6043
|
+
return /* @__PURE__ */ jsxs34("div", { className: [root9, className].filter(Boolean).join(" "), children: [
|
|
6044
|
+
/* @__PURE__ */ jsx51(
|
|
6045
|
+
"div",
|
|
6046
|
+
{
|
|
6047
|
+
"aria-live": "polite",
|
|
6048
|
+
className: visuallyHidden,
|
|
6049
|
+
children: announcement
|
|
6050
|
+
}
|
|
6051
|
+
),
|
|
6052
|
+
/* @__PURE__ */ jsxs34("div", { className: header2, children: [
|
|
6053
|
+
/* @__PURE__ */ jsx51("span", { className: rangeLabel, children: rangeLabelText }),
|
|
6054
|
+
/* @__PURE__ */ jsxs34("div", { className: headerNav, children: [
|
|
6055
|
+
/* @__PURE__ */ jsx51(
|
|
6056
|
+
"button",
|
|
6057
|
+
{
|
|
6058
|
+
type: "button",
|
|
6059
|
+
className: navButton2,
|
|
6060
|
+
"aria-label": "Previous week",
|
|
6061
|
+
onClick: () => onDateChange?.(addDays(date, -7)),
|
|
6062
|
+
children: "\u2039"
|
|
6063
|
+
}
|
|
6064
|
+
),
|
|
6065
|
+
/* @__PURE__ */ jsx51(
|
|
6066
|
+
"button",
|
|
6067
|
+
{
|
|
6068
|
+
type: "button",
|
|
6069
|
+
className: todayButton,
|
|
6070
|
+
onClick: () => onDateChange?.(/* @__PURE__ */ new Date()),
|
|
6071
|
+
children: "Today"
|
|
6072
|
+
}
|
|
6073
|
+
),
|
|
6074
|
+
/* @__PURE__ */ jsx51(
|
|
6075
|
+
"button",
|
|
6076
|
+
{
|
|
6077
|
+
type: "button",
|
|
6078
|
+
className: navButton2,
|
|
6079
|
+
"aria-label": "Next week",
|
|
6080
|
+
onClick: () => onDateChange?.(addDays(date, 7)),
|
|
6081
|
+
children: "\u203A"
|
|
6082
|
+
}
|
|
6083
|
+
)
|
|
6084
|
+
] })
|
|
6085
|
+
] }),
|
|
6086
|
+
/* @__PURE__ */ jsxs34("div", { className: dayHeaderRow, children: [
|
|
6087
|
+
/* @__PURE__ */ jsx51("div", { className: dayHeaderGutter }),
|
|
6088
|
+
days.map((day) => {
|
|
6089
|
+
const isToday = isSameDay(day, today);
|
|
6090
|
+
return /* @__PURE__ */ jsxs34("div", { className: dayHeaderCell, "data-today": isToday || void 0, children: [
|
|
6091
|
+
/* @__PURE__ */ jsx51("span", { children: weekdayFormatter.format(day) }),
|
|
6092
|
+
/* @__PURE__ */ jsx51("span", { className: dayHeaderDateNumber, "data-today": isToday || void 0, children: dayNumberFormatter.format(day) })
|
|
6093
|
+
] }, day.toISOString());
|
|
6094
|
+
})
|
|
6095
|
+
] }),
|
|
6096
|
+
/* @__PURE__ */ jsxs34("div", { className: allDayRow, children: [
|
|
6097
|
+
/* @__PURE__ */ jsx51("div", { className: allDayGutter, children: "All day" }),
|
|
6098
|
+
days.map((day, dayIndex) => /* @__PURE__ */ jsx51("div", { className: allDayCell, children: allDayEventsByDay[dayIndex].map((event) => {
|
|
6099
|
+
const color = getEventColor(event.id, event.color);
|
|
6100
|
+
const selected = event.id === selectedEventId;
|
|
6101
|
+
return /* @__PURE__ */ jsx51(
|
|
6102
|
+
"button",
|
|
6103
|
+
{
|
|
6104
|
+
type: "button",
|
|
6105
|
+
className: allDayEventBlock,
|
|
6106
|
+
style: { background: color },
|
|
6107
|
+
"data-selected": selected || void 0,
|
|
6108
|
+
onClick: () => handleEventActivate(event),
|
|
6109
|
+
children: event.title
|
|
6110
|
+
},
|
|
6111
|
+
event.id
|
|
6112
|
+
);
|
|
6113
|
+
}) }, day.toISOString()))
|
|
6114
|
+
] }),
|
|
6115
|
+
/* @__PURE__ */ jsxs34("div", { className: scrollArea, children: [
|
|
6116
|
+
/* @__PURE__ */ jsx51("div", { className: timeGutter, style: { height: totalHeightPx }, children: hourMarks.map((mark) => /* @__PURE__ */ jsx51(
|
|
6117
|
+
"span",
|
|
6118
|
+
{
|
|
6119
|
+
className: hourLabel,
|
|
6120
|
+
style: { top: `${mark.top}%` },
|
|
6121
|
+
children: mark.label
|
|
6122
|
+
},
|
|
6123
|
+
mark.hour
|
|
6124
|
+
)) }),
|
|
6125
|
+
days.map((day, dayIndex) => {
|
|
6126
|
+
const isToday = isSameDay(day, today);
|
|
6127
|
+
return /* @__PURE__ */ jsxs34(
|
|
6128
|
+
"div",
|
|
6129
|
+
{
|
|
6130
|
+
ref: (el) => {
|
|
6131
|
+
dayColumnRefs.current[dayIndex] = el;
|
|
6132
|
+
},
|
|
6133
|
+
className: dayColumn,
|
|
6134
|
+
style: { height: totalHeightPx },
|
|
6135
|
+
children: [
|
|
6136
|
+
isToday && showNowLine ? /* @__PURE__ */ jsx51("div", { className: nowLine, style: { top: `${nowTop}%` }, children: /* @__PURE__ */ jsx51("span", { className: nowLineDot }) }) : null,
|
|
6137
|
+
timedEventsByDay[dayIndex].map(({ event, metrics, placement }) => {
|
|
6138
|
+
const color = getEventColor(event.id, event.color);
|
|
6139
|
+
const selected = event.id === selectedEventId;
|
|
6140
|
+
const isResizingThis = drag?.kind === "resize" && drag.event.id === event.id;
|
|
6141
|
+
const isDraggingThis = drag?.event.id === event.id;
|
|
6142
|
+
const displayMetrics = isResizingThis ? getVerticalMetrics(event.start, drag.currentEnd, startHour, endHour) ?? metrics : metrics;
|
|
6143
|
+
const displayEnd = isResizingThis ? drag.currentEnd : event.end;
|
|
6144
|
+
const width = 100 / placement.columnCount;
|
|
6145
|
+
const left = placement.columnIndex * width;
|
|
6146
|
+
const showTime = displayMetrics.height > 6;
|
|
6147
|
+
return /* @__PURE__ */ jsxs34(
|
|
6148
|
+
"button",
|
|
6149
|
+
{
|
|
6150
|
+
type: "button",
|
|
6151
|
+
className: eventBlock,
|
|
6152
|
+
"data-selected": selected || void 0,
|
|
6153
|
+
"data-editable": editable || void 0,
|
|
6154
|
+
"data-dragging": isDraggingThis || void 0,
|
|
6155
|
+
style: {
|
|
6156
|
+
top: `${displayMetrics.top}%`,
|
|
6157
|
+
height: `${displayMetrics.height}%`,
|
|
6158
|
+
left: `${left}%`,
|
|
6159
|
+
width: `${width}%`,
|
|
6160
|
+
background: color
|
|
6161
|
+
},
|
|
6162
|
+
onClick: () => handleEventActivate(event),
|
|
6163
|
+
onPointerDown: editable ? handleMovePointerDown(event, dayIndex) : void 0,
|
|
6164
|
+
onPointerMove: editable ? handleDragPointerMove : void 0,
|
|
6165
|
+
onPointerUp: editable ? handleDragPointerUp : void 0,
|
|
6166
|
+
onPointerCancel: editable ? handleDragPointerCancel : void 0,
|
|
6167
|
+
onKeyDown: editable ? (e) => handleEventKeyDown(e, event, dayIndex) : void 0,
|
|
6168
|
+
children: [
|
|
6169
|
+
/* @__PURE__ */ jsx51("span", { className: eventTitle, children: event.title }),
|
|
6170
|
+
showTime ? /* @__PURE__ */ jsxs34("span", { className: eventTime, children: [
|
|
6171
|
+
formatEventTime(event.start, locale),
|
|
6172
|
+
" \u2013",
|
|
6173
|
+
" ",
|
|
6174
|
+
formatEventTime(displayEnd, locale)
|
|
6175
|
+
] }) : null,
|
|
6176
|
+
editable ? /* @__PURE__ */ jsx51(
|
|
6177
|
+
"span",
|
|
6178
|
+
{
|
|
6179
|
+
className: resizeHandle2,
|
|
6180
|
+
onPointerDown: handleResizePointerDown(event, dayIndex),
|
|
6181
|
+
onPointerMove: handleDragPointerMove,
|
|
6182
|
+
onPointerUp: handleDragPointerUp,
|
|
6183
|
+
onPointerCancel: handleDragPointerCancel
|
|
6184
|
+
}
|
|
6185
|
+
) : null
|
|
6186
|
+
]
|
|
6187
|
+
},
|
|
6188
|
+
event.id
|
|
6189
|
+
);
|
|
6190
|
+
}),
|
|
6191
|
+
drag && drag.kind === "move" && drag.currentDayIndex === dayIndex && dragPreviewMetrics ? /* @__PURE__ */ jsxs34(
|
|
6192
|
+
"div",
|
|
6193
|
+
{
|
|
6194
|
+
className: dragPreview,
|
|
6195
|
+
style: {
|
|
6196
|
+
top: `${dragPreviewMetrics.top}%`,
|
|
6197
|
+
height: `${dragPreviewMetrics.height}%`,
|
|
6198
|
+
left: 0,
|
|
6199
|
+
width: "100%"
|
|
6200
|
+
},
|
|
6201
|
+
children: [
|
|
6202
|
+
/* @__PURE__ */ jsx51("span", { className: dragPreviewLabel, children: drag.event.title }),
|
|
6203
|
+
/* @__PURE__ */ jsxs34("span", { className: dragPreviewLabel, children: [
|
|
6204
|
+
formatEventTime(drag.currentStart, locale),
|
|
6205
|
+
" \u2013",
|
|
6206
|
+
" ",
|
|
6207
|
+
formatEventTime(drag.currentEnd, locale)
|
|
6208
|
+
] })
|
|
6209
|
+
]
|
|
6210
|
+
}
|
|
6211
|
+
) : null
|
|
6212
|
+
]
|
|
6213
|
+
},
|
|
6214
|
+
day.toISOString()
|
|
6215
|
+
);
|
|
6216
|
+
})
|
|
6217
|
+
] })
|
|
6218
|
+
] });
|
|
6219
|
+
}
|
|
6220
|
+
|
|
4216
6221
|
// src/index.ts
|
|
4217
|
-
import { vars as
|
|
6222
|
+
import { vars as vars13, defaultThemeClass, defaultThemeVars } from "@vesture/tokens";
|
|
4218
6223
|
export {
|
|
4219
6224
|
Accordion2 as Accordion,
|
|
4220
6225
|
AccordionContent,
|
|
4221
6226
|
AccordionItem,
|
|
4222
6227
|
AccordionTrigger,
|
|
4223
6228
|
Alert,
|
|
6229
|
+
AreaChart,
|
|
4224
6230
|
Avatar,
|
|
4225
6231
|
Badge,
|
|
6232
|
+
BarChart,
|
|
4226
6233
|
Breadcrumbs2 as Breadcrumbs,
|
|
4227
6234
|
BreadcrumbsItem,
|
|
4228
6235
|
Button,
|
|
@@ -4238,13 +6245,20 @@ export {
|
|
|
4238
6245
|
DropdownMenu2 as DropdownMenu,
|
|
4239
6246
|
DropdownMenuItem,
|
|
4240
6247
|
Input,
|
|
6248
|
+
InteractiveAreaChart,
|
|
6249
|
+
InteractiveBarChart,
|
|
6250
|
+
InteractiveLineChart,
|
|
6251
|
+
InteractivePieChart,
|
|
4241
6252
|
Label,
|
|
6253
|
+
LineChart,
|
|
4242
6254
|
Modal,
|
|
4243
6255
|
NumberInput,
|
|
4244
6256
|
Pagination,
|
|
6257
|
+
PieChart,
|
|
4245
6258
|
Popover,
|
|
4246
6259
|
Progress,
|
|
4247
6260
|
Radio,
|
|
6261
|
+
Scheduler,
|
|
4248
6262
|
Select,
|
|
4249
6263
|
Slider,
|
|
4250
6264
|
Spinner,
|
|
@@ -4262,6 +6276,6 @@ export {
|
|
|
4262
6276
|
defaultThemeVars,
|
|
4263
6277
|
useCommandPaletteShortcut,
|
|
4264
6278
|
useToast,
|
|
4265
|
-
|
|
6279
|
+
vars13 as vars
|
|
4266
6280
|
};
|
|
4267
6281
|
//# sourceMappingURL=index.js.map
|