@thebuoyant-tsdev/mui-ts-library 3.9.1 → 3.11.2

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 (32) hide show
  1. package/README.de.md +93 -0
  2. package/README.md +93 -0
  3. package/dist/components/chord-chart/ChordChart.d.ts +1 -1
  4. package/dist/components/chord-chart/ChordChart.js +155 -137
  5. package/dist/components/chord-chart/ChordChart.types.d.ts +1 -1
  6. package/dist/components/circle-packing-chart/CirclePackingChart.d.ts +1 -1
  7. package/dist/components/circle-packing-chart/CirclePackingChart.js +134 -121
  8. package/dist/components/gantt-chart/hooks/useGanttDrag.js +44 -38
  9. package/dist/components/horizontal-tree-chart/HorizontalTreeChart.d.ts +1 -1
  10. package/dist/components/horizontal-tree-chart/HorizontalTreeChart.js +319 -247
  11. package/dist/components/horizontal-tree-chart/HorizontalTreeChart.types.d.ts +3 -1
  12. package/dist/components/json-editor/JsonEditorContent.js +134 -119
  13. package/dist/components/json-editor/JsonEditorToolbar.js +3 -3
  14. package/dist/components/password-strength-meter/PasswordStrengthMeter.js +131 -130
  15. package/dist/components/radial-tree-chart/RadialTreeChart.d.ts +1 -1
  16. package/dist/components/radial-tree-chart/RadialTreeChart.js +207 -146
  17. package/dist/components/radial-tree-chart/RadialTreeChart.types.d.ts +2 -0
  18. package/dist/components/rich-text-editor/RichTextEditor.js +1 -1
  19. package/dist/components/rich-text-editor/RichTextEditorMarkdownDialog.js +40 -39
  20. package/dist/components/shared/useTimedFlag.d.ts +6 -0
  21. package/dist/components/shared/useTimedFlag.js +14 -0
  22. package/dist/components/sql-editor/SqlEditorHistoryMenu.js +1 -1
  23. package/dist/components/sql-editor/useSqlQueryHistory.js +14 -12
  24. package/dist/components/sql-editor/util/sqlQueryHistory.util.d.ts +1 -0
  25. package/dist/components/sql-editor/util/sqlQueryHistory.util.js +21 -13
  26. package/dist/components/sunburst-chart/SunburstChart.d.ts +1 -1
  27. package/dist/components/sunburst-chart/SunburstChart.js +193 -150
  28. package/dist/components/sunburst-chart/SunburstChart.types.d.ts +2 -0
  29. package/dist/components/tag-selection/TagSelectionAutocomplete.js +7 -5
  30. package/dist/index.cjs +2 -2
  31. package/dist/index.js +7 -7
  32. package/package.json +1 -1
