@epoch32/visage 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/api/index.js +55 -4085
  2. package/dist/charts/index.js +48 -2806
  3. package/dist/devtools/index.js +18 -4771
  4. package/dist/dom/index.js +32 -1639
  5. package/dist/form/index.js +13 -1498
  6. package/dist/index-061jf06a.js +848 -0
  7. package/dist/index-0madxn60.js +442 -0
  8. package/dist/index-1xtrtz1t.js +256 -0
  9. package/dist/index-2zz0g2n2.js +212 -0
  10. package/dist/index-5s255b3w.js +303 -0
  11. package/dist/index-6kfe1nr4.js +1179 -0
  12. package/dist/index-8czhpea8.js +338 -0
  13. package/dist/index-8x8xz80v.js +727 -0
  14. package/dist/index-921pn75b.js +0 -0
  15. package/dist/index-965ryh36.js +537 -0
  16. package/dist/index-9fvarkrx.js +98 -0
  17. package/dist/index-a4xns6cc.js +219 -0
  18. package/dist/index-b5wc752a.js +1696 -0
  19. package/dist/index-df5e614s.js +334 -0
  20. package/dist/index-dyvgtp43.js +1094 -0
  21. package/dist/index-grhdtcb5.js +234 -0
  22. package/dist/index-h6tjqk6e.js +158 -0
  23. package/dist/index-js199er4.js +101 -0
  24. package/dist/index-x2rs3vab.js +124 -0
  25. package/dist/index-y9bq7h9g.js +1162 -0
  26. package/dist/index-zr6cvset.js +2092 -0
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +458 -11920
  29. package/dist/jsx-runtime/index.js +13 -1719
  30. package/dist/query/index.js +47 -2505
  31. package/dist/router/index.js +25 -1945
  32. package/dist/rpc/index.js +39 -3567
  33. package/dist/server/index.js +11 -1256
  34. package/dist/signals/index.js +52 -1160
  35. package/dist/style/index.js +77 -2429
  36. package/dist/template/index.js +7 -1232
  37. package/dist/ui/index.d.ts +1 -1
  38. package/dist/ui/index.js +150 -4249
  39. package/dist/ui/tabs.d.ts +23 -1
  40. package/dist/virtual/index.js +12 -2044
  41. package/dist/vite/index.js +5 -744
  42. package/package.json +2 -2
  43. package/src/dom/render.ts +20 -7
  44. package/src/index.ts +2 -0
  45. package/src/signals/computed.ts +19 -12
  46. package/src/signals/effect.ts +7 -7
  47. package/src/signals/signal.ts +16 -12
  48. package/src/signals/system.ts +50 -21
  49. package/src/ui/index.ts +2 -0
  50. package/src/ui/tabs.tsx +211 -10
  51. package/src/ui/utils.ts +1 -3