package/README.de.md CHANGED
@@ -284,6 +284,71 @@ const data: RadialTreeChartData = {
284
284
 
285
285
  ---
286
286
 
287
+ ### CirclePackingChart
288
+
289
+ Hierarchische Daten als verschachtelte Kreise, proportional zum Wert skaliert. Ideal für Speicherplatz-Auswertungen, Budget-Übersichten oder jede Hierarchie, bei der relative Größe auf einen Blick zählt. `Ctrl / Cmd ⌘+Click` (oder Doppelklick) auf einen Kreis mit Kindern zoomt mit sanfter animierter Transition hinein; Klick auf den Hintergrund oder `Escape` zoomt zurück.
290
+
291
+ ```tsx
292
+ import { CirclePackingChart } from '@thebuoyant-tsdev/mui-ts-library';
293
+ import type { CirclePackingData } from '@thebuoyant-tsdev/mui-ts-library';
294
+
295
+ const data: CirclePackingData = {
296
+ id: 'disk', name: 'Festplatte',
297
+ children: [
298
+ { id: 'photos', name: 'Fotos', value: 120 },
299
+ { id: 'videos', name: 'Videos', value: 340 },
300
+ { id: 'apps', name: 'Apps',
301
+ children: [
302
+ { id: 'xcode', name: 'Xcode', value: 48 },
303
+ { id: 'docker', name: 'Docker', value: 12 },
304
+ ]},
305
+ ],
306
+ };
307
+
308
+ <CirclePackingChart
309
+ data={data}
310
+ size={500}
311
+ onCircleClick={(info) => console.log(info.name, info.value)}
312
+ />
313
+ ```
314
+
315
+ → [Vollständige Dokumentation](user-manuals/CirclePackingChart.de.md)
316
+
317
+ ---
318
+
319
+ ### HorizontalTreeChart
320
+
321
+ Hierarchische Daten als links-nach-rechts (oder eine der 4 Ausrichtungen) Entscheidungsbaum mit geschwungenen Links. Ideal für Entscheidungslogik, Eskalationspfade oder Org-Charts, die natürlicher von oben nach unten oder seitlich gelesen werden als radial. `Ctrl / Cmd ⌘+Click` bohrt in Teilbäume, `Ctrl / Cmd ⌘+Scroll` zoomt.
322
+
323
+ ```tsx
324
+ import { HorizontalTreeChart } from '@thebuoyant-tsdev/mui-ts-library';
325
+ import type { HorizontalTreeData } from '@thebuoyant-tsdev/mui-ts-library';
326
+
327
+ const data: HorizontalTreeData = {
328
+ id: 'ticket', name: 'Neues Ticket',
329
+ children: [
330
+ { id: 'bug', name: 'Bug', specialValueA: 'P1 — 4h SLA',
331
+ children: [
332
+ { id: 'bug-fe', name: 'Frontend-Team' },
333
+ { id: 'bug-be', name: 'Backend-Team' },
334
+ ]},
335
+ { id: 'feature', name: 'Feature-Anfrage', specialValueA: 'P3 — Backlog' },
336
+ ],
337
+ };
338
+
339
+ <HorizontalTreeChart
340
+ data={data}
341
+ orientation="LR"
342
+ width={700}
343
+ drillable
344
+ onNodeClick={(info) => console.log(info.name, info.depth)}
345
+ />
346
+ ```
347
+
348
+ → [Vollständige Dokumentation](user-manuals/HorizontalTreeChart.de.md)
349
+
350
+ ---
351
+
287
352
  ## TypeScript
288
353
 
289
354
  Alle Typen und Defaults werden direkt exportiert — kein separates `@types/...`-Paket nötig.
@@ -343,6 +408,34 @@ Dieses Projekt folgt [Semantic Versioning](https://semver.org/). In der Praxis b
343
408
 
344
409
  ## Changelog
345
410
 
411
+ ### [3.11.2] — 2026-06-28
412
+
413
+ **Behoben**
414
+ - Eine tiefgreifende Bug-Prüfung über alle 11 Komponenten — veraltete Timer/Listener bei Unmount, `maxTags`-Umgehung, fehlendes `noData`-Rendering auf allen 5 D3-Charts, ChordChart valueIn/valueOut-Fehlzählung im undirected-Modus, HorizontalTreeChart RL/BT-Spiegelung außermittig bei flachen Bäumen, und mehr. Jeder Fix ist mit einem Regressionstest abgesichert. Vollständige Liste siehe [Changelog](#3112--2026-06-28).
415
+
416
+ ---
417
+
418
+ ### [3.11.1] — 2026-06-27
419
+
420
+ **Behoben**
421
+ - TagSelection: doppeltes Tag in der `WithCustomColorCreation`-Storybook-Story — ein Story-Bug, kein Komponenten-Bug. Siehe [Changelog](#3111--2026-06-27).
422
+
423
+ ---
424
+
425
+ ### [3.11.0] — 2026-06-25
426
+
427
+ **RadialTreeChart & HorizontalTreeChart**
428
+ - `duration`: Rein-/Rauszoomen und Escape-Resets crossfaden jetzt statt abrupt zu wechseln (Standard 750ms, `0` deaktiviert).
429
+
430
+ ---
431
+
432
+ ### [3.10.0] — 2026-06-25
433
+
434
+ **SunburstChart**
435
+ - `duration`: Rein-/Rauszoomen animiert jetzt sanft zwischen Fokus-Ebenen (Standard 750ms, `0` deaktiviert).
436
+
437
+ ---
438
+
346
439
  ### [3.9.1] — 2026-06-25
347
440
 
348
441
  **Behoben**
package/README.md CHANGED
@@ -284,6 +284,71 @@ const data: RadialTreeChartData = {
284
284
 
285
285
  ---
286
286
 
287
+ ### CirclePackingChart
288
+
289
+ Hierarchical data as nested circles, sized proportionally to value. Use `CirclePackingChart` for disk usage, org budgets, or any hierarchy where relative size matters at a glance. `Ctrl / Cmd ⌘+Click` (or double-click) a circle with children to zoom in with a smooth animated transition; click the background or `Escape` to zoom back out.
290
+
291
+ ```tsx
292
+ import { CirclePackingChart } from '@thebuoyant-tsdev/mui-ts-library';
293
+ import type { CirclePackingData } from '@thebuoyant-tsdev/mui-ts-library';
294
+
295
+ const data: CirclePackingData = {
296
+ id: 'disk', name: 'Disk',
297
+ children: [
298
+ { id: 'photos', name: 'Photos', value: 120 },
299
+ { id: 'videos', name: 'Videos', value: 340 },
300
+ { id: 'apps', name: 'Apps',
301
+ children: [
302
+ { id: 'xcode', name: 'Xcode', value: 48 },
303
+ { id: 'docker', name: 'Docker', value: 12 },
304
+ ]},
305
+ ],
306
+ };
307
+
308
+ <CirclePackingChart
309
+ data={data}
310
+ size={500}
311
+ onCircleClick={(info) => console.log(info.name, info.value)}
312
+ />
313
+ ```
314
+
315
+ → [Full documentation](user-manuals/CirclePackingChart.md)
316
+
317
+ ---
318
+
319
+ ### HorizontalTreeChart
320
+
321
+ Hierarchical data as a left-to-right (or any of 4 orientations) decision tree with curved links. Use `HorizontalTreeChart` for decision logic, escalation paths, or org charts that read more naturally top-to-bottom or side-to-side than radially. `Ctrl / Cmd ⌘+Click` drills into subtrees, `Ctrl / Cmd ⌘+Scroll` zooms.
322
+
323
+ ```tsx
324
+ import { HorizontalTreeChart } from '@thebuoyant-tsdev/mui-ts-library';
325
+ import type { HorizontalTreeData } from '@thebuoyant-tsdev/mui-ts-library';
326
+
327
+ const data: HorizontalTreeData = {
328
+ id: 'ticket', name: 'New Ticket',
329
+ children: [
330
+ { id: 'bug', name: 'Bug', specialValueA: 'P1 — 4h SLA',
331
+ children: [
332
+ { id: 'bug-fe', name: 'Frontend Team' },
333
+ { id: 'bug-be', name: 'Backend Team' },
334
+ ]},
335
+ { id: 'feature', name: 'Feature Request', specialValueA: 'P3 — Backlog' },
336
+ ],
337
+ };
338
+
339
+ <HorizontalTreeChart
340
+ data={data}
341
+ orientation="LR"
342
+ width={700}
343
+ drillable
344
+ onNodeClick={(info) => console.log(info.name, info.depth)}
345
+ />
346
+ ```
347
+
348
+ → [Full documentation](user-manuals/HorizontalTreeChart.md)
349
+
350
+ ---
351
+
287
352
  ## TypeScript
288
353
 
289
354
  All types and defaults are exported directly — no separate `@types/...` package needed.
@@ -343,6 +408,34 @@ This project follows [Semantic Versioning](https://semver.org/). In practice:
343
408
 
344
409
  ## Changelog
345
410
 
411
+ ### [3.11.2] — 2026-06-28
412
+
413
+ **Fixed**
414
+ - A deep bug audit across all 11 components — stale timers/listeners on unmount, `maxTags` bypass, missing `noData` rendering on all 5 D3 charts, `ChordChart` valueIn/valueOut miscount in undirected mode, `HorizontalTreeChart` RL/BT mirror off-center for shallow trees, and more. Every fix is backed by a regression test. See [Changelog](#3112--2026-06-28) for the full list.
415
+
416
+ ---
417
+
418
+ ### [3.11.1] — 2026-06-27
419
+
420
+ **Fixed**
421
+ - TagSelection: duplicate tag in the `WithCustomColorCreation` Storybook story — a story bug, not a component bug. See [Changelog](#3111--2026-06-27).
422
+
423
+ ---
424
+
425
+ ### [3.11.0] — 2026-06-25
426
+
427
+ **RadialTreeChart & HorizontalTreeChart**
428
+ - `duration`: drill in/out and Escape resets now crossfade instead of jump-cutting (default 750ms, `0` disables).
429
+
430
+ ---
431
+
432
+ ### [3.10.0] — 2026-06-25
433
+
434
+ **SunburstChart**
435
+ - `duration`: drill-in/out now animates smoothly between focus levels (default 750ms, `0` disables).
436
+
437
+ ---
438
+
346
439
  ### [3.9.1] — 2026-06-25
347
440
 
348
441
  **Fixed**
@@ -1,5 +1,5 @@
1
1
  import { type ChordChartProps } from "./ChordChart.types";
2
- export declare function ChordChart({ data, size, innerRadius, ringThickness, padAngle, ribbonPadAngle, sortSubgroups, sortChords, chartColors, groupColorConfigs, showGroupLabels, labelOffset, ribbonOpacity, ribbonBlendMode, directed, valueDecimalCount, valueDecimalSeparator, valueThousandsSeparator, onGroupClick, onChordClick, zoomable, disabled, }: ChordChartProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function ChordChart({ data, size, innerRadius, ringThickness, padAngle, ribbonPadAngle, sortSubgroups, sortChords, chartColors, groupColorConfigs, showGroupLabels, labelOffset, ribbonOpacity, ribbonBlendMode, directed, valueDecimalCount, valueDecimalSeparator, valueThousandsSeparator, onGroupClick, onChordClick, zoomable, disabled, translation, }: ChordChartProps): import("react/jsx-runtime").JSX.Element;
3
3
  export declare namespace ChordChart {
4
4
  var displayName: string;
5
5
  }
@@ -1,18 +1,19 @@
1
- import { useCallback as e, useLayoutEffect as t, useMemo as n, useRef as r, useState as i } from "react";
2
- import { Box as a, Tooltip as o, Typography as s, useTheme as ee } from "@mui/material";
3
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
4
- import * as u from "d3";
1
+ import { DEFAULT_CHORD_CHART_TRANSLATION as e } from "./ChordChart.types.js";
2
+ import { useCallback as t, useLayoutEffect as n, useMemo as r, useRef as i, useState as a } from "react";
3
+ import { Box as o, Tooltip as s, Typography as c, useTheme as ee } from "@mui/material";
4
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ import * as d from "d3";
5
6
  //#region src/components/chord-chart/ChordChart.tsx
6
- function d(e, t = 0, n = ".", r = ",") {
7
+ function te(e, t = 0, n = ".", r = ",") {
7
8
  if (!isFinite(e)) return String(e);
8
9
  let [i, a] = e.toFixed(Math.max(0, t)).split("."), o = i.replace(/\B(?=(\d{3})+(?!\d))/g, r);
9
10
  return a ? `${o}${n}${a}` : o;
10
11
  }
11
- function f({ name: e, valueOut: t, valueIn: n, fmt: r }) {
12
- return /* @__PURE__ */ l(a, {
12
+ function ne({ name: e, valueOut: t, valueIn: n, fmt: r }) {
13
+ return /* @__PURE__ */ u(o, {
13
14
  sx: { py: .25 },
14
15
  children: [
15
- /* @__PURE__ */ c(s, {
16
+ /* @__PURE__ */ l(c, {
16
17
  variant: "caption",
17
18
  sx: {
18
19
  fontWeight: "bold",
@@ -20,7 +21,7 @@ function f({ name: e, valueOut: t, valueIn: n, fmt: r }) {
20
21
  },
21
22
  children: e
22
23
  }),
23
- /* @__PURE__ */ l(s, {
24
+ /* @__PURE__ */ u(c, {
24
25
  variant: "caption",
25
26
  sx: {
26
27
  display: "block",
@@ -28,7 +29,7 @@ function f({ name: e, valueOut: t, valueIn: n, fmt: r }) {
28
29
  },
29
30
  children: [r(t), " outgoing →"]
30
31
  }),
31
- /* @__PURE__ */ l(s, {
32
+ /* @__PURE__ */ u(c, {
32
33
  variant: "caption",
33
34
  sx: {
34
35
  display: "block",
@@ -39,11 +40,11 @@ function f({ name: e, valueOut: t, valueIn: n, fmt: r }) {
39
40
  ]
40
41
  });
41
42
  }
42
- function te({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, directed: i, fmt: o }) {
43
- return /* @__PURE__ */ l(a, {
43
+ function f({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, directed: i, fmt: a }) {
44
+ return /* @__PURE__ */ u(o, {
44
45
  sx: { py: .25 },
45
46
  children: [
46
- /* @__PURE__ */ l(s, {
47
+ /* @__PURE__ */ u(c, {
47
48
  variant: "caption",
48
49
  sx: {
49
50
  fontWeight: "bold",
@@ -55,15 +56,15 @@ function te({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, dire
55
56
  t
56
57
  ]
57
58
  }),
58
- /* @__PURE__ */ c(s, {
59
+ /* @__PURE__ */ l(c, {
59
60
  variant: "caption",
60
61
  sx: {
61
62
  display: "block",
62
63
  opacity: .85
63
64
  },
64
- children: o(n)
65
+ children: a(n)
65
66
  }),
66
- i && r > 0 && r !== n && /* @__PURE__ */ l(s, {
67
+ i && r > 0 && r !== n && /* @__PURE__ */ u(c, {
67
68
  variant: "caption",
68
69
  sx: {
69
70
  display: "block",
@@ -75,27 +76,30 @@ function te({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, dire
75
76
  " → ",
76
77
  e,
77
78
  ": ",
78
- o(r)
79
+ a(r)
79
80
  ]
80
81
  })
81
82
  ]
82
83
  });
83
84
  }
84
- function p({ data: s, size: p = 500, innerRadius: m, ringThickness: h = 20, padAngle: ne, ribbonPadAngle: re, sortSubgroups: g = "descending", sortChords: _ = "descending", chartColors: v, groupColorConfigs: y, showGroupLabels: b = !0, labelOffset: ie = 8, ribbonOpacity: x = .75, ribbonBlendMode: ae, directed: S = !0, valueDecimalCount: C = 0, valueDecimalSeparator: w = ".", valueThousandsSeparator: T = ",", onGroupClick: E, onChordClick: D, zoomable: O = !1, disabled: k = !1 }) {
85
- let A = ee(), j = ae ?? (A.palette.mode === "dark" ? "normal" : "multiply"), oe = [
86
- A.palette.primary.main,
87
- A.palette.secondary.main,
88
- A.palette.error.main,
89
- A.palette.warning.main,
90
- A.palette.success.main,
91
- A.palette.info.main
92
- ], M = v && v.length > 0 ? v : oe, se = m ?? Math.min(p, p) * .5 - 90, N = Math.max(10, se), P = N + Math.max(1, h), F = ne ?? 10 / N, I = re ?? 1 / N, L = e((e) => d(e, C, w, T), [
93
- C,
94
- w,
95
- T
96
- ]), { names: R, matrix: z } = n(() => {
97
- let e = u.sort(u.union(s.map((e) => e.source), s.map((e) => e.target))), t = new Map(e.map((e, t) => [e, t])), n = Array.from({ length: e.length }, () => Array(e.length).fill(0));
98
- for (let { source: e, target: r, value: i } of s) {
85
+ function p({ data: c, size: p = 500, innerRadius: m, ringThickness: h = 20, padAngle: re, ribbonPadAngle: g, sortSubgroups: _ = "descending", sortChords: v = "descending", chartColors: y, groupColorConfigs: b, showGroupLabels: ie = !0, labelOffset: x = 8, ribbonOpacity: S = .75, ribbonBlendMode: C, directed: w = !0, valueDecimalCount: T = 0, valueDecimalSeparator: E = ".", valueThousandsSeparator: D = ",", onGroupClick: O, onChordClick: k, zoomable: A = !1, disabled: j = !1, translation: ae }) {
86
+ let M = ee(), oe = {
87
+ ...e,
88
+ ...ae
89
+ }, se = c.length === 0, ce = C ?? (M.palette.mode === "dark" ? "normal" : "multiply"), le = [
90
+ M.palette.primary.main,
91
+ M.palette.secondary.main,
92
+ M.palette.error.main,
93
+ M.palette.warning.main,
94
+ M.palette.success.main,
95
+ M.palette.info.main
96
+ ], N = y && y.length > 0 ? y : le, ue = m ?? Math.min(p, p) * .5 - 90, P = Math.max(10, ue), F = P + Math.max(1, h), I = re ?? 10 / P, L = g ?? 1 / P, R = t((e) => te(e, T, E, D), [
97
+ T,
98
+ E,
99
+ D
100
+ ]), { names: z, matrix: B } = r(() => {
101
+ let e = d.sort(d.union(c.map((e) => e.source), c.map((e) => e.target))), t = new Map(e.map((e, t) => [e, t])), n = Array.from({ length: e.length }, () => Array(e.length).fill(0));
102
+ for (let { source: e, target: r, value: i } of c) {
99
103
  let a = t.get(e), o = t.get(r);
100
104
  a == null || o == null || (n[a][o] += i);
101
105
  }
@@ -103,40 +107,40 @@ function p({ data: s, size: p = 500, innerRadius: m, ringThickness: h = 20, padA
103
107
  names: e,
104
108
  matrix: n
105
109
  };
106
- }, [s]), B = n(() => {
107
- let e = (S ? u.chordDirected() : u.chord()).padAngle(F);
108
- return g === "ascending" && (e = e.sortSubgroups(u.ascending)), g === "descending" && (e = e.sortSubgroups(u.descending)), _ === "ascending" && (e = e.sortChords(u.ascending)), _ === "descending" && (e = e.sortChords(u.descending)), e(z);
110
+ }, [c]), V = r(() => {
111
+ let e = (w ? d.chordDirected() : d.chord()).padAngle(I);
112
+ return _ === "ascending" && (e = e.sortSubgroups(d.ascending)), _ === "descending" && (e = e.sortSubgroups(d.descending)), v === "ascending" && (e = e.sortChords(d.ascending)), v === "descending" && (e = e.sortChords(d.descending)), e(B);
109
113
  }, [
110
- z,
111
- F,
112
- S,
113
- g,
114
- _
115
- ]), V = n(() => u.arc().innerRadius(N).outerRadius(P), [N, P]), H = n(() => (S ? u.ribbonArrow() : u.ribbon()).radius(N - 1).padAngle(I), [
116
- N,
114
+ B,
117
115
  I,
118
- S
119
- ]), U = e((e) => H({
116
+ w,
117
+ _,
118
+ v
119
+ ]), H = r(() => d.arc().innerRadius(P).outerRadius(F), [P, F]), U = r(() => (w ? d.ribbonArrow() : d.ribbon()).radius(P - 1).padAngle(L), [
120
+ P,
121
+ L,
122
+ w
123
+ ]), de = t((e) => U({
120
124
  source: {
121
125
  startAngle: e.source.startAngle,
122
126
  endAngle: e.source.endAngle,
123
- radius: N - 1
127
+ radius: P - 1
124
128
  },
125
129
  target: {
126
130
  startAngle: e.target.startAngle,
127
131
  endAngle: e.target.endAngle,
128
- radius: N - 1
132
+ radius: P - 1
129
133
  }
130
- }) ?? "", [H, N]), W = n(() => u.scaleOrdinal().domain(u.range(R.length)).range(M.length >= R.length ? M : [...Array(Math.ceil(R.length / M.length))].flatMap(() => M).slice(0, R.length)), [M, R.length]), G = e((e) => y?.[R[e]]?.fill ?? W(e), [
131
- y,
132
- R,
134
+ }) ?? "", [U, P]), W = r(() => d.scaleOrdinal().domain(d.range(z.length)).range(N.length >= z.length ? N : [...Array(Math.ceil(z.length / N.length))].flatMap(() => N).slice(0, z.length)), [N, z.length]), G = t((e) => b?.[z[e]]?.fill ?? W(e), [
135
+ b,
136
+ z,
133
137
  W
134
- ]), K = r(null), [q, J] = i(`-${p / 2} -${p / 2} ${p} ${p}`), [Y, X] = i(1), ce = n(() => {
138
+ ]), K = i(null), [q, J] = a(`-${p / 2} -${p / 2} ${p} ${p}`), [Y, X] = a(1), fe = r(() => {
135
139
  if (Y === 1) return q;
136
140
  let [e, t, n, r] = q.split(" ").map(Number), i = n / Y, a = r / Y;
137
141
  return `${e + (n - i) / 2} ${t + (r - a) / 2} ${i} ${a}`;
138
142
  }, [q, Y]);
139
- t(() => {
143
+ n(() => {
140
144
  let e = K.current;
141
145
  if (!e) return;
142
146
  let t = requestAnimationFrame(() => {
@@ -150,131 +154,145 @@ function p({ data: s, size: p = 500, innerRadius: m, ringThickness: h = 20, padA
150
154
  return () => cancelAnimationFrame(t);
151
155
  }, [
152
156
  p,
153
- N,
154
157
  P,
155
- R.length,
156
- B
158
+ F,
159
+ z.length,
160
+ V
157
161
  ]);
158
- let [Z, Q] = i(null), le = e((e) => ({
159
- name: R[e.index],
162
+ let [Z, Q] = a(null), pe = t((e) => ({
163
+ name: z[e.index],
160
164
  index: e.index,
161
- valueOut: u.sum(B, (t) => t.source.index === e.index ? t.source.value : 0),
162
- valueIn: u.sum(B, (t) => t.target.index === e.index ? t.source.value : 0)
163
- }), [R, B]), ue = e((e) => ({
165
+ valueOut: d.sum(V, (t) => (t.source.index === e.index ? t.source.value : 0) + (!w && t.target.index === e.index ? t.target.value : 0)),
166
+ valueIn: d.sum(V, (t) => (t.target.index === e.index ? t.source.value : 0) + (!w && t.source.index === e.index ? t.target.value : 0))
167
+ }), [
168
+ z,
169
+ V,
170
+ w
171
+ ]), me = t((e) => ({
164
172
  source: {
165
- name: R[e.source.index],
173
+ name: z[e.source.index],
166
174
  index: e.source.index,
167
175
  value: e.source.value
168
176
  },
169
177
  target: {
170
- name: R[e.target.index],
178
+ name: z[e.target.index],
171
179
  index: e.target.index,
172
180
  value: e.target.value
173
181
  }
174
- }), [R]), de = (e) => {
182
+ }), [z]), he = (e) => {
175
183
  let t = (e.startAngle + e.endAngle) / 2, n = t * 180 / Math.PI - 90, r = t > Math.PI ? " rotate(180)" : "";
176
- return `rotate(${n}) translate(${P + ie})${r}`;
177
- }, fe = (e) => (e.startAngle + e.endAngle) / 2 > Math.PI ? "end" : "start", pe = e((e) => {
178
- if (!O || k || !e.ctrlKey) return;
184
+ return `rotate(${n}) translate(${F + x})${r}`;
185
+ }, ge = (e) => (e.startAngle + e.endAngle) / 2 > Math.PI ? "end" : "start", _e = t((e) => {
186
+ if (!A || j || !e.ctrlKey) return;
179
187
  e.preventDefault();
180
188
  let t = e.deltaY < 0 ? 1.15 : 1 / 1.15;
181
189
  X((e) => Math.max(.25, Math.min(8, e * t)));
182
- }, [O, k]);
183
- t(() => {
184
- if (!O) return;
190
+ }, [A, j]);
191
+ n(() => {
192
+ if (!A) return;
185
193
  let e = (e) => {
186
194
  e.key === "Escape" && X(1);
187
195
  };
188
196
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
189
- }, [O]);
197
+ }, [A]);
190
198
  let $ = {
191
199
  followCursor: !0,
192
200
  enterDelay: 50,
193
201
  enterNextDelay: 0,
194
- disableHoverListener: k,
202
+ disableHoverListener: j,
195
203
  slotProps: { tooltip: { sx: { maxWidth: 240 } } }
196
- }, me = A.palette.text.primary, he = A.typography.fontFamily;
197
- return /* @__PURE__ */ c(a, {
204
+ }, ve = M.palette.text.primary, ye = M.typography.fontFamily;
205
+ return /* @__PURE__ */ l(o, {
198
206
  sx: {
199
207
  display: "inline-flex",
200
- opacity: k ? .5 : 1,
201
- cursor: k ? "not-allowed" : "default",
208
+ opacity: j ? .5 : 1,
209
+ cursor: j ? "not-allowed" : "default",
202
210
  userSelect: "none"
203
211
  },
204
- children: /* @__PURE__ */ c("svg", {
212
+ children: /* @__PURE__ */ l("svg", {
205
213
  width: p,
206
214
  height: p,
207
- viewBox: ce,
208
- onWheel: pe,
215
+ viewBox: fe,
216
+ onWheel: _e,
209
217
  style: {
210
- fontFamily: he ?? "sans-serif",
211
- overflow: O && Y > 1 ? "hidden" : "visible"
218
+ fontFamily: ye ?? "sans-serif",
219
+ overflow: A && Y > 1 ? "hidden" : "visible"
212
220
  },
213
221
  role: "img",
214
222
  "aria-label": "Chord chart",
215
- children: /* @__PURE__ */ l("g", {
223
+ children: /* @__PURE__ */ u("g", {
216
224
  ref: K,
217
- children: [/* @__PURE__ */ c("g", { children: B.groups.map((e) => {
218
- let t = le(e), n = Z === e.index, r = Z !== null && !n;
219
- return /* @__PURE__ */ c(o, {
220
- ...$,
221
- title: /* @__PURE__ */ c(f, {
222
- name: t.name,
223
- valueOut: t.valueOut,
224
- valueIn: t.valueIn,
225
- fmt: L
226
- }),
227
- children: /* @__PURE__ */ l("g", {
228
- style: { cursor: k ? "not-allowed" : "pointer" },
229
- onMouseEnter: () => !k && Q(e.index),
230
- onMouseLeave: () => Q(null),
231
- onClick: (e) => !k && E?.(t, e),
232
- children: [/* @__PURE__ */ c("path", {
233
- d: V(e) || "",
234
- fill: G(e.index),
235
- stroke: A.palette.divider,
236
- opacity: r ? .35 : 1,
237
- style: { transition: "opacity 0.15s" }
238
- }), b && /* @__PURE__ */ c("text", {
239
- dy: "0.35em",
240
- fontSize: 11,
241
- fill: me,
242
- transform: de(e),
243
- textAnchor: fe(e),
244
- pointerEvents: "none",
245
- children: R[e.index]
246
- })]
247
- })
248
- }, `grp-tt-${e.index}`);
249
- }) }), /* @__PURE__ */ c("g", {
250
- fillOpacity: x,
251
- style: { mixBlendMode: j },
252
- children: B.map((e, t) => {
253
- let n = ue(e), r = Z === null || e.source.index === Z || e.target.index === Z;
254
- return /* @__PURE__ */ c(o, {
225
+ children: [
226
+ se && /* @__PURE__ */ l("text", {
227
+ textAnchor: "middle",
228
+ dy: "0.35em",
229
+ fontSize: 13,
230
+ fill: M.palette.text.secondary,
231
+ children: oe.noData
232
+ }),
233
+ /* @__PURE__ */ l("g", { children: V.groups.map((e) => {
234
+ let t = pe(e), n = Z === e.index, r = Z !== null && !n;
235
+ return /* @__PURE__ */ l(s, {
255
236
  ...$,
256
- title: /* @__PURE__ */ c(te, {
257
- sourceName: n.source.name,
258
- targetName: n.target.name,
259
- sourceValue: n.source.value,
260
- targetValue: n.target.value,
261
- directed: S,
262
- fmt: L
237
+ title: /* @__PURE__ */ l(ne, {
238
+ name: t.name,
239
+ valueOut: t.valueOut,
240
+ valueIn: t.valueIn,
241
+ fmt: R
263
242
  }),
264
- children: /* @__PURE__ */ c("path", {
265
- d: U(e),
266
- fill: G(e.target.index),
267
- stroke: "none",
268
- opacity: r ? 1 : .12,
269
- style: {
270
- cursor: k ? "not-allowed" : "pointer",
271
- transition: "opacity 0.15s"
272
- },
273
- onClick: (e) => !k && D?.(n, e)
243
+ children: /* @__PURE__ */ u("g", {
244
+ style: { cursor: j ? "not-allowed" : "pointer" },
245
+ onMouseEnter: () => !j && Q(e.index),
246
+ onMouseLeave: () => Q(null),
247
+ onClick: (e) => !j && O?.(t, e),
248
+ children: [/* @__PURE__ */ l("path", {
249
+ d: H(e) || "",
250
+ fill: G(e.index),
251
+ stroke: M.palette.divider,
252
+ opacity: r ? .35 : 1,
253
+ style: { transition: "opacity 0.15s" }
254
+ }), ie && /* @__PURE__ */ l("text", {
255
+ dy: "0.35em",
256
+ fontSize: 11,
257
+ fill: ve,
258
+ transform: he(e),
259
+ textAnchor: ge(e),
260
+ pointerEvents: "none",
261
+ children: z[e.index]
262
+ })]
274
263
  })
275
- }, `chord-tt-${t}`);
264
+ }, `grp-tt-${e.index}`);
265
+ }) }),
266
+ /* @__PURE__ */ l("g", {
267
+ fillOpacity: S,
268
+ style: { mixBlendMode: ce },
269
+ children: V.map((e, t) => {
270
+ let n = me(e), r = Z === null || e.source.index === Z || e.target.index === Z;
271
+ return /* @__PURE__ */ l(s, {
272
+ ...$,
273
+ title: /* @__PURE__ */ l(f, {
274
+ sourceName: n.source.name,
275
+ targetName: n.target.name,
276
+ sourceValue: n.source.value,
277
+ targetValue: n.target.value,
278
+ directed: w,
279
+ fmt: R
280
+ }),
281
+ children: /* @__PURE__ */ l("path", {
282
+ d: de(e),
283
+ fill: G(e.target.index),
284
+ stroke: "none",
285
+ opacity: r ? 1 : .12,
286
+ style: {
287
+ cursor: j ? "not-allowed" : "pointer",
288
+ transition: "opacity 0.15s"
289
+ },
290
+ onClick: (e) => !j && k?.(n, e)
291
+ })
292
+ }, `chord-tt-${t}`);
293
+ })
276
294
  })
277
- })]
295
+ ]
278
296
  })
279
297
  })
280
298
  });
@@ -68,7 +68,7 @@ export type ChordChartProps = {
68
68
  groupColorConfigs?: ChordGroupColorConfigs;
69
69
  /** Show group name labels outside the arc ring (default: true) */
70
70
  showGroupLabels?: boolean;
71
- /** Gap between arc outer edge and label text in px (default: 6) */
71
+ /** Gap between arc outer edge and label text in px (default: 8) */
72
72
  labelOffset?: number;
73
73
  /** Opacity of ribbons — 0 to 1 (default: 0.75) */
74
74
  ribbonOpacity?: number;
@@ -1,5 +1,5 @@
1
1
  import { type CirclePackingChartProps } from "./CirclePackingChart.types";
2
- export declare function CirclePackingChart({ data, size, padding, sortBy, showLabels, showAllLabels, labelFontSize, innerLabelFontSize, labelColor, chartColors, depthColorStart, depthColorEnd, background, duration, zoomable, disabled, onCircleClick, onZoomChange, }: CirclePackingChartProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function CirclePackingChart({ data, size, padding, sortBy, showLabels, showAllLabels, labelFontSize, innerLabelFontSize, labelColor, chartColors, depthColorStart, depthColorEnd, background, duration, zoomable, disabled, onCircleClick, onZoomChange, translation, }: CirclePackingChartProps): import("react/jsx-runtime").JSX.Element;
3
3
  export declare namespace CirclePackingChart {
4
4
  var displayName: string;
5
5
  }