@@ -1,2808 +1,50 @@
1
- // src/signals/types.ts
2
- var SubscriberState;
3
- ((SubscriberState) => {
4
- SubscriberState[SubscriberState["CLEAN"] = 0] = "CLEAN";
5
- SubscriberState[SubscriberState["CHECK_DIRTY"] = 1] = "CHECK_DIRTY";
6
- SubscriberState[SubscriberState["DIRTY"] = 2] = "DIRTY";
7
- SubscriberState[SubscriberState["DISPOSED"] = 3] = "DISPOSED";
8
- })(SubscriberState ||= {});
9
- var SIGNAL_BRAND = Symbol("visage.signal");
10
- var COMPUTED_BRAND = Symbol("visage.computed");
11
- function isSignal(value) {
12
- return typeof value === "function" && ((SIGNAL_BRAND in value) || (COMPUTED_BRAND in value));
13
- }
14
-
15
- // src/signals/system.ts
16
- var currentSubscriber = null;
17
- var currentScope = null;
18
- var batchDepth = 0;
19
- var pendingEffects = new Set;
20
- var warnedCyclicSubscribers = new WeakSet;
21
- var isFlushing = false;
22
- function setCurrentSubscriber(sub) {
23
- currentSubscriber = sub;
24
- }
25
- function setCurrentScope(scope) {
26
- currentScope = scope;
27
- }
28
- function getCurrentScope() {
29
- return currentScope;
30
- }
31
- function addPendingEffect(eff) {
32
- pendingEffects.add(eff);
33
- }
34
- function removePendingEffect(eff) {
35
- pendingEffects.delete(eff);
36
- }
37
- var MAX_FLUSH_COUNT = 100;
38
- function flushEffects() {
39
- if (isFlushing || batchDepth > 0)
40
- return;
41
- isFlushing = true;
42
- let iterations = 0;
43
- try {
44
- while (pendingEffects.size > 0) {
45
- if (++iterations > MAX_FLUSH_COUNT) {
46
- pendingEffects.clear();
47
- throw new Error(`[Visage Reactivity] Maximum update depth exceeded (${MAX_FLUSH_COUNT} cycles). ` + `An effect continuously triggered state mutations (infinite loop detected). ` + `Ensure effects that modify signals do not unconditionally depend on them, or use untrack() to read state.`);
48
- }
49
- const effectsToRun = Array.from(pendingEffects);
50
- pendingEffects.clear();
51
- for (const eff of effectsToRun) {
52
- if (eff.state === 2 /* DIRTY */ || eff.state === 1 /* CHECK_DIRTY */) {
53
- eff.run();
54
- }
55
- }
56
- }
57
- } finally {
58
- isFlushing = false;
59
- }
60
- }
61
- function batch(fn) {
62
- batchDepth++;
63
- try {
64
- return fn();
65
- } finally {
66
- batchDepth--;
67
- if (batchDepth === 0) {
68
- flushEffects();
69
- }
70
- }
71
- }
72
- function untrack(fn) {
73
- const prev = currentSubscriber;
74
- currentSubscriber = null;
75
- try {
76
- return fn();
77
- } finally {
78
- currentSubscriber = prev;
79
- }
80
- }
81
-
82
- // src/signals/computed.ts
83
- class Computed {
84
- [COMPUTED_BRAND] = true;
85
- _fn;
86
- _value;
87
- _subscribers = new Set;
88
- sources = new Set;
89
- sourceVersions = new Map;
90
- state = 2 /* DIRTY */;
91
- scope;
92
- version = 0;
93
- constructor(fn) {
94
- this._fn = fn;
95
- this.scope = currentScope;
96
- if (currentScope) {
97
- currentScope.addSubscriber(this);
98
- }
99
- }
100
- get() {
101
- if (this.state === 3 /* DISPOSED */) {
102
- return this._fn();
103
- }
104
- if (currentSubscriber !== null && currentSubscriber.state !== 3 /* DISPOSED */) {
105
- this._subscribers.add(currentSubscriber);
106
- currentSubscriber.sources.add(this);
107
- currentSubscriber.sourceVersions.set(this, this.version);
108
- }
109
- if (this.state === 2 /* DIRTY */ || this.state === 1 /* CHECK_DIRTY */) {
110
- this.updateIfNecessary();
111
- }
112
- return this._value;
113
- }
114
- get value() {
115
- return this.get();
116
- }
117
- removeSubscriber(sub) {
118
- this._subscribers.delete(sub);
119
- }
120
- markDirty(targetState = 1 /* CHECK_DIRTY */) {
121
- if (this.state >= targetState || this.state === 3 /* DISPOSED */) {
122
- return;
123
- }
124
- this.state = targetState;
125
- for (const sub of this._subscribers) {
126
- sub.markDirty(1 /* CHECK_DIRTY */);
127
- }
128
- }
129
- updateIfNecessary() {
130
- if (this.state === 2 /* DIRTY */) {
131
- const prev = this._value;
132
- this.recompute();
133
- return !Object.is(prev, this._value);
134
- }
135
- if (this.state === 1 /* CHECK_DIRTY */) {
136
- let anyChanged = false;
137
- for (const source of this.sources) {
138
- if (source instanceof Computed) {
139
- source.updateIfNecessary();
140
- }
141
- const lastVersion = this.sourceVersions.get(source);
142
- if (lastVersion !== undefined && lastVersion !== source.version) {
143
- anyChanged = true;
144
- }
145
- }
146
- if (anyChanged) {
147
- const prev = this._value;
148
- this.recompute();
149
- return !Object.is(prev, this._value);
150
- }
151
- this.state = 0 /* CLEAN */;
152
- return false;
153
- }
154
- return false;
155
- }
156
- recompute() {
157
- this.cleanupSources();
158
- const prevSubscriber = currentSubscriber;
159
- setCurrentSubscriber(this);
160
- const prevScope = currentScope;
161
- setCurrentScope(this.scope);
162
- try {
163
- const next = this._fn();
164
- if (!Object.is(this._value, next)) {
165
- this._value = next;
166
- this.version++;
167
- }
168
- this.state = 0 /* CLEAN */;
169
- } finally {
170
- setCurrentSubscriber(prevSubscriber);
171
- setCurrentScope(prevScope);
172
- }
173
- }
174
- cleanupSources() {
175
- for (const source of this.sources) {
176
- source.removeSubscriber(this);
177
- }
178
- this.sources.clear();
179
- this.sourceVersions.clear();
180
- }
181
- dispose() {
182
- if (this.state === 3 /* DISPOSED */)
183
- return;
184
- this.state = 3 /* DISPOSED */;
185
- this.cleanupSources();
186
- this._subscribers.clear();
187
- }
188
- }
189
- function computed(fn, options) {
190
- const isInternal = options?.internal ?? false;
191
- const customName = options?.name;
192
- const c = new Computed(fn);
193
- const accessor = () => c.get();
194
- Object.defineProperties(accessor, {
195
- [COMPUTED_BRAND]: { value: true },
196
- get: { value: () => c.get() },
197
- value: { get: () => c.get() }
198
- });
199
- if (!isInternal && typeof window !== "undefined" && window.__VISAGE_DEVTOOLS__) {
200
- const devtools = window.__VISAGE_DEVTOOLS__;
201
- const sigId = devtools.registerSignal({
202
- name: customName,
203
- type: "computed",
204
- getValue: () => c.get(),
205
- version: () => c.version,
206
- subscribersCount: () => c._subscribers?.size ?? 0,
207
- dependencies: () => Array.from(c.sources ?? []).map((src) => src._devId).filter(Boolean),
208
- dependents: () => Array.from(c._subscribers ?? []).map((sub) => sub._devId).filter(Boolean)
209
- });
210
- c._devId = sigId;
211
- if (currentScope) {
212
- currentScope.addCleanup(() => {
213
- devtools.unregisterSignal(sigId);
214
- });
215
- }
216
- }
217
- return accessor;
218
- }
219
- var createMemo = computed;
220
- // src/style/cx.ts
221
- function hasReactiveClass(val) {
222
- if (typeof val === "function")
223
- return true;
224
- if (Array.isArray(val)) {
225
- for (let i = 0;i < val.length; i++) {
226
- if (hasReactiveClass(val[i]))
227
- return true;
228
- }
229
- return false;
230
- }
231
- if (typeof val === "object" && val !== null) {
232
- for (const k in val) {
233
- if (typeof val[k] === "function")
234
- return true;
235
- }
236
- }
237
- return false;
238
- }
239
- function normalizeClass(val) {
240
- if (!val)
241
- return "";
242
- if (typeof val === "function")
243
- return normalizeClass(val());
244
- if (typeof val === "string")
245
- return val.trim();
246
- if (typeof val === "number")
247
- return String(val);
248
- if (Array.isArray(val)) {
249
- let res = "";
250
- for (let i = 0;i < val.length; i++) {
251
- const item = typeof val[i] === "function" ? val[i]() : val[i];
252
- const itemStr = normalizeClass(item);
253
- if (itemStr) {
254
- res = res ? `${res} ${itemStr}` : itemStr;
255
- }
256
- }
257
- return res;
258
- }
259
- if (typeof val === "object") {
260
- let res = "";
261
- for (const key in val) {
262
- const condition = typeof val[key] === "function" ? val[key]() : val[key];
263
- if (condition) {
264
- res = res ? `${res} ${key}` : key;
265
- }
266
- }
267
- return res;
268
- }
269
- return "";
270
- }
271
- function cx(...args) {
272
- return normalizeClass(args);
273
- }
274
-
275
- // src/style/scale.ts
276
- var UNITLESS_PROPERTIES = new Set([
277
- "animationIterationCount",
278
- "aspectRatio",
279
- "borderImageSlice",
280
- "columnCount",
281
- "columns",
282
- "flex",
283
- "flexGrow",
284
- "flexShrink",
285
- "flexOrder",
286
- "fontWeight",
287
- "lineHeight",
288
- "opacity",
289
- "order",
290
- "orphans",
291
- "scale",
292
- "tabSize",
293
- "widows",
294
- "zIndex",
295
- "zoom",
296
- "fillOpacity",
297
- "strokeOpacity"
298
- ]);
299
- var DIMENSION_KEYWORDS = {
300
- screen: "100dvh",
301
- "screen-h": "100dvh",
302
- "screen-w": "100dvw",
303
- full: "100%",
304
- half: "50%",
305
- third: "33.333333%",
306
- "two-thirds": "66.666667%",
307
- quarter: "25%",
308
- "three-quarters": "75%",
309
- auto: "auto",
310
- min: "min-content",
311
- max: "max-content",
312
- fit: "fit-content"
313
- };
314
- function space(val) {
315
- if (val === undefined || val === null || val === "")
316
- return "";
317
- if (typeof val === "number") {
318
- if (val === 0)
319
- return "0px";
320
- return `${val * 4}px`;
321
- }
322
- const str = String(val).trim();
323
- if (str in DIMENSION_KEYWORDS) {
324
- return DIMENSION_KEYWORDS[str];
325
- }
326
- return str;
327
- }
328
- function resolveDimension(val) {
329
- if (val === undefined || val === null || val === "")
330
- return "";
331
- if (typeof val === "number") {
332
- if (val === 0)
333
- return "0px";
334
- if (val > 48)
335
- return `${val}px`;
336
- return `${val * 4}px`;
337
- }
338
- const str = String(val).trim();
339
- if (str in DIMENSION_KEYWORDS) {
340
- return DIMENSION_KEYWORDS[str];
341
- }
342
- return str;
343
- }
344
- function px(val) {
345
- return `${val}px`;
346
- }
347
- function rem(val) {
348
- return `${val}rem`;
349
- }
350
- function em(val) {
351
- return `${val}em`;
352
- }
353
- function fluid(minPx, maxPx, options) {
354
- const minVw = options?.minVw ?? 375;
355
- const maxVw = options?.maxVw ?? 1280;
356
- const slope = (maxPx - minPx) / (maxVw - minVw);
357
- const yIntercept = -minVw * slope + minPx;
358
- const slopeVw = slope * 100;
359
- const preferred = `${yIntercept.toFixed(2)}px + ${slopeVw.toFixed(2)}vw`;
360
- const min = Math.min(minPx, maxPx);
361
- const max = Math.max(minPx, maxPx);
362
- return `clamp(${min}px, ${preferred}, ${max}px)`;
363
- }
364
- var SHADOW_PRESETS = {
365
- none: "none",
366
- sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
367
- md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
368
- lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
369
- xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)",
370
- soft: "0 8px 30px rgba(0, 0, 0, 0.06)",
371
- glow: "0 0 24px rgba(168, 85, 247, 0.35)",
372
- inner: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)"
373
- };
374
- function shadow(variant) {
375
- if (variant in SHADOW_PRESETS) {
376
- return SHADOW_PRESETS[variant];
377
- }
378
- return variant;
379
- }
380
- var RADIUS_PRESETS = {
381
- none: "0px",
382
- sm: "4px",
383
- md: "8px",
384
- lg: "12px",
385
- xl: "16px",
386
- "2xl": "20px",
387
- "3xl": "24px",
388
- full: "9999px"
389
- };
390
- function radius(variant) {
391
- if (typeof variant === "number") {
392
- return `${variant}px`;
393
- }
394
- if (variant in RADIUS_PRESETS) {
395
- return RADIUS_PRESETS[variant];
396
- }
397
- return String(variant);
398
- }
399
- function glass(options = {}) {
400
- const blurVal = typeof options.blur === "number" ? `${options.blur}px` : options.blur ?? "20px";
401
- const tintVal = options.tint ?? "rgba(255, 255, 255, 0.65)";
402
- const borderVal = options.border ?? "1px solid rgba(255, 255, 255, 0.75)";
403
- return {
404
- backdropFilter: `blur(${blurVal})`,
405
- WebkitBackdropFilter: `blur(${blurVal})`,
406
- backgroundColor: tintVal,
407
- border: borderVal
408
- };
409
- }
410
- function formatStyleProp(prop, val) {
411
- if (val === null || val === undefined || val === "")
412
- return "";
413
- if (typeof val === "number") {
414
- if (val === 0 || UNITLESS_PROPERTIES.has(prop)) {
415
- return String(val);
416
- }
417
- return `${val}px`;
418
- }
419
- const str = String(val).trim();
420
- if (str in DIMENSION_KEYWORDS) {
421
- const lowerProp = prop.toLowerCase();
422
- if (str === "screen") {
423
- if (lowerProp.includes("width"))
424
- return "100dvw";
425
- return "100dvh";
426
- }
427
- return DIMENSION_KEYWORDS[str];
428
- }
429
- return str;
430
- }
431
-
432
- // src/dom/render.ts
433
- function isReactive(value) {
434
- return isSignal(value) || typeof value === "function";
435
- }
436
- function resolveValue(val) {
437
- if (typeof val === "function") {
438
- return val();
439
- }
440
- return val;
441
- }
442
- function render(fn, container) {
443
- return createRoot((dispose) => {
444
- container.textContent = "";
445
- const node = insertChild(container, fn());
446
- onCleanup(() => {
447
- if (node && node instanceof Node && node.parentNode === container) {
448
- container.removeChild(node);
449
- }
450
- });
451
- return dispose;
452
- });
453
- }
454
- function setAttribute(el, key, value) {
455
- if (key.startsWith("on") && typeof value === "function") {
456
- const eventName = key.startsWith("onCapture") ? key.slice(9).toLowerCase() : key.slice(2).toLowerCase();
457
- const useCapture = key.startsWith("onCapture");
458
- el.addEventListener(eventName, value, useCapture);
459
- onCleanup(() => {
460
- el.removeEventListener(eventName, value, useCapture);
461
- });
462
- return;
463
- }
464
- if (key === "ref" && typeof value === "function") {
465
- value(el);
466
- return;
467
- }
468
- if (key === "class" || key === "className") {
469
- if (hasReactiveClass(value)) {
470
- effect(() => {
471
- const cls = normalizeClass(value);
472
- if (cls)
473
- el.setAttribute("class", cls);
474
- else
475
- el.removeAttribute("class");
476
- });
477
- } else {
478
- const cls = normalizeClass(value);
479
- if (cls)
480
- el.setAttribute("class", cls);
481
- else
482
- el.removeAttribute("class");
483
- }
484
- return;
485
- }
486
- if (isReactive(value)) {
487
- effect(() => {
488
- const resolved = resolveValue(value);
489
- applyProp(el, key, resolved);
490
- });
491
- } else {
492
- applyProp(el, key, value);
493
- }
494
- }
495
- function setStyleProperty(el, prop, val) {
496
- const formatted = formatStyleProp(prop, val);
497
- if (prop.startsWith("--") || prop.includes("-")) {
498
- if (formatted === "") {
499
- el.style.removeProperty(prop);
500
- } else {
501
- el.style.setProperty(prop, formatted);
502
- }
503
- } else {
504
- el.style[prop] = formatted;
505
- }
506
- }
507
- function applyProp(el, key, value) {
508
- if (value === null || value === undefined || value === false && !key.startsWith("aria-") && !key.startsWith("data-")) {
509
- if (key === "className" || key === "class") {
510
- el.removeAttribute("class");
511
- } else if (key === "style" && typeof value === "string") {
512
- el.removeAttribute("style");
513
- } else if (key in el && !(el instanceof SVGElement)) {
514
- try {
515
- el[key] = typeof el[key] === "boolean" ? false : "";
516
- } catch {
517
- el.removeAttribute(key);
518
- }
519
- } else {
520
- el.removeAttribute(key);
521
- }
522
- return;
523
- }
524
- if (key === "className" || key === "class") {
525
- const cls = normalizeClass(value);
526
- if (cls) {
527
- el.setAttribute("class", cls);
528
- } else {
529
- el.removeAttribute("class");
530
- }
531
- } else if (key === "style") {
532
- if (typeof value === "string") {
533
- el.setAttribute("style", value);
534
- } else if (typeof value === "object" && value !== null) {
535
- for (const styleKey in value) {
536
- const styleVal = value[styleKey];
537
- if (isReactive(styleVal)) {
538
- effect(() => {
539
- setStyleProperty(el, styleKey, resolveValue(styleVal));
540
- });
541
- } else {
542
- setStyleProperty(el, styleKey, styleVal);
543
- }
544
- }
545
- }
546
- } else if (key === "dangerouslySetInnerHTML" && value && typeof value.__html === "string") {
547
- el.innerHTML = value.__html;
548
- } else if (key in el && !(el instanceof SVGElement) && key !== "list" && key !== "form") {
549
- try {
550
- el[key] = value;
551
- } catch {
552
- el.setAttribute(key, String(value));
553
- }
554
- } else {
555
- if (key.startsWith("aria-") || key.startsWith("data-")) {
556
- el.setAttribute(key, String(value));
557
- } else if (value === true) {
558
- el.setAttribute(key, "");
559
- } else {
560
- el.setAttribute(key, String(value));
561
- }
562
- }
563
- }
564
- function insertChild(parent, child, before = null) {
565
- if (child === null || child === undefined || child === false || child === true) {
566
- return null;
567
- }
568
- if (child instanceof Node) {
569
- parent.insertBefore(child, before);
570
- return child;
571
- }
572
- if (Array.isArray(child)) {
573
- const fragment = document.createDocumentFragment();
574
- for (const item of child) {
575
- insertChild(fragment, item);
576
- }
577
- parent.insertBefore(fragment, before);
578
- return fragment;
579
- }
580
- if (isReactive(child)) {
581
- const marker = document.createTextNode("");
582
- parent.insertBefore(marker, before);
583
- let childScope = null;
584
- let currentNodes = [];
585
- effect(() => {
586
- const resolved = resolveValue(child);
587
- if ((typeof resolved === "string" || typeof resolved === "number") && currentNodes.length === 1 && currentNodes[0].nodeType === Node.TEXT_NODE) {
588
- currentNodes[0].data = String(resolved);
589
- return;
590
- }
591
- if (childScope) {
592
- childScope.dispose();
593
- }
594
- childScope = new Scope(getActiveScope());
595
- runInScope(childScope, () => {
596
- for (const node of currentNodes) {
597
- if (node.parentNode) {
598
- node.parentNode.removeChild(node);
599
- }
600
- }
601
- currentNodes = [];
602
- if (resolved === null || resolved === undefined || resolved === false) {
603
- return;
604
- }
605
- const frag = document.createDocumentFragment();
606
- if (typeof resolved === "string" || typeof resolved === "number" || typeof resolved === "boolean") {
607
- frag.appendChild(document.createTextNode(String(resolved)));
608
- } else {
609
- insertChild(frag, resolved);
610
- }
611
- currentNodes = Array.from(frag.childNodes);
612
- if (marker.parentNode) {
613
- marker.parentNode.insertBefore(frag, marker);
614
- }
615
- });
616
- });
617
- onCleanup(() => {
618
- if (childScope) {
619
- childScope.dispose();
620
- }
621
- for (const node of currentNodes) {
622
- if (node.parentNode) {
623
- node.parentNode.removeChild(node);
624
- }
625
- }
626
- if (marker.parentNode) {
627
- marker.parentNode.removeChild(marker);
628
- }
629
- });
630
- return marker;
631
- }
632
- const textNode = document.createTextNode(String(child));
633
- parent.insertBefore(textNode, before);
634
- return textNode;
635
- }
636
-
637
- // src/signals/scope.ts
638
- class Scope {
639
- subscribers = new Set;
640
- cleanups = [];
641
- parent = null;
642
- isDisposed = false;
643
- context;
644
- constructor(parent = currentScope) {
645
- this.parent = parent;
646
- if (parent && !parent.isDisposed) {
647
- parent.cleanups.push(() => this.dispose());
648
- if (parent.context) {
649
- this.context = new Map(parent.context);
650
- }
651
- }
652
- }
653
- addSubscriber(sub) {
654
- if (this.isDisposed)
655
- return;
656
- this.subscribers.add(sub);
657
- }
658
- addCleanup(fn) {
659
- if (this.isDisposed) {
660
- fn();
661
- return;
662
- }
663
- this.cleanups.push(fn);
664
- }
665
- dispose() {
666
- if (this.isDisposed)
667
- return;
668
- this.isDisposed = true;
669
- for (const sub of this.subscribers) {
670
- sub.dispose();
671
- }
672
- this.subscribers.clear();
673
- for (let i = this.cleanups.length - 1;i >= 0; i--) {
674
- try {
675
- this.cleanups[i]();
676
- } catch (err) {
677
- console.error("Error during cleanup:", err);
678
- }
679
- }
680
- this.cleanups = [];
681
- }
682
- }
683
- function onCleanup(fn) {
684
- if (currentSubscriber && "addCleanup" in currentSubscriber) {
685
- currentSubscriber.addCleanup(fn);
686
- } else if (currentScope) {
687
- currentScope.addCleanup(fn);
688
- }
689
- }
690
- function createRoot(fn) {
691
- const prevScope = currentScope;
692
- const scope = new Scope(null);
693
- setCurrentScope(scope);
694
- try {
695
- return fn(() => scope.dispose());
696
- } finally {
697
- setCurrentScope(prevScope);
698
- }
699
- }
700
- function runInScope(scope, fn) {
701
- const prevScope = currentScope;
702
- setCurrentScope(scope);
703
- try {
704
- return fn();
705
- } finally {
706
- setCurrentScope(prevScope);
707
- }
708
- }
709
- function getActiveScope() {
710
- return getCurrentScope();
711
- }
712
-
713
- // src/signals/context.ts
714
- function createContext(defaultValue) {
715
- const id = Symbol("visage.context");
716
- const context = {
717
- id,
718
- defaultValue,
719
- Provider: (props) => {
720
- const parentScope = getActiveScope();
721
- const scope = new Scope(parentScope);
722
- if (!scope.context) {
723
- scope.context = new Map(parentScope?.context);
724
- }
725
- scope.context.set(id, props.value);
726
- return runInScope(scope, () => {
727
- const content = typeof props.children === "function" ? props.children() : props.children;
728
- if (typeof document !== "undefined") {
729
- const frag = document.createDocumentFragment();
730
- insertChild(frag, content);
731
- return frag;
732
- }
733
- return content;
734
- });
735
- }
736
- };
737
- return context;
738
- }
739
- function useContext(context) {
740
- let scope = getActiveScope();
741
- while (scope) {
742
- if (scope.context?.has(context.id)) {
743
- return scope.context.get(context.id);
744
- }
745
- scope = scope.parent;
746
- }
747
- return context.defaultValue;
748
- }
749
- // src/signals/effect.ts
750
- class Effect {
751
- _fn;
752
- sources = new Set;
753
- sourceVersions = new Map;
754
- cleanups = [];
755
- state = 2 /* DIRTY */;
756
- scope;
757
- constructor(fn) {
758
- this._fn = fn;
759
- this.scope = currentScope;
760
- if (currentScope) {
761
- currentScope.addSubscriber(this);
762
- }
763
- this.run();
764
- }
765
- addCleanup(fn) {
766
- this.cleanups.push(fn);
767
- }
768
- runCleanups() {
769
- for (let i = this.cleanups.length - 1;i >= 0; i--) {
770
- try {
771
- this.cleanups[i]();
772
- } catch (e) {
773
- console.error("Error in effect cleanup:", e);
774
- }
775
- }
776
- this.cleanups = [];
777
- }
778
- markDirty(targetState = 2 /* DIRTY */) {
779
- if (this.state >= targetState || this.state === 3 /* DISPOSED */) {
780
- return;
781
- }
782
- this.state = targetState;
783
- addPendingEffect(this);
784
- if (batchDepth === 0) {
785
- flushEffects();
786
- }
787
- }
788
- run() {
789
- if (this.state === 3 /* DISPOSED */)
790
- return;
791
- if (this.state === 1 /* CHECK_DIRTY */) {
792
- let isDirty = false;
793
- for (const source of this.sources) {
794
- if (source instanceof Computed) {
795
- source.updateIfNecessary();
796
- }
797
- const lastVersion = this.sourceVersions.get(source);
798
- if (lastVersion !== undefined && lastVersion !== source.version) {
799
- isDirty = true;
800
- }
801
- }
802
- if (!isDirty) {
803
- this.state = 0 /* CLEAN */;
804
- return;
805
- }
806
- }
807
- this.runCleanups();
808
- this.cleanupSources();
809
- const prevSubscriber = currentSubscriber;
810
- setCurrentSubscriber(this);
811
- const prevScope = currentScope;
812
- setCurrentScope(this.scope);
813
- try {
814
- this.state = 0 /* CLEAN */;
815
- const res = this._fn();
816
- if (typeof res === "function") {
817
- this.cleanups.push(res);
818
- }
819
- } finally {
820
- setCurrentSubscriber(prevSubscriber);
821
- setCurrentScope(prevScope);
822
- }
823
- }
824
- cleanupSources() {
825
- for (const source of this.sources) {
826
- source.removeSubscriber(this);
827
- }
828
- this.sources.clear();
829
- this.sourceVersions.clear();
830
- }
831
- dispose() {
832
- if (this.state === 3 /* DISPOSED */)
833
- return;
834
- this.state = 3 /* DISPOSED */;
835
- this.runCleanups();
836
- this.cleanupSources();
837
- removePendingEffect(this);
838
- }
839
- }
840
- function effect(fn) {
841
- const eff = new Effect(fn);
842
- return () => eff.dispose();
843
- }
844
- var createEffect = effect;
845
- // src/signals/signal.ts
846
- class Signal {
847
- [SIGNAL_BRAND] = true;
848
- _value;
849
- _subscribers = new Set;
850
- _equals;
851
- _onSet;
852
- version = 0;
853
- constructor(initialValue, equals, onSet) {
854
- this._value = initialValue;
855
- this._equals = equals ?? Object.is;
856
- this._onSet = onSet;
857
- }
858
- get() {
859
- if (currentSubscriber !== null && currentSubscriber.state !== 3 /* DISPOSED */) {
860
- this._subscribers.add(currentSubscriber);
861
- currentSubscriber.sources.add(this);
862
- currentSubscriber.sourceVersions.set(this, this.version);
863
- }
864
- return this._value;
865
- }
866
- set(newValue) {
867
- if (this._equals(this._value, newValue)) {
868
- return;
869
- }
870
- if (currentSubscriber !== null && this._subscribers.has(currentSubscriber)) {
871
- if (!warnedCyclicSubscribers.has(currentSubscriber)) {
872
- warnedCyclicSubscribers.add(currentSubscriber);
873
- if (typeof console !== "undefined" && typeof console.warn === "function") {
874
- console.warn(`[Visage Reactivity] Cyclic update detected: An active subscriber modified a signal that it depends on. ` + `To read a signal inside an effect/computed without creating a circular dependency, wrap the read in untrack():
875
- ` + ` untrack(() => signal())`);
876
- }
877
- }
878
- }
879
- this._value = newValue;
880
- this.version++;
881
- if (this._onSet) {
882
- this._onSet(newValue);
883
- }
884
- batch(() => {
885
- this.notify();
886
- });
887
- }
888
- update(fn) {
889
- this.set(fn(this._value));
890
- }
891
- get value() {
892
- return this.get();
893
- }
894
- set value(val) {
895
- this.set(val);
896
- }
897
- removeSubscriber(sub) {
898
- this._subscribers.delete(sub);
899
- }
900
- notify() {
901
- if (this._subscribers.size === 0)
902
- return;
903
- const subs = Array.from(this._subscribers);
904
- for (const sub of subs) {
905
- sub.markDirty(2 /* DIRTY */);
906
- }
907
- }
908
- }
909
- function resolveStorage(storageOption) {
910
- if (storageOption && typeof storageOption === "object") {
911
- return storageOption;
912
- }
913
- if (storageOption === "session") {
914
- try {
915
- if (typeof sessionStorage !== "undefined")
916
- return sessionStorage;
917
- } catch {}
918
- try {
919
- if (typeof window !== "undefined" && window.sessionStorage) {
920
- return window.sessionStorage;
921
- }
922
- } catch {}
923
- try {
924
- if (typeof globalThis !== "undefined" && globalThis.sessionStorage) {
925
- return globalThis.sessionStorage;
926
- }
927
- } catch {}
928
- return null;
929
- }
930
- try {
931
- if (typeof localStorage !== "undefined")
932
- return localStorage;
933
- } catch {}
934
- try {
935
- if (typeof window !== "undefined" && window.localStorage) {
936
- return window.localStorage;
937
- }
938
- } catch {}
939
- try {
940
- if (typeof globalThis !== "undefined" && globalThis.localStorage) {
941
- return globalThis.localStorage;
942
- }
943
- } catch {}
944
- return null;
945
- }
946
- function signal(initialValue, optionsOrEquals) {
947
- const equals = typeof optionsOrEquals === "function" ? optionsOrEquals : optionsOrEquals?.equals;
948
- const isInternal = typeof optionsOrEquals === "object" ? optionsOrEquals?.internal : false;
949
- const customName = typeof optionsOrEquals === "object" ? optionsOrEquals?.name : undefined;
950
- const persistOption = typeof optionsOrEquals === "object" ? optionsOrEquals?.persist : undefined;
951
- const persistConfig = persistOption ? typeof persistOption === "string" ? { key: persistOption } : persistOption : undefined;
952
- let effectiveInitial = initialValue;
953
- const storage = persistConfig ? resolveStorage(persistConfig.storage) : null;
954
- const serialize = persistConfig?.serialize ?? JSON.stringify;
955
- const deserialize = persistConfig?.deserialize ?? JSON.parse;
956
- if (persistConfig && storage) {
957
- try {
958
- const stored = storage.getItem(persistConfig.key);
959
- if (stored !== null) {
960
- effectiveInitial = deserialize(stored);
961
- }
962
- } catch {}
963
- }
964
- let isSyncing = false;
965
- const onSet = persistConfig && storage ? (val) => {
966
- if (isSyncing)
967
- return;
968
- try {
969
- storage.setItem(persistConfig.key, serialize(val));
970
- } catch {}
971
- } : undefined;
972
- const s = new Signal(effectiveInitial, equals, onSet);
973
- if (persistConfig && storage && (persistConfig.syncTabs ?? true) && typeof window !== "undefined" && typeof window.addEventListener === "function") {
974
- const onStorage = (e) => {
975
- if (e.key === persistConfig.key) {
976
- try {
977
- const nextVal = e.newValue !== null ? deserialize(e.newValue) : initialValue;
978
- isSyncing = true;
979
- try {
980
- s.set(nextVal);
981
- } finally {
982
- isSyncing = false;
983
- }
984
- } catch {}
985
- }
986
- };
987
- window.addEventListener("storage", onStorage);
988
- if (currentScope) {
989
- currentScope.addCleanup(() => {
990
- window.removeEventListener("storage", onStorage);
991
- });
992
- }
993
- }
994
- const accessor = (...args) => {
995
- if (args.length === 0) {
996
- return s.get();
997
- }
998
- s.set(args[0]);
999
- return args[0];
1000
- };
1001
- Object.defineProperties(accessor, {
1002
- [SIGNAL_BRAND]: { value: true },
1003
- get: { value: () => s.get() },
1004
- set: { value: (v) => s.set(v) },
1005
- update: { value: (fn) => s.update(fn) },
1006
- value: {
1007
- get: () => s.get(),
1008
- set: (v) => s.set(v)
1009
- }
1010
- });
1011
- if (!isInternal && typeof window !== "undefined" && window.__VISAGE_DEVTOOLS__) {
1012
- const devtools = window.__VISAGE_DEVTOOLS__;
1013
- const sigId = devtools.registerSignal({
1014
- name: customName,
1015
- type: "signal",
1016
- getValue: () => s.get(),
1017
- version: () => s.version,
1018
- subscribersCount: () => s._subscribers?.size ?? 0,
1019
- dependents: () => Array.from(s._subscribers ?? []).map((sub) => sub._devId).filter(Boolean)
1020
- });
1021
- s._devId = sigId;
1022
- if (currentScope) {
1023
- currentScope.addCleanup(() => {
1024
- devtools.unregisterSignal(sigId);
1025
- });
1026
- }
1027
- }
1028
- return accessor;
1029
- }
1030
- function createSignal(initialValue, optionsOrEquals) {
1031
- const s = signal(initialValue, optionsOrEquals);
1032
- const setter = (value) => {
1033
- if (typeof value === "function") {
1034
- s.update(value);
1035
- } else {
1036
- s.set(value);
1037
- }
1038
- };
1039
- return [s, setter];
1040
- }
1041
- // src/signals/store.ts
1042
- var STORE_RAW = Symbol("visage.store.raw");
1043
- var STORE_SIGNALS = Symbol("visage.store.signals");
1044
- var STORE_PROXY = Symbol("visage.store.proxy");
1045
- function isObject(val) {
1046
- return typeof val === "object" && val !== null && (typeof Node === "undefined" || !(val instanceof Node)) && !isSignal(val);
1047
- }
1048
- function getOrCreatePropertySignal(target, prop) {
1049
- let signalsMap = target[STORE_SIGNALS];
1050
- if (!signalsMap) {
1051
- signalsMap = new Map;
1052
- Object.defineProperty(target, STORE_SIGNALS, {
1053
- value: signalsMap,
1054
- enumerable: false,
1055
- writable: true
1056
- });
1057
- }
1058
- let sig = signalsMap.get(prop);
1059
- if (!sig) {
1060
- sig = new Signal(target[prop]);
1061
- signalsMap.set(prop, sig);
1062
- }
1063
- return sig;
1064
- }
1065
- function createStoreProxy(target) {
1066
- if (!isObject(target))
1067
- return target;
1068
- if (target[STORE_PROXY])
1069
- return target[STORE_PROXY];
1070
- const proxy = new Proxy(target, {
1071
- get(target, prop, receiver) {
1072
- if (prop === STORE_RAW)
1073
- return target;
1074
- if (prop === STORE_PROXY)
1075
- return proxy;
1076
- if (typeof prop === "string" || typeof prop === "symbol") {
1077
- const sig = getOrCreatePropertySignal(target, prop);
1078
- sig.get();
1079
- }
1080
- const value = Reflect.get(target, prop, receiver);
1081
- if (isObject(value)) {
1082
- return createStoreProxy(value);
1083
- }
1084
- return value;
1085
- },
1086
- set(target, prop, value, receiver) {
1087
- const prevValue = Reflect.get(target, prop, receiver);
1088
- if (Object.is(prevValue, value)) {
1089
- return true;
1090
- }
1091
- const success = Reflect.set(target, prop, value, receiver);
1092
- if (success) {
1093
- const sig = getOrCreatePropertySignal(target, prop);
1094
- sig.set(value);
1095
- if (Array.isArray(target) && prop !== "length") {
1096
- const lenSig = getOrCreatePropertySignal(target, "length");
1097
- lenSig.set(target.length);
1098
- }
1099
- }
1100
- return success;
1101
- },
1102
- deleteProperty(target, prop) {
1103
- const hadProp = Reflect.has(target, prop);
1104
- const success = Reflect.deleteProperty(target, prop);
1105
- if (hadProp && success) {
1106
- const sig = getOrCreatePropertySignal(target, prop);
1107
- sig.set(undefined);
1108
- }
1109
- return success;
1110
- }
1111
- });
1112
- Object.defineProperty(target, STORE_PROXY, {
1113
- value: proxy,
1114
- enumerable: false,
1115
- writable: true
1116
- });
1117
- return proxy;
1118
- }
1119
- function createStore(initialState) {
1120
- if (!isObject(initialState)) {
1121
- throw new Error("createStore requires an object or array as initial state");
1122
- }
1123
- return createStoreProxy(initialState);
1124
- }
1125
- function mutateStore(store, mutator) {
1126
- batch(() => {
1127
- mutator(store);
1128
- });
1129
- }
1130
- function unwrapStore(store) {
1131
- if (isObject(store) && store[STORE_RAW]) {
1132
- return store[STORE_RAW];
1133
- }
1134
- return store;
1135
- }
1136
- // src/charts/context.ts
1137
- var ChartContext = createContext(undefined);
1138
- function useChartContext() {
1139
- const ctx = useContext(ChartContext);
1140
- if (!ctx) {
1141
- throw new Error("Visage Chart child component must be rendered within a <Chart> container.");
1142
- }
1143
- return ctx;
1144
- }
1145
-
1146
- // src/charts/path.ts
1147
- function pathLine(points, options = {}) {
1148
- if (points.length === 0)
1149
- return "";
1150
- if (points.length === 1) {
1151
- const p = points[0];
1152
- return `M ${p.x.toFixed(2)},${p.y.toFixed(2)}`;
1153
- }
1154
- const curve = options.curve ?? "linear";
1155
- if (curve === "smooth" && points.length >= 2) {
1156
- if (points.length === 2) {
1157
- const p0 = points[0];
1158
- const p1 = points[1];
1159
- return `M ${p0.x.toFixed(2)},${p0.y.toFixed(2)} L ${p1.x.toFixed(2)},${p1.y.toFixed(2)}`;
1160
- }
1161
- const n = points.length;
1162
- const dx = [];
1163
- const dy = [];
1164
- const slopes = [];
1165
- for (let i = 0;i < n - 1; i++) {
1166
- const pA = points[i];
1167
- const pB = points[i + 1];
1168
- const deltaX = pB.x - pA.x;
1169
- const deltaY = pB.y - pA.y;
1170
- dx.push(deltaX);
1171
- dy.push(deltaY);
1172
- slopes.push(deltaX === 0 ? 0 : deltaY / deltaX);
1173
- }
1174
- const m = new Array(n).fill(0);
1175
- m[0] = slopes[0];
1176
- m[n - 1] = slopes[n - 2];
1177
- for (let i = 1;i < n - 1; i++) {
1178
- const sPrev = slopes[i - 1];
1179
- const sNext = slopes[i];
1180
- if (sPrev * sNext <= 0) {
1181
- m[i] = 0;
1182
- } else {
1183
- const dxPrev = dx[i - 1];
1184
- const dxNext = dx[i];
1185
- const common = dxPrev + dxNext;
1186
- m[i] = common === 0 ? 0 : 3 * common / ((common + dxNext) / sPrev + (common + dxPrev) / sNext);
1187
- }
1188
- }
1189
- let d = `M ${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
1190
- for (let i = 0;i < n - 1; i++) {
1191
- const p1 = points[i];
1192
- const p2 = points[i + 1];
1193
- const deltaX = dx[i];
1194
- const cp1x = p1.x + deltaX / 3;
1195
- const cp1y = p1.y + m[i] * deltaX / 3;
1196
- const cp2x = p2.x - deltaX / 3;
1197
- const cp2y = p2.y - m[i + 1] * deltaX / 3;
1198
- d += ` C ${cp1x.toFixed(2)},${cp1y.toFixed(2)} ${cp2x.toFixed(2)},${cp2y.toFixed(2)} ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
1199
- }
1200
- return d;
1201
- }
1202
- if (curve === "step") {
1203
- let d = `M ${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
1204
- for (let i = 0;i < points.length - 1; i++) {
1205
- const p1 = points[i];
1206
- const p2 = points[i + 1];
1207
- const midX = (p1.x + p2.x) / 2;
1208
- d += ` L ${midX.toFixed(2)},${p1.y.toFixed(2)} L ${midX.toFixed(2)},${p2.y.toFixed(2)} L ${p2.x.toFixed(2)},${p2.y.toFixed(2)}`;
1209
- }
1210
- return d;
1211
- }
1212
- let d = `M ${points[0].x.toFixed(2)},${points[0].y.toFixed(2)}`;
1213
- for (let i = 1;i < points.length; i++) {
1214
- d += ` L ${points[i].x.toFixed(2)},${points[i].y.toFixed(2)}`;
1215
- }
1216
- return d;
1217
- }
1218
- function pathArea(points, baselineY, options = {}) {
1219
- if (points.length === 0)
1220
- return "";
1221
- const lineD = pathLine(points, options);
1222
- if (!lineD)
1223
- return "";
1224
- const first = points[0];
1225
- const last = points[points.length - 1];
1226
- return `${lineD} L ${last.x.toFixed(2)},${baselineY.toFixed(2)} L ${first.x.toFixed(2)},${baselineY.toFixed(2)} Z`;
1227
- }
1228
- function pathArc(options) {
1229
- const { cx, cy, innerRadius, outerRadius, startAngle, endAngle } = options;
1230
- const cosStart = Math.cos(startAngle);
1231
- const sinStart = Math.sin(startAngle);
1232
- const cosEnd = Math.cos(endAngle);
1233
- const sinEnd = Math.sin(endAngle);
1234
- const x0 = cx + outerRadius * cosStart;
1235
- const y0 = cy + outerRadius * sinStart;
1236
- const x1 = cx + outerRadius * cosEnd;
1237
- const y1 = cy + outerRadius * sinEnd;
1238
- const largeArcFlag = endAngle - startAngle <= Math.PI ? 0 : 1;
1239
- if (innerRadius <= 0) {
1240
- return `M ${cx.toFixed(2)},${cy.toFixed(2)} L ${x0.toFixed(2)},${y0.toFixed(2)} A ${outerRadius.toFixed(2)},${outerRadius.toFixed(2)} 0 ${largeArcFlag} 1 ${x1.toFixed(2)},${y1.toFixed(2)} Z`;
1241
- }
1242
- const x2 = cx + innerRadius * cosEnd;
1243
- const y2 = cy + innerRadius * sinEnd;
1244
- const x3 = cx + innerRadius * cosStart;
1245
- const y3 = cy + innerRadius * sinStart;
1246
- return `M ${x0.toFixed(2)},${y0.toFixed(2)} A ${outerRadius.toFixed(2)},${outerRadius.toFixed(2)} 0 ${largeArcFlag} 1 ${x1.toFixed(2)},${y1.toFixed(2)} L ${x2.toFixed(2)},${y2.toFixed(2)} A ${innerRadius.toFixed(2)},${innerRadius.toFixed(2)} 0 ${largeArcFlag} 0 ${x3.toFixed(2)},${y3.toFixed(2)} Z`;
1247
- }
1248
-
1249
- // src/dom/resource.ts
1250
- var SuspenseContext = createContext(null);
1251
- function createResource(sourceOrFetcher, maybeFetcher) {
1252
- const isDirect = typeof maybeFetcher !== "function";
1253
- const fetcher = isDirect ? sourceOrFetcher : maybeFetcher;
1254
- const source = isDirect ? null : sourceOrFetcher;
1255
- const data = signal(undefined);
1256
- const loading = signal(true);
1257
- const error = signal(null);
1258
- let currentPromise = null;
1259
- let requestId = 0;
1260
- const load = async (arg) => {
1261
- const currentReq = ++requestId;
1262
- loading.set(true);
1263
- error.set(null);
1264
- const promise = isDirect ? fetcher() : fetcher(arg);
1265
- currentPromise = promise;
1266
- const suspense = useContext(SuspenseContext);
1267
- if (suspense) {
1268
- suspense.registerPromise(promise);
1269
- }
1270
- try {
1271
- const res = await promise;
1272
- if (currentReq === requestId) {
1273
- data.set(res);
1274
- loading.set(false);
1275
- currentPromise = null;
1276
- }
1277
- return res;
1278
- } catch (err) {
1279
- if (currentReq === requestId) {
1280
- error.set(err);
1281
- loading.set(false);
1282
- currentPromise = null;
1283
- }
1284
- throw err;
1285
- }
1286
- };
1287
- if (source) {
1288
- effect(() => {
1289
- const sourceVal = resolveValue(source);
1290
- if (sourceVal !== false && sourceVal !== null && sourceVal !== undefined) {
1291
- load(sourceVal).catch(() => {});
1292
- }
1293
- });
1294
- } else {
1295
- load().catch(() => {});
1296
- }
1297
- const accessor = () => {
1298
- if (loading() && currentPromise) {
1299
- const suspense = useContext(SuspenseContext);
1300
- if (suspense) {
1301
- suspense.registerPromise(currentPromise);
1302
- }
1303
- }
1304
- return data();
1305
- };
1306
- Object.defineProperties(accessor, {
1307
- loading: { get: () => loading },
1308
- error: { get: () => error },
1309
- mutate: { value: (val) => data.set(val) },
1310
- refetch: { value: () => source ? load(resolveValue(source)) : load() }
1311
- });
1312
- return accessor;
1313
- }
1314
-
1315
- // src/dom/lazy.ts
1316
- function lazy(importer) {
1317
- let loadedComponent = null;
1318
- let loadingPromise = null;
1319
- const preload = () => {
1320
- if (loadedComponent) {
1321
- return Promise.resolve(loadedComponent);
1322
- }
1323
- if (!loadingPromise) {
1324
- loadingPromise = importer().then((mod) => {
1325
- const comp = mod && typeof mod === "object" && "default" in mod ? mod.default : mod;
1326
- loadedComponent = comp;
1327
- return comp;
1328
- }).catch((err) => {
1329
- loadingPromise = null;
1330
- throw err;
1331
- });
1332
- }
1333
- return loadingPromise;
1334
- };
1335
- const LazyWrapper = (props) => {
1336
- if (loadedComponent) {
1337
- return loadedComponent(props);
1338
- }
1339
- const promise = preload();
1340
- const suspense = useContext(SuspenseContext);
1341
- if (suspense) {
1342
- suspense.registerPromise(promise);
1343
- }
1344
- const res = createResource(() => promise);
1345
- return () => {
1346
- const Comp = res();
1347
- return Comp ? Comp(props) : null;
1348
- };
1349
- };
1350
- LazyWrapper.preload = preload;
1351
- return LazyWrapper;
1352
- }
1353
- // src/dom/async.ts
1354
- function Suspense(props) {
1355
- if (typeof document === "undefined") {
1356
- return typeof props.children === "function" ? props.children() : props.children;
1357
- }
1358
- const marker = document.createTextNode("");
1359
- const initialFrag = document.createDocumentFragment();
1360
- const pendingCount = signal(0);
1361
- let currentScope = null;
1362
- let currentNodes = [];
1363
- let isMounted = false;
1364
- const suspenseValue = {
1365
- registerPromise(p) {
1366
- pendingCount.update((c) => c + 1);
1367
- p.finally(() => {
1368
- pendingCount.update((c) => Math.max(0, c - 1));
1369
- });
1370
- }
1371
- };
1372
- const renderContent = (content) => {
1373
- const parent = marker.parentNode ?? (!isMounted ? initialFrag : null);
1374
- if (!parent)
1375
- return;
1376
- for (const n of currentNodes) {
1377
- if (n.parentNode)
1378
- n.parentNode.removeChild(n);
1379
- }
1380
- currentNodes = [];
1381
- const frag = document.createDocumentFragment();
1382
- insertChild(frag, content);
1383
- currentNodes = Array.from(frag.childNodes);
1384
- if (marker.parentNode) {
1385
- marker.parentNode.insertBefore(frag, marker);
1386
- } else if (!isMounted) {
1387
- initialFrag.appendChild(frag);
1388
- }
1389
- };
1390
- effect(() => {
1391
- if (currentScope) {
1392
- currentScope.dispose();
1393
- currentScope = null;
1394
- }
1395
- currentScope = new Scope(getActiveScope());
1396
- runInScope(currentScope, () => {
1397
- let threwPromise = null;
1398
- let rendered = null;
1399
- try {
1400
- const SuspenseProvider = SuspenseContext.Provider;
1401
- rendered = SuspenseProvider({
1402
- value: suspenseValue,
1403
- children: props.children
1404
- });
1405
- } catch (err) {
1406
- if (err && typeof err.then === "function") {
1407
- threwPromise = err;
1408
- suspenseValue.registerPromise(err);
1409
- } else {
1410
- throw err;
1411
- }
1412
- }
1413
- if (pendingCount() > 0 || threwPromise) {
1414
- renderContent(props.fallback);
1415
- } else {
1416
- renderContent(rendered);
1417
- }
1418
- });
1419
- });
1420
- isMounted = true;
1421
- initialFrag.appendChild(marker);
1422
- onCleanup(() => {
1423
- if (currentScope)
1424
- currentScope.dispose();
1425
- });
1426
- return initialFrag;
1427
- }
1428
- function ErrorBoundary(props) {
1429
- if (typeof document === "undefined") {
1430
- try {
1431
- return typeof props.children === "function" ? props.children() : props.children;
1432
- } catch (err) {
1433
- return typeof props.fallback === "function" ? props.fallback(err, () => {}) : props.fallback;
1434
- }
1435
- }
1436
- const marker = document.createTextNode("");
1437
- const initialFrag = document.createDocumentFragment();
1438
- const currentError = signal(null);
1439
- let currentScope = null;
1440
- let currentNodes = [];
1441
- let isMounted = false;
1442
- const reset = () => {
1443
- currentError.set(null);
1444
- };
1445
- const renderNodes = (child) => {
1446
- const parent = marker.parentNode ?? (!isMounted ? initialFrag : null);
1447
- if (!parent)
1448
- return;
1449
- for (const n of currentNodes) {
1450
- if (n.parentNode)
1451
- n.parentNode.removeChild(n);
1452
- }
1453
- currentNodes = [];
1454
- const frag = document.createDocumentFragment();
1455
- insertChild(frag, child);
1456
- currentNodes = Array.from(frag.childNodes);
1457
- if (marker.parentNode) {
1458
- marker.parentNode.insertBefore(frag, marker);
1459
- } else if (!isMounted) {
1460
- initialFrag.appendChild(frag);
1461
- }
1462
- };
1463
- effect(() => {
1464
- const err = currentError();
1465
- if (currentScope) {
1466
- currentScope.dispose();
1467
- currentScope = null;
1468
- }
1469
- currentScope = new Scope(getActiveScope());
1470
- runInScope(currentScope, () => {
1471
- if (err !== null) {
1472
- const fallbackNode = typeof props.fallback === "function" ? props.fallback(err, reset) : props.fallback;
1473
- renderNodes(fallbackNode);
1474
- } else {
1475
- try {
1476
- const content = typeof props.children === "function" ? props.children() : props.children;
1477
- renderNodes(content);
1478
- } catch (catchedErr) {
1479
- currentError.set(catchedErr);
1480
- }
1481
- }
1482
- });
1483
- });
1484
- isMounted = true;
1485
- initialFrag.appendChild(marker);
1486
- onCleanup(() => {
1487
- if (currentScope)
1488
- currentScope.dispose();
1489
- });
1490
- return initialFrag;
1491
- }
1492
- // src/dom/control-flow.ts
1493
- function Show(props) {
1494
- if (typeof document === "undefined") {
1495
- const condition = resolveValue(props.when);
1496
- if (condition) {
1497
- return typeof props.children === "function" && props.children.length > 0 ? props.children(() => resolveValue(props.when)) : typeof props.children === "function" ? props.children() : props.children;
1498
- }
1499
- return props.fallback ?? null;
1500
- }
1501
- const marker = document.createComment("visage-show");
1502
- const initialFrag = document.createDocumentFragment();
1503
- initialFrag.appendChild(marker);
1504
- let currentScope = null;
1505
- let currentContent = [];
1506
- effect(() => {
1507
- const condition = resolveValue(props.when);
1508
- if (currentScope) {
1509
- currentScope.dispose();
1510
- currentScope = null;
1511
- }
1512
- for (const node of currentContent) {
1513
- if (node.parentNode) {
1514
- node.parentNode.removeChild(node);
1515
- }
1516
- }
1517
- currentContent = [];
1518
- const frag = document.createDocumentFragment();
1519
- if (condition) {
1520
- currentScope = new Scope(getActiveScope());
1521
- untrack(() => {
1522
- runInScope(currentScope, () => {
1523
- const childRes = typeof props.children === "function" && props.children.length > 0 ? props.children(() => resolveValue(props.when)) : typeof props.children === "function" ? props.children() : props.children;
1524
- insertChild(frag, childRes);
1525
- });
1526
- });
1527
- } else if (props.fallback !== undefined) {
1528
- currentScope = new Scope(getActiveScope());
1529
- untrack(() => {
1530
- runInScope(currentScope, () => {
1531
- const fallbackRes = typeof props.fallback === "function" ? props.fallback() : props.fallback;
1532
- insertChild(frag, fallbackRes);
1533
- });
1534
- });
1535
- }
1536
- currentContent = Array.from(frag.childNodes);
1537
- const parent = marker.parentNode;
1538
- if (parent) {
1539
- parent.insertBefore(frag, marker);
1540
- }
1541
- });
1542
- onCleanup(() => {
1543
- if (currentScope) {
1544
- currentScope.dispose();
1545
- }
1546
- for (const node of currentContent) {
1547
- if (node.parentNode) {
1548
- node.parentNode.removeChild(node);
1549
- }
1550
- }
1551
- if (marker.parentNode) {
1552
- marker.parentNode.removeChild(marker);
1553
- }
1554
- });
1555
- return initialFrag;
1556
- }
1557
- function For(props) {
1558
- if (typeof document === "undefined") {
1559
- const list = resolveValue(props.each) ?? [];
1560
- if (list.length === 0) {
1561
- return props.fallback ?? null;
1562
- }
1563
- return list.map((item, idx) => props.children(item, () => idx));
1564
- }
1565
- const marker = document.createTextNode("");
1566
- const initialFrag = document.createDocumentFragment();
1567
- let items = [];
1568
- let fallbackScope = null;
1569
- let fallbackNodes = [];
1570
- let isMounted = false;
1571
- effect(() => {
1572
- const list = resolveValue(props.each) ?? [];
1573
- const parent = marker.parentNode ?? (!isMounted ? initialFrag : null);
1574
- if (list.length === 0) {
1575
- for (const rec of items) {
1576
- rec.scope.dispose();
1577
- for (const node of rec.nodes) {
1578
- if (node.parentNode)
1579
- node.parentNode.removeChild(node);
1580
- }
1581
- }
1582
- items = [];
1583
- if (props.fallback !== undefined && fallbackNodes.length === 0 && parent) {
1584
- fallbackScope = new Scope(getActiveScope());
1585
- untrack(() => {
1586
- runInScope(fallbackScope, () => {
1587
- const frag = document.createDocumentFragment();
1588
- insertChild(frag, props.fallback);
1589
- fallbackNodes = Array.from(frag.childNodes);
1590
- if (marker.parentNode) {
1591
- marker.parentNode.insertBefore(frag, marker);
1592
- } else if (!isMounted) {
1593
- initialFrag.appendChild(frag);
1594
- }
1595
- });
1596
- });
1597
- }
1598
- return;
1599
- }
1600
- if (fallbackNodes.length > 0) {
1601
- if (fallbackScope) {
1602
- fallbackScope.dispose();
1603
- fallbackScope = null;
1604
- }
1605
- for (const node of fallbackNodes) {
1606
- if (node.parentNode)
1607
- node.parentNode.removeChild(node);
1608
- }
1609
- fallbackNodes = [];
1610
- }
1611
- if (!parent)
1612
- return;
1613
- const newItems = [];
1614
- const prevMap = new Map;
1615
- for (const rec of items) {
1616
- prevMap.set(rec.item, rec);
1617
- }
1618
- for (let i = 0;i < list.length; i++) {
1619
- const item = list[i];
1620
- const existing = prevMap.get(item);
1621
- if (existing) {
1622
- existing.indexSignal(i);
1623
- newItems.push(existing);
1624
- prevMap.delete(item);
1625
- } else {
1626
- let indexVal = i;
1627
- const indexSubscribers = new Set;
1628
- const indexSignal = (...args) => {
1629
- if (args.length > 0 && args[0] !== undefined && args[0] !== indexVal) {
1630
- indexVal = args[0];
1631
- for (const sub of Array.from(indexSubscribers))
1632
- sub();
1633
- }
1634
- return indexVal;
1635
- };
1636
- const itemScope = new Scope(getActiveScope());
1637
- let itemNodes = [];
1638
- untrack(() => {
1639
- runInScope(itemScope, () => {
1640
- const frag = document.createDocumentFragment();
1641
- const child = props.children(item, indexSignal);
1642
- insertChild(frag, child);
1643
- itemNodes = Array.from(frag.childNodes);
1644
- });
1645
- });
1646
- newItems.push({
1647
- item,
1648
- scope: itemScope,
1649
- nodes: itemNodes,
1650
- indexSignal
1651
- });
1652
- }
1653
- }
1654
- for (const [, removed] of prevMap) {
1655
- removed.scope.dispose();
1656
- for (const node of removed.nodes) {
1657
- if (node.parentNode)
1658
- node.parentNode.removeChild(node);
1659
- }
1660
- }
1661
- if (marker.parentNode) {
1662
- let currentMarker = marker;
1663
- for (let i = newItems.length - 1;i >= 0; i--) {
1664
- const rec = newItems[i];
1665
- for (let j = rec.nodes.length - 1;j >= 0; j--) {
1666
- const node = rec.nodes[j];
1667
- if (node.nextSibling !== currentMarker) {
1668
- marker.parentNode.insertBefore(node, currentMarker);
1669
- }
1670
- currentMarker = node;
1671
- }
1672
- }
1673
- } else if (!isMounted) {
1674
- for (const rec of newItems) {
1675
- for (const node of rec.nodes) {
1676
- initialFrag.appendChild(node);
1677
- }
1678
- }
1679
- }
1680
- items = newItems;
1681
- });
1682
- isMounted = true;
1683
- initialFrag.appendChild(marker);
1684
- onCleanup(() => {
1685
- for (const rec of items) {
1686
- rec.scope.dispose();
1687
- }
1688
- if (fallbackScope) {
1689
- fallbackScope.dispose();
1690
- }
1691
- });
1692
- return initialFrag;
1693
- }
1694
- function Portal(props) {
1695
- if (typeof document === "undefined") {
1696
- return null;
1697
- }
1698
- const marker = document.createTextNode("");
1699
- let currentScope = null;
1700
- let nodes = [];
1701
- effect(() => {
1702
- const target = props.mount ?? (typeof document !== "undefined" ? document.body : null);
1703
- if (!target)
1704
- return;
1705
- if (currentScope) {
1706
- currentScope.dispose();
1707
- currentScope = null;
1708
- }
1709
- for (const node of nodes) {
1710
- if (node.parentNode) {
1711
- node.parentNode.removeChild(node);
1712
- }
1713
- }
1714
- nodes = [];
1715
- currentScope = new Scope(getActiveScope());
1716
- untrack(() => {
1717
- runInScope(currentScope, () => {
1718
- const childRes = typeof props.children === "function" ? props.children() : props.children;
1719
- const frag = document.createDocumentFragment();
1720
- insertChild(frag, childRes);
1721
- nodes = Array.from(frag.childNodes);
1722
- target.appendChild(frag);
1723
- });
1724
- });
1725
- });
1726
- onCleanup(() => {
1727
- if (currentScope) {
1728
- currentScope.dispose();
1729
- currentScope = null;
1730
- }
1731
- for (const node of nodes) {
1732
- if (node.parentNode) {
1733
- node.parentNode.removeChild(node);
1734
- }
1735
- }
1736
- nodes = [];
1737
- });
1738
- return marker;
1739
- }
1740
- // src/jsx-runtime/index.ts
1741
- var SVG_NS = "http://www.w3.org/2000/svg";
1742
- var SVG_TAGS = new Set([
1743
- "svg",
1744
- "path",
1745
- "circle",
1746
- "rect",
1747
- "g",
1748
- "line",
1749
- "polyline",
1750
- "polygon",
1751
- "text",
1752
- "defs",
1753
- "clipPath",
1754
- "linearGradient",
1755
- "radialGradient",
1756
- "stop"
1757
- ]);
1758
- function Fragment(props) {
1759
- if (typeof document === "undefined") {
1760
- return props.children !== undefined ? props.children : [];
1761
- }
1762
- const fragment = document.createDocumentFragment();
1763
- if (props.children !== undefined) {
1764
- insertChild(fragment, props.children);
1765
- }
1766
- return fragment;
1767
- }
1768
- function jsx(type, props = {}, key) {
1769
- if (typeof type === "function") {
1770
- return type(props, key);
1771
- }
1772
- if (typeof type === "string") {
1773
- const { children, ...restProps } = props;
1774
- if (typeof document === "undefined") {
1775
- const attributes = new Map;
1776
- for (const propName in restProps) {
1777
- const val = restProps[propName];
1778
- if (propName === "className" || propName === "class") {
1779
- const resolved = typeof val === "function" ? val() : val;
1780
- if (resolved)
1781
- attributes.set("class", resolved);
1782
- } else if (propName === "style") {
1783
- const val = restProps[propName];
1784
- const resolved = resolveValue(val);
1785
- if (typeof resolved === "string") {
1786
- attributes.set("style", resolved);
1787
- } else if (typeof resolved === "object" && resolved !== null) {
1788
- const styleStr = Object.entries(resolved).map(([k, v]) => {
1789
- const finalVal = resolveValue(v);
1790
- const formatted = formatStyleProp(k, finalVal);
1791
- if (!formatted)
1792
- return "";
1793
- const kebab = k.startsWith("--") ? k : k.replace(/([A-Z])/g, "-$1").toLowerCase();
1794
- return `${kebab}: ${formatted}`;
1795
- }).filter(Boolean).join("; ");
1796
- if (styleStr)
1797
- attributes.set("style", styleStr);
1798
- }
1799
- } else if (!propName.startsWith("on")) {
1800
- const resolved = typeof val === "function" ? val() : val;
1801
- if (resolved === true) {
1802
- attributes.set(propName, propName);
1803
- } else if (resolved !== false && resolved !== null && resolved !== undefined) {
1804
- attributes.set(propName, resolved);
1805
- }
1806
- }
1807
- }
1808
- const childNodes = children !== undefined ? Array.isArray(children) ? children : [children] : [];
1809
- return {
1810
- tagName: type,
1811
- attributes,
1812
- childNodes
1813
- };
1814
- }
1815
- const isSvg = SVG_TAGS.has(type);
1816
- const element = isSvg ? document.createElementNS(SVG_NS, type) : document.createElement(type);
1817
- for (const propName in restProps) {
1818
- setAttribute(element, propName, restProps[propName]);
1819
- }
1820
- if (children !== undefined) {
1821
- insertChild(element, children);
1822
- }
1823
- return element;
1824
- }
1825
- return type;
1826
- }
1827
- var jsxs = jsx;
1828
- var jsxDEV = jsx;
1829
-
1830
- // src/charts/Area.tsx
1831
- function Area(props) {
1832
- return () => {
1833
- const ctx = useChartContext();
1834
- const stroke = props.stroke ?? "#a855f7";
1835
- const strokeWidth = props.strokeWidth ?? 2;
1836
- const fill = props.fill ?? "rgba(168, 85, 247, 0.15)";
1837
- const fillOpacity = props.fillOpacity ?? 1;
1838
- const curve = props.curve ?? "smooth";
1839
- const id = `area-${props.dataKey}-${Math.random().toString(36).slice(2, 7)}`;
1840
- ctx.registerSeries({
1841
- id,
1842
- dataKey: props.dataKey,
1843
- type: "area",
1844
- color: stroke,
1845
- name: props.name ?? props.dataKey
1846
- });
1847
- onCleanup(() => {
1848
- ctx.unregisterSeries(id);
1849
- });
1850
- return /* @__PURE__ */ jsx("g", {
1851
- class: `visage-area-${props.dataKey}`,
1852
- opacity: props.opacity ?? 1,
1853
- children: () => {
1854
- const dataArr = ctx.data();
1855
- if (dataArr.length === 0)
1856
- return null;
1857
- const xScale = ctx.xScale();
1858
- const yScale = ctx.yScale();
1859
- const baselineY = ctx.innerHeight();
1860
- const points = [];
1861
- for (let i = 0;i < dataArr.length; i++) {
1862
- const item = dataArr[i];
1863
- const val = item[props.dataKey];
1864
- if (typeof val !== "number" || Number.isNaN(val))
1865
- continue;
1866
- let x = 0;
1867
- if (xScale.type === "band") {
1868
- x = xScale(i) + xScale.bandwidth() / 2;
1869
- } else {
1870
- x = xScale(i);
1871
- }
1872
- const y = yScale(val);
1873
- points.push({ x, y });
1874
- }
1875
- const areaD = pathArea(points, baselineY, { curve });
1876
- const lineD = pathLine(points, { curve });
1877
- const dots = [];
1878
- if (props.dot && points.length > 0) {
1879
- const dotCfg = typeof props.dot === "object" ? props.dot : {};
1880
- const r = dotCfg.r ?? 3.5;
1881
- const dotFill = dotCfg.fill ?? "#ffffff";
1882
- const dotStroke = dotCfg.stroke ?? stroke;
1883
- for (let i = 0;i < points.length; i++) {
1884
- const p = points[i];
1885
- dots.push(/* @__PURE__ */ jsx("circle", {
1886
- cx: p.x,
1887
- cy: p.y,
1888
- r,
1889
- fill: dotFill,
1890
- stroke: dotStroke,
1891
- "stroke-width": 2
1892
- }));
1893
- }
1894
- }
1895
- return [
1896
- /* @__PURE__ */ jsx("path", {
1897
- d: areaD,
1898
- fill,
1899
- "fill-opacity": fillOpacity
1900
- }),
1901
- /* @__PURE__ */ jsx("path", {
1902
- d: lineD,
1903
- fill: "none",
1904
- stroke,
1905
- "stroke-width": strokeWidth,
1906
- "stroke-linejoin": "round",
1907
- "stroke-linecap": "round"
1908
- }),
1909
- ...dots
1910
- ];
1911
- }
1912
- });
1913
- };
1914
- }
1915
- // src/charts/Axis.tsx
1916
- function XAxis(props) {
1917
- return () => {
1918
- const ctx = useChartContext();
1919
- if (props.dataKey) {
1920
- ctx.setXDataKey(props.dataKey);
1921
- onCleanup(() => {
1922
- if (ctx.xDataKey() === props.dataKey) {
1923
- ctx.setXDataKey("");
1924
- }
1925
- });
1926
- }
1927
- const stroke = props.stroke ?? "#94a3b8";
1928
- const fontSize = props.fontSize ?? 11;
1929
- const hideLine = props.hideLine ?? false;
1930
- const w = ctx.innerWidth();
1931
- const h = ctx.innerHeight();
1932
- const xScale = ctx.xScale();
1933
- const dataArr = ctx.data();
1934
- const elements = [];
1935
- if (!hideLine) {
1936
- elements.push(/* @__PURE__ */ jsx("line", {
1937
- x1: 0,
1938
- y1: h,
1939
- x2: w,
1940
- y2: h,
1941
- stroke,
1942
- "stroke-width": 1
1943
- }));
1944
- }
1945
- if (xScale.type === "band") {
1946
- const ticks = xScale.ticks();
1947
- const bw = xScale.bandwidth();
1948
- for (let i = 0;i < ticks.length; i++) {
1949
- const val = ticks[i];
1950
- const x = xScale(i) + bw / 2;
1951
- const text = props.tickFormat ? props.tickFormat(val, i) : String(val);
1952
- elements.push(/* @__PURE__ */ jsx("text", {
1953
- x,
1954
- y: h + 16,
1955
- "text-anchor": "middle",
1956
- "font-size": fontSize,
1957
- fill: stroke,
1958
- children: text
1959
- }));
1960
- }
1961
- } else {
1962
- const count = props.tickCount ?? 5;
1963
- const ticks = xScale.ticks(count);
1964
- for (let i = 0;i < ticks.length; i++) {
1965
- const tickIdx = ticks[i];
1966
- const x = xScale(tickIdx);
1967
- const idx = Math.max(0, Math.min(dataArr.length - 1, Math.round(tickIdx)));
1968
- const rawItem = dataArr[idx];
1969
- const rawVal = props.dataKey && rawItem ? rawItem[props.dataKey] : idx;
1970
- const text = props.tickFormat ? props.tickFormat(rawVal, i) : String(rawVal ?? idx);
1971
- elements.push(/* @__PURE__ */ jsx("text", {
1972
- x,
1973
- y: h + 16,
1974
- "text-anchor": "middle",
1975
- "font-size": fontSize,
1976
- fill: stroke,
1977
- children: text
1978
- }));
1979
- }
1980
- }
1981
- return /* @__PURE__ */ jsx("g", {
1982
- class: "visage-x-axis",
1983
- children: elements
1984
- });
1985
- };
1986
- }
1987
- function YAxis(props) {
1988
- return () => {
1989
- const ctx = useChartContext();
1990
- const stroke = props.stroke ?? "#94a3b8";
1991
- const fontSize = props.fontSize ?? 11;
1992
- const hideLine = props.hideLine ?? true;
1993
- const unit = props.unit ?? "";
1994
- const h = ctx.innerHeight();
1995
- const yScale = ctx.yScale();
1996
- const ticks = yScale.ticks(props.tickCount ?? 5);
1997
- const elements = [];
1998
- if (!hideLine) {
1999
- elements.push(/* @__PURE__ */ jsx("line", {
2000
- x1: 0,
2001
- y1: 0,
2002
- x2: 0,
2003
- y2: h,
2004
- stroke,
2005
- "stroke-width": 1
2006
- }));
2007
- }
2008
- for (let i = 0;i < ticks.length; i++) {
2009
- const val = ticks[i];
2010
- const y = yScale(val);
2011
- const formatted = props.tickFormat ? props.tickFormat(val, i) : unit ? `${val}${unit}` : String(val);
2012
- elements.push(/* @__PURE__ */ jsx("text", {
2013
- x: -8,
2014
- y: y + 4,
2015
- "text-anchor": "end",
2016
- "font-size": fontSize,
2017
- fill: stroke,
2018
- children: formatted
2019
- }));
2020
- }
2021
- return /* @__PURE__ */ jsx("g", {
2022
- class: "visage-y-axis",
2023
- children: elements
2024
- });
2025
- };
2026
- }
2027
- // src/charts/Bar.tsx
2028
- function Bar(props) {
2029
- return () => {
2030
- const ctx = useChartContext();
2031
- const fill = props.fill ?? "#6366f1";
2032
- const radius = props.radius ?? 4;
2033
- const id = `bar-${props.dataKey}-${Math.random().toString(36).slice(2, 7)}`;
2034
- ctx.registerSeries({
2035
- id,
2036
- dataKey: props.dataKey,
2037
- type: "bar",
2038
- color: fill,
2039
- name: props.name ?? props.dataKey
2040
- });
2041
- onCleanup(() => {
2042
- ctx.unregisterSeries(id);
2043
- });
2044
- return /* @__PURE__ */ jsx("g", {
2045
- class: `visage-bar-${props.dataKey}`,
2046
- opacity: props.opacity ?? 1,
2047
- children: () => {
2048
- const dataArr = ctx.data();
2049
- if (dataArr.length === 0)
2050
- return null;
2051
- const xScale = ctx.xScale();
2052
- const yScale = ctx.yScale();
2053
- const baselineY = ctx.innerHeight();
2054
- const allBars = ctx.series().filter((s) => s.type === "bar");
2055
- const barIndex = allBars.findIndex((s) => s.id === id);
2056
- const totalBars = Math.max(1, allBars.length);
2057
- const bars = [];
2058
- for (let i = 0;i < dataArr.length; i++) {
2059
- const item = dataArr[i];
2060
- const val = item[props.dataKey];
2061
- if (typeof val !== "number" || Number.isNaN(val))
2062
- continue;
2063
- let slotX = 0;
2064
- let slotW = 20;
2065
- if (xScale.type === "band") {
2066
- slotX = xScale(i);
2067
- slotW = xScale.bandwidth();
2068
- } else {
2069
- const stepW = ctx.innerWidth() / Math.max(1, dataArr.length);
2070
- slotX = xScale(i) - stepW / 2;
2071
- slotW = stepW * 0.8;
2072
- }
2073
- const subBarW = slotW / totalBars;
2074
- const barW = props.maxWidth ? Math.min(props.maxWidth, subBarW) : subBarW;
2075
- const barX = slotX + (barIndex >= 0 ? barIndex * subBarW : 0) + (subBarW - barW) / 2;
2076
- const y = yScale(val);
2077
- const h = Math.max(0, baselineY - y);
2078
- bars.push(/* @__PURE__ */ jsx("rect", {
2079
- x: barX,
2080
- y,
2081
- width: barW,
2082
- height: h,
2083
- rx: radius,
2084
- ry: radius,
2085
- fill
2086
- }));
2087
- }
2088
- return bars;
2089
- }
2090
- });
2091
- };
2092
- }
2093
- // src/charts/CartesianGrid.tsx
2094
- function CartesianGrid(props) {
2095
- return () => {
2096
- const ctx = useChartContext();
2097
- const horizontal = props.horizontal ?? true;
2098
- const vertical = props.vertical ?? false;
2099
- const stroke = props.stroke ?? "#e2e8f0";
2100
- const strokeWidth = props.strokeWidth ?? 1;
2101
- const strokeDasharray = props.strokeDasharray;
2102
- const opacity = props.opacity ?? 0.8;
2103
- const lines = [];
2104
- const w = ctx.innerWidth();
2105
- const h = ctx.innerHeight();
2106
- const yScale = ctx.yScale();
2107
- const xScale = ctx.xScale();
2108
- if (horizontal) {
2109
- const ticks = yScale.ticks(5);
2110
- for (const t of ticks) {
2111
- const y = yScale(t);
2112
- lines.push(/* @__PURE__ */ jsx("line", {
2113
- x1: 0,
2114
- y1: y,
2115
- x2: w,
2116
- y2: y,
2117
- stroke,
2118
- "stroke-width": strokeWidth,
2119
- "stroke-dasharray": strokeDasharray
2120
- }));
2121
- }
2122
- }
2123
- if (vertical) {
2124
- const ticks = xScale.ticks(5);
2125
- for (const t of ticks) {
2126
- const x = xScale(t);
2127
- lines.push(/* @__PURE__ */ jsx("line", {
2128
- x1: x,
2129
- y1: 0,
2130
- x2: x,
2131
- y2: h,
2132
- stroke,
2133
- "stroke-width": strokeWidth,
2134
- "stroke-dasharray": strokeDasharray
2135
- }));
2136
- }
2137
- }
2138
- return /* @__PURE__ */ jsx("g", {
2139
- class: "visage-cartesian-grid",
2140
- opacity,
2141
- children: lines
2142
- });
2143
- };
2144
- }
2145
- // src/charts/scale.ts
2146
- function generateNiceTicks(min, max, count = 5) {
2147
- if (min === max)
2148
- return [min];
2149
- if (count <= 0)
2150
- return [];
2151
- const span = max - min;
2152
- const rawStep = span / count;
2153
- const magnitude = 10 ** Math.floor(Math.log10(rawStep));
2154
- const err = rawStep / magnitude;
2155
- let step;
2156
- if (err >= 7.5) {
2157
- step = 10 * magnitude;
2158
- } else if (err >= 3.5) {
2159
- step = 5 * magnitude;
2160
- } else if (err >= 1.5) {
2161
- step = 2 * magnitude;
2162
- } else {
2163
- step = 1 * magnitude;
2164
- }
2165
- const start = Math.floor(min / step) * step;
2166
- const end = Math.ceil(max / step) * step;
2167
- const ticks = [];
2168
- for (let current = start;current <= end + step * 0.5; current += step) {
2169
- const rounded = Number(current.toPrecision(12));
2170
- ticks.push(rounded);
2171
- }
2172
- return ticks;
2173
- }
2174
- function createLinearScale(domain, range, options = {}) {
2175
- let [d0, d1] = domain;
2176
- const [r0, r1] = range;
2177
- if (options.nice && d0 !== d1) {
2178
- const ticks = generateNiceTicks(d0, d1, 5);
2179
- if (ticks.length > 0) {
2180
- d0 = Math.min(d0, ticks[0]);
2181
- d1 = Math.max(d1, ticks[ticks.length - 1]);
2182
- }
2183
- }
2184
- const fn = (val) => {
2185
- let v = val;
2186
- if (options.clamp) {
2187
- const minD = Math.min(d0, d1);
2188
- const maxD = Math.max(d0, d1);
2189
- v = Math.max(minD, Math.min(maxD, v));
2190
- }
2191
- const ratio = d1 === d0 ? 0 : (v - d0) / (d1 - d0);
2192
- return r0 + ratio * (r1 - r0);
2193
- };
2194
- fn.type = "linear";
2195
- fn.domain = [d0, d1];
2196
- fn.range = [r0, r1];
2197
- fn.invert = (pixel) => {
2198
- const ratio = r1 === r0 ? 0 : (pixel - r0) / (r1 - r0);
2199
- return d0 + ratio * (d1 - d0);
2200
- };
2201
- fn.ticks = (count = 5) => {
2202
- return generateNiceTicks(d0, d1, count);
2203
- };
2204
- return fn;
2205
- }
2206
- function createBandScale(domain, range, options = {}) {
2207
- const paddingInner = options.paddingInner ?? 0.2;
2208
- const paddingOuter = options.paddingOuter ?? 0.1;
2209
- const n = domain.length;
2210
- const totalSteps = Math.max(1, n - paddingInner + 2 * paddingOuter);
2211
- const step = (range[1] - range[0]) / totalSteps;
2212
- const bandwidth = step * (1 - paddingInner);
2213
- const fn = (val) => {
2214
- let idx = -1;
2215
- if (typeof val === "number" && Number.isInteger(val) && val >= 0 && val < domain.length) {
2216
- idx = val;
2217
- } else {
2218
- idx = domain.indexOf(val);
2219
- }
2220
- if (idx === -1)
2221
- return range[0];
2222
- return range[0] + (idx + paddingOuter) * step;
2223
- };
2224
- fn.type = "band";
2225
- fn.domain = [...domain];
2226
- fn.range = [range[0], range[1]];
2227
- fn.bandwidth = () => bandwidth;
2228
- fn.step = () => step;
2229
- fn.ticks = () => [...domain];
2230
- return fn;
2231
- }
2232
-
2233
- // src/charts/Chart.tsx
2234
- var DEFAULT_MARGIN = {
2235
- top: 16,
2236
- right: 16,
2237
- bottom: 24,
2238
- left: 36
2239
- };
2240
- function Chart(props) {
2241
- const margin = {
2242
- ...DEFAULT_MARGIN,
2243
- ...props.margin
2244
- };
2245
- const initialW = typeof props.width === "number" ? props.width : 500;
2246
- const initialH = typeof props.height === "number" ? props.height : 300;
2247
- const measuredWidth = signal(initialW);
2248
- const measuredHeight = signal(initialH);
2249
- let containerEl = null;
2250
- const handleRef = (el) => {
2251
- containerEl = el;
2252
- if (typeof ResizeObserver !== "undefined") {
2253
- const ro = new ResizeObserver((entries) => {
2254
- for (const entry of entries) {
2255
- const cr = entry.contentRect;
2256
- if (cr.width > 0)
2257
- measuredWidth.set(cr.width);
2258
- if (cr.height > 0)
2259
- measuredHeight.set(cr.height);
2260
- }
2261
- });
2262
- ro.observe(el);
2263
- onCleanup(() => ro.disconnect());
2264
- } else {
2265
- if (el.clientWidth > 0)
2266
- measuredWidth.set(el.clientWidth);
2267
- if (el.clientHeight > 0)
2268
- measuredHeight.set(el.clientHeight);
2269
- }
2270
- };
2271
- const innerWidth = computed(() => Math.max(10, measuredWidth() - margin.left - margin.right));
2272
- const innerHeight = computed(() => Math.max(10, measuredHeight() - margin.top - margin.bottom));
2273
- const rawData = () => resolveValue(props.data) || [];
2274
- const seriesList = signal([]);
2275
- const xDataKey = signal(undefined);
2276
- const registerSeries = (meta) => {
2277
- untrack(() => {
2278
- seriesList.update((prev) => {
2279
- if (prev.some((s) => s.id === meta.id))
2280
- return prev;
2281
- return [...prev, meta];
2282
- });
2283
- });
2284
- };
2285
- const unregisterSeries = (id) => {
2286
- untrack(() => {
2287
- seriesList.update((prev) => prev.filter((s) => s.id !== id));
2288
- });
2289
- };
2290
- const hoverState = signal({
2291
- active: false,
2292
- x: 0,
2293
- y: 0,
2294
- index: -1
2295
- });
2296
- const xScale = computed(() => {
2297
- const dataArr = rawData();
2298
- const w = innerWidth();
2299
- const key = xDataKey();
2300
- const hasBarSeries = untrack(() => seriesList().some((s) => s.type === "bar"));
2301
- if (hasBarSeries && key && dataArr.length > 0) {
2302
- const categories = dataArr.map((d) => String(d[key]));
2303
- return createBandScale(categories, [0, w], {
2304
- paddingInner: 0.1,
2305
- paddingOuter: 0.05
2306
- });
2307
- }
2308
- const maxIdx = Math.max(1, dataArr.length - 1);
2309
- return createLinearScale([0, maxIdx], [0, w]);
2310
- });
2311
- const yScale = computed(() => {
2312
- const h = innerHeight();
2313
- const dataArr = rawData();
2314
- const currentSeries = seriesList();
2315
- let minY = 0;
2316
- let maxY = 10;
2317
- if (props.yDomain) {
2318
- minY = props.yDomain[0];
2319
- maxY = props.yDomain[1];
2320
- } else if (dataArr.length > 0 && currentSeries.length > 0) {
2321
- let foundMin = Infinity;
2322
- let foundMax = -Infinity;
2323
- for (const item of dataArr) {
2324
- for (const s of currentSeries) {
2325
- const val = item[s.dataKey];
2326
- if (typeof val === "number" && !Number.isNaN(val)) {
2327
- if (val < foundMin)
2328
- foundMin = val;
2329
- if (val > foundMax)
2330
- foundMax = val;
2331
- }
2332
- }
2333
- }
2334
- if (foundMax > -Infinity) {
2335
- minY = Math.min(0, foundMin);
2336
- maxY = foundMax === 0 ? 1 : foundMax * 1.1;
2337
- }
2338
- }
2339
- return createLinearScale([minY, maxY], [h, 0], { nice: true });
2340
- });
2341
- const handlePointer = (clientX, clientY) => {
2342
- if (!containerEl)
2343
- return;
2344
- const rect = containerEl.getBoundingClientRect();
2345
- const relX = clientX - rect.left - margin.left;
2346
- const relY = clientY - rect.top - margin.top;
2347
- const w = innerWidth();
2348
- const h = innerHeight();
2349
- if (relX < 0 || relX > w || relY < 0 || relY > h) {
2350
- hoverState.set({ active: false, x: 0, y: 0, index: -1 });
2351
- return;
2352
- }
2353
- const dataArr = rawData();
2354
- if (dataArr.length === 0)
2355
- return;
2356
- const count = dataArr.length;
2357
- const stepW = w / Math.max(1, count - 1);
2358
- const rawIdx = Math.round(relX / stepW);
2359
- const clampedIdx = Math.max(0, Math.min(count - 1, rawIdx));
2360
- hoverState.set({
2361
- active: true,
2362
- x: relX + margin.left,
2363
- y: relY + margin.top,
2364
- index: clampedIdx,
2365
- datum: dataArr[clampedIdx]
2366
- });
2367
- };
2368
- const handleMouseMove = (e) => {
2369
- handlePointer(e.clientX, e.clientY);
2370
- };
2371
- const handleMouseLeave = () => {
2372
- hoverState.set({ active: false, x: 0, y: 0, index: -1 });
2373
- };
2374
- const handleTouchMove = (e) => {
2375
- const touch = e.touches[0];
2376
- if (touch)
2377
- handlePointer(touch.clientX, touch.clientY);
2378
- };
2379
- const handleTouchEnd = () => {
2380
- hoverState.set({ active: false, x: 0, y: 0, index: -1 });
2381
- };
2382
- const ctxValue = {
2383
- data: rawData,
2384
- width: () => measuredWidth(),
2385
- height: () => measuredHeight(),
2386
- margin,
2387
- innerWidth: () => innerWidth(),
2388
- innerHeight: () => innerHeight(),
2389
- xScale: () => xScale(),
2390
- yScale: () => yScale(),
2391
- hoverState: () => hoverState(),
2392
- setHoverState: (s) => hoverState.set(s),
2393
- xDataKey: () => xDataKey(),
2394
- setXDataKey: (k) => xDataKey.set(k),
2395
- series: () => seriesList(),
2396
- registerSeries,
2397
- unregisterSeries
2398
- };
2399
- const containerStyle = {
2400
- position: "relative",
2401
- width: typeof props.width === "number" ? `${props.width}px` : props.width ?? "100%",
2402
- height: typeof props.height === "number" ? `${props.height}px` : props.height ?? "300px",
2403
- touchAction: "none",
2404
- userSelect: "none",
2405
- ...props.style
2406
- };
2407
- const rawChildren = Array.isArray(props.children) ? props.children : [props.children];
2408
- const childrenList = [];
2409
- const stack = [...rawChildren];
2410
- while (stack.length > 0) {
2411
- const item = stack.shift();
2412
- if (Array.isArray(item)) {
2413
- stack.unshift(...item);
2414
- } else if (item !== null && item !== undefined && item !== false) {
2415
- childrenList.push(item);
2416
- }
2417
- }
2418
- const svgChildren = [];
2419
- const overlayChildren = [];
2420
- for (const child of childrenList) {
2421
- if (typeof child === "function" && child.__visage_overlay) {
2422
- overlayChildren.push(child);
2423
- } else {
2424
- svgChildren.push(child);
2425
- }
2426
- }
2427
- return ChartContext.Provider({
2428
- value: ctxValue,
2429
- children: () => /* @__PURE__ */ jsxs("div", {
2430
- ref: handleRef,
2431
- class: props.class || props.className,
2432
- style: containerStyle,
2433
- onMouseMove: handleMouseMove,
2434
- onMouseLeave: handleMouseLeave,
2435
- onTouchMove: handleTouchMove,
2436
- onTouchEnd: handleTouchEnd,
2437
- children: [
2438
- /* @__PURE__ */ jsxs("svg", {
2439
- role: "img",
2440
- "aria-label": props["aria-label"] ?? "Data visualization chart",
2441
- viewBox: () => `0 0 ${measuredWidth()} ${measuredHeight()}`,
2442
- width: "100%",
2443
- height: "100%",
2444
- style: { overflow: "visible", display: "block" },
2445
- children: [
2446
- /* @__PURE__ */ jsx("title", {
2447
- children: props.title ?? "Data Visualization Chart"
2448
- }),
2449
- /* @__PURE__ */ jsx("g", {
2450
- transform: `translate(${margin.left}, ${margin.top})`,
2451
- children: svgChildren
2452
- })
2453
- ]
2454
- }),
2455
- overlayChildren
2456
- ]
2457
- })
2458
- });
2459
- }
2460
- // src/charts/Cursor.tsx
2461
- function ChartCursor(props) {
2462
- return () => {
2463
- const ctx = useChartContext();
2464
- const stroke = props.stroke ?? "#94a3b8";
2465
- const strokeWidth = props.strokeWidth ?? 1;
2466
- const strokeDasharray = props.strokeDasharray ?? "4 4";
2467
- const opacity = props.opacity ?? 0.8;
2468
- const hover = ctx.hoverState();
2469
- if (!hover.active)
2470
- return null;
2471
- const h = ctx.innerHeight();
2472
- const x = hover.x - ctx.margin.left;
2473
- return /* @__PURE__ */ jsx("g", {
2474
- class: "visage-chart-cursor",
2475
- children: /* @__PURE__ */ jsx("line", {
2476
- x1: x,
2477
- y1: 0,
2478
- x2: x,
2479
- y2: h,
2480
- stroke,
2481
- "stroke-width": strokeWidth,
2482
- "stroke-dasharray": strokeDasharray,
2483
- opacity
2484
- })
2485
- });
2486
- };
2487
- }
2488
- // src/charts/Legend.tsx
2489
- function ChartLegend(props) {
2490
- const render = () => {
2491
- const ctx = useChartContext();
2492
- const align = props.align ?? "center";
2493
- const justifyMap = {
2494
- left: "flex-start",
2495
- center: "center",
2496
- right: "flex-end"
2497
- };
2498
- const series = ctx.series();
2499
- return /* @__PURE__ */ jsx("div", {
2500
- class: props.class || props.className,
2501
- style: {
2502
- display: "flex",
2503
- alignItems: "center",
2504
- justifyContent: justifyMap[align],
2505
- gap: "16px",
2506
- paddingTop: "8px",
2507
- fontSize: "12px",
2508
- color: "#475569"
2509
- },
2510
- children: series.map((s) => /* @__PURE__ */ jsxs("div", {
2511
- style: { display: "flex", alignItems: "center", gap: "6px" },
2512
- children: [
2513
- /* @__PURE__ */ jsx("span", {
2514
- style: {
2515
- width: "10px",
2516
- height: "10px",
2517
- borderRadius: "3px",
2518
- background: s.color ?? "#8b5cf6"
2519
- }
2520
- }),
2521
- /* @__PURE__ */ jsx("span", {
2522
- children: s.name ?? s.dataKey
2523
- })
2524
- ]
2525
- }))
2526
- });
2527
- };
2528
- render.__visage_overlay = true;
2529
- return render;
2530
- }
2531
- var Legend = ChartLegend;
2532
- // src/charts/Line.tsx
2533
- function Line(props) {
2534
- return () => {
2535
- const ctx = useChartContext();
2536
- const stroke = props.stroke ?? "#8b5cf6";
2537
- const strokeWidth = props.strokeWidth ?? 2;
2538
- const curve = props.curve ?? "linear";
2539
- const id = `line-${props.dataKey}-${Math.random().toString(36).slice(2, 7)}`;
2540
- ctx.registerSeries({
2541
- id,
2542
- dataKey: props.dataKey,
2543
- type: "line",
2544
- color: stroke,
2545
- name: props.name ?? props.dataKey
2546
- });
2547
- onCleanup(() => {
2548
- ctx.unregisterSeries(id);
2549
- });
2550
- return /* @__PURE__ */ jsx("g", {
2551
- class: `visage-line-${props.dataKey}`,
2552
- opacity: props.opacity ?? 1,
2553
- children: () => {
2554
- const dataArr = ctx.data();
2555
- if (dataArr.length === 0)
2556
- return null;
2557
- const xScale = ctx.xScale();
2558
- const yScale = ctx.yScale();
2559
- const points = [];
2560
- for (let i = 0;i < dataArr.length; i++) {
2561
- const item = dataArr[i];
2562
- const val = item[props.dataKey];
2563
- if (typeof val !== "number" || Number.isNaN(val))
2564
- continue;
2565
- let x = 0;
2566
- if (xScale.type === "band") {
2567
- x = xScale(i) + xScale.bandwidth() / 2;
2568
- } else {
2569
- x = xScale(i);
2570
- }
2571
- const y = yScale(val);
2572
- points.push({ x, y });
2573
- }
2574
- const d = pathLine(points, { curve });
2575
- const dots = [];
2576
- if (props.dot && points.length > 0) {
2577
- const dotCfg = typeof props.dot === "object" ? props.dot : {};
2578
- const r = dotCfg.r ?? 3.5;
2579
- const fill = dotCfg.fill ?? "#ffffff";
2580
- const dotStroke = dotCfg.stroke ?? stroke;
2581
- const dotSw = dotCfg.strokeWidth ?? 2;
2582
- for (let i = 0;i < points.length; i++) {
2583
- const p = points[i];
2584
- dots.push(/* @__PURE__ */ jsx("circle", {
2585
- cx: p.x,
2586
- cy: p.y,
2587
- r,
2588
- fill,
2589
- stroke: dotStroke,
2590
- "stroke-width": dotSw
2591
- }));
2592
- }
2593
- }
2594
- return [
2595
- /* @__PURE__ */ jsx("path", {
2596
- d,
2597
- fill: "none",
2598
- stroke,
2599
- "stroke-width": strokeWidth,
2600
- "stroke-dasharray": props.strokeDasharray,
2601
- "stroke-linejoin": "round",
2602
- "stroke-linecap": "round"
2603
- }),
2604
- ...dots
2605
- ];
2606
- }
2607
- });
2608
- };
2609
- }
2610
- // src/charts/Pie.tsx
2611
- var DEFAULT_PALETTE = [
2612
- "#8b5cf6",
2613
- "#ec4899",
2614
- "#3b82f6",
2615
- "#10b981",
2616
- "#f59e0b",
2617
- "#6366f1",
2618
- "#14b8a6",
2619
- "#ef4444"
2620
- ];
2621
- function Pie(props) {
2622
- return () => {
2623
- const ctx = useChartContext();
2624
- const innerRadius = props.innerRadius ?? 0;
2625
- const outerRadius = props.outerRadius ?? 80;
2626
- const colors = props.colors ?? DEFAULT_PALETTE;
2627
- const padAngle = props.padAngle ?? 0.02;
2628
- return /* @__PURE__ */ jsx("g", {
2629
- class: "visage-pie",
2630
- children: () => {
2631
- const dataArr = ctx.data();
2632
- if (dataArr.length === 0)
2633
- return null;
2634
- const w = ctx.innerWidth();
2635
- const h = ctx.innerHeight();
2636
- const centerX = props.cx ?? w / 2;
2637
- const centerY = props.cy ?? h / 2;
2638
- let total = 0;
2639
- for (const item of dataArr) {
2640
- const val = Number(item[props.dataKey]) || 0;
2641
- total += val;
2642
- }
2643
- if (total === 0)
2644
- return null;
2645
- const slices = [];
2646
- let currentAngle = -Math.PI / 2;
2647
- for (let i = 0;i < dataArr.length; i++) {
2648
- const item = dataArr[i];
2649
- const val = Number(item[props.dataKey]) || 0;
2650
- const sliceAngle = val / total * (2 * Math.PI);
2651
- const startAngle = currentAngle + (val > 0 ? padAngle / 2 : 0);
2652
- const endAngle = currentAngle + sliceAngle - (val > 0 ? padAngle / 2 : 0);
2653
- currentAngle += sliceAngle;
2654
- if (val <= 0 || endAngle <= startAngle)
2655
- continue;
2656
- const d = pathArc({
2657
- cx: centerX,
2658
- cy: centerY,
2659
- innerRadius,
2660
- outerRadius,
2661
- startAngle,
2662
- endAngle
2663
- });
2664
- const fill = colors[i % colors.length];
2665
- slices.push(/* @__PURE__ */ jsx("path", {
2666
- d,
2667
- fill,
2668
- stroke: "#ffffff",
2669
- "stroke-width": 1.5
2670
- }));
2671
- }
2672
- return slices;
2673
- }
2674
- });
2675
- };
2676
- }
2677
- // src/charts/Tooltip.tsx
2678
- function ChartTooltip(props) {
2679
- const render = () => {
2680
- const ctx = useChartContext();
2681
- const hover = ctx.hoverState();
2682
- if (!hover.active || !hover.datum)
2683
- return null;
2684
- const w = ctx.width();
2685
- const datum = hover.datum;
2686
- const series = ctx.series();
2687
- const xKey = ctx.xDataKey();
2688
- const cardWidth = 160;
2689
- let left = hover.x + 14;
2690
- if (left + cardWidth > w) {
2691
- left = Math.max(10, hover.x - cardWidth - 14);
2692
- }
2693
- const top = Math.max(10, hover.y - 30);
2694
- if (props.content) {
2695
- return /* @__PURE__ */ jsx("div", {
2696
- style: {
2697
- position: "absolute",
2698
- left: `${left}px`,
2699
- top: `${top}px`,
2700
- pointerEvents: "none",
2701
- zIndex: 50
2702
- },
2703
- children: props.content(datum, series)
2704
- });
2705
- }
2706
- const label = xKey && datum[xKey] !== undefined ? datum[xKey] : `#${hover.index + 1}`;
2707
- const formattedLabel = props.labelFormat ? props.labelFormat(label) : String(label);
2708
- return /* @__PURE__ */ jsxs("div", {
2709
- class: props.class || props.className,
2710
- style: {
2711
- position: "absolute",
2712
- left: `${left}px`,
2713
- top: `${top}px`,
2714
- pointerEvents: "none",
2715
- zIndex: 50,
2716
- minWidth: `${cardWidth}px`,
2717
- padding: "8px 12px",
2718
- borderRadius: "10px",
2719
- background: "rgba(255, 255, 255, 0.92)",
2720
- backdropFilter: "blur(12px)",
2721
- WebkitBackdropFilter: "blur(12px)",
2722
- border: "1px solid rgba(226, 232, 240, 0.8)",
2723
- boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.05)",
2724
- fontSize: "12px",
2725
- color: "#1e293b",
2726
- lineHeight: "1.4"
2727
- },
2728
- children: [
2729
- /* @__PURE__ */ jsx("div", {
2730
- style: {
2731
- fontWeight: "600",
2732
- color: "#475569",
2733
- marginBottom: "6px",
2734
- borderBottom: "1px solid #f1f5f9",
2735
- paddingBottom: "4px"
2736
- },
2737
- children: formattedLabel
2738
- }),
2739
- /* @__PURE__ */ jsx("div", {
2740
- style: { display: "flex", flexDirection: "column", gap: "4px" },
2741
- children: series.map((s) => {
2742
- const rawVal = datum[s.dataKey];
2743
- if (rawVal === undefined || rawVal === null)
2744
- return null;
2745
- const valStr = props.format ? props.format(rawVal, s.name ?? s.dataKey) : String(rawVal);
2746
- return /* @__PURE__ */ jsxs("div", {
2747
- style: {
2748
- display: "flex",
2749
- alignItems: "center",
2750
- justifyContent: "space-between",
2751
- gap: "8px"
2752
- },
2753
- children: [
2754
- /* @__PURE__ */ jsxs("div", {
2755
- style: { display: "flex", alignItems: "center", gap: "6px" },
2756
- children: [
2757
- /* @__PURE__ */ jsx("span", {
2758
- style: {
2759
- width: "8px",
2760
- height: "8px",
2761
- borderRadius: "50%",
2762
- background: s.color ?? "#8b5cf6"
2763
- }
2764
- }),
2765
- /* @__PURE__ */ jsx("span", {
2766
- style: { color: "#64748b" },
2767
- children: s.name ?? s.dataKey
2768
- })
2769
- ]
2770
- }),
2771
- /* @__PURE__ */ jsx("span", {
2772
- style: { fontWeight: "600", color: "#0f172a" },
2773
- children: valStr
2774
- })
2775
- ]
2776
- });
2777
- })
2778
- })
2779
- ]
2780
- });
2781
- };
2782
- render.__visage_overlay = true;
2783
- return render;
2784
- }
2785
- var Tooltip = ChartTooltip;
1
+ import"../index-6kfe1nr4.js";
2
+ import"../index-5s255b3w.js";
3
+ import"../index-9fvarkrx.js";
4
+ import {
5
+ ChartContext2,
6
+ useChartContext2,
7
+ pathLine2,
8
+ pathArea2,
9
+ pathArc2,
10
+ Area2,
11
+ XAxis2,
12
+ YAxis2,
13
+ Bar2,
14
+ CartesianGrid2,
15
+ generateNiceTicks2,
16
+ createLinearScale2,
17
+ createBandScale2,
18
+ Chart2,
19
+ ChartCursor2,
20
+ ChartLegend2,
21
+ Legend2,
22
+ Line2,
23
+ Pie2,
24
+ ChartTooltip2,
25
+ Tooltip2
26
+ } from "../index-dyvgtp43.js";
27
+ import"../index-a4xns6cc.js";
2786
28
  export {
2787
- Area,
2788
- Bar,
2789
- CartesianGrid,
2790
- Chart,
2791
- ChartContext,
2792
- ChartCursor,
2793
- ChartLegend,
2794
- ChartTooltip,
2795
- Legend,
2796
- Line,
2797
- Pie,
2798
- Tooltip,
2799
- XAxis,
2800
- YAxis,
2801
- createBandScale,
2802
- createLinearScale,
2803
- generateNiceTicks,
2804
- pathArc,
2805
- pathArea,
2806
- pathLine,
2807
- useChartContext
29
+ Area2 as Area,
30
+ Bar2 as Bar,
31
+ CartesianGrid2 as CartesianGrid,
32
+ Chart2 as Chart,
33
+ ChartContext2 as ChartContext,
34
+ ChartCursor2 as ChartCursor,
35
+ ChartLegend2 as ChartLegend,
36
+ ChartTooltip2 as ChartTooltip,
37
+ Legend2 as Legend,
38
+ Line2 as Line,
39
+ Pie2 as Pie,
40
+ Tooltip2 as Tooltip,
41
+ XAxis2 as XAxis,
42
+ YAxis2 as YAxis,
43
+ createBandScale2 as createBandScale,
44
+ createLinearScale2 as createLinearScale,
45
+ generateNiceTicks2 as generateNiceTicks,
46
+ pathArc2 as pathArc,
47
+ pathArea2 as pathArea,
48
+ pathLine2 as pathLine,
49
+ useChartContext2 as useChartContext
2808
50
  };