@thebuoyant-tsdev/mui-ts-library 3.29.2 → 3.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.de.md +49 -1
  2. package/README.md +49 -1
  3. package/dist/components/chord-chart/ChordChart.js +112 -112
  4. package/dist/components/circle-packing-chart/CirclePackingChart.js +135 -135
  5. package/dist/components/color-picker/ColorPicker.js +217 -217
  6. package/dist/components/color-picker/PopoverColorPicker.js +7 -7
  7. package/dist/components/date-range-picker/DateRangePicker.js +9 -9
  8. package/dist/components/gantt-chart/GanttChart.js +18 -18
  9. package/dist/components/gantt-chart/GanttTaskDialog.js +43 -43
  10. package/dist/components/gantt-chart/GanttTaskPanel.js +128 -128
  11. package/dist/components/gantt-chart/GanttTimeline.js +16 -16
  12. package/dist/components/gantt-chart/GanttToolbar.js +24 -24
  13. package/dist/components/horizontal-tree-chart/HorizontalTreeChart.js +244 -244
  14. package/dist/components/json-editor/JsonEditor.js +9 -9
  15. package/dist/components/json-editor/JsonEditorContent.js +54 -54
  16. package/dist/components/json-editor/JsonEditorToolbar.js +12 -12
  17. package/dist/components/kanban-board/KanbanBoard.d.ts +2 -0
  18. package/dist/components/kanban-board/KanbanBoard.js +129 -0
  19. package/dist/components/kanban-board/KanbanBoard.types.d.ts +84 -0
  20. package/dist/components/kanban-board/KanbanBoard.types.js +19 -0
  21. package/dist/components/kanban-board/KanbanBoardCard.d.ts +13 -0
  22. package/dist/components/kanban-board/KanbanBoardCard.js +104 -0
  23. package/dist/components/kanban-board/KanbanBoardCardDialog.d.ts +23 -0
  24. package/dist/components/kanban-board/KanbanBoardCardDialog.js +120 -0
  25. package/dist/components/kanban-board/KanbanBoardColumn.d.ts +14 -0
  26. package/dist/components/kanban-board/KanbanBoardColumn.js +129 -0
  27. package/dist/components/kanban-board/kanbanBoardClasses.d.ts +47 -0
  28. package/dist/components/kanban-board/kanbanBoardClasses.js +18 -0
  29. package/dist/components/password-strength-meter/PasswordStrengthMeter.js +27 -27
  30. package/dist/components/radial-stacked-bar-chart/RadialStackedBarChart.js +48 -48
  31. package/dist/components/radial-tree-chart/RadialTreeChart.js +173 -173
  32. package/dist/components/rich-text-editor/RichTextEditor.js +32 -32
  33. package/dist/components/rich-text-editor/RichTextEditorColorPicker.js +20 -20
  34. package/dist/components/rich-text-editor/RichTextEditorEmojiPicker.js +12 -12
  35. package/dist/components/rich-text-editor/RichTextEditorImageDialog.js +11 -11
  36. package/dist/components/rich-text-editor/RichTextEditorLinkDialog.js +11 -11
  37. package/dist/components/rich-text-editor/RichTextEditorMarkdownDialog.js +14 -14
  38. package/dist/components/rich-text-editor/RichTextEditorMentionList.js +14 -14
  39. package/dist/components/rich-text-editor/RichTextEditorTableMenu.js +28 -28
  40. package/dist/components/rich-text-editor/RichTextEditorToolbar.js +35 -35
  41. package/dist/components/sql-editor/SqlEditor.js +24 -24
  42. package/dist/components/sql-editor/SqlEditorContent.js +16 -16
  43. package/dist/components/sql-editor/SqlEditorHistoryMenu.js +15 -15
  44. package/dist/components/sql-editor/SqlEditorToolbar.js +21 -21
  45. package/dist/components/sunburst-chart/SunburstChart.js +126 -126
  46. package/dist/components/tag-selection/TagSelection.js +18 -18
  47. package/dist/components/tag-selection/TagSelectionAutocomplete.js +120 -120
  48. package/dist/components/tag-selection/TagSelectionSelectedTags.js +10 -10
  49. package/dist/index.cjs +2 -2
  50. package/dist/index.d.cts +3 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.js +38 -35
  53. package/package.json +9 -2
package/README.de.md CHANGED
@@ -16,13 +16,14 @@ Eine typsichere React-Komponentenbibliothek auf Basis von **TypeScript** und **M
16
16
 
17
17
  ## Komponenten
18
18
 
19
- 13 produktionsreife Komponenten in drei Kategorien. Jede verlinkt zu einer interaktiven Live-Demo und einem vollständigen Manual mit allen Props, Typen und Mustern.
19
+ 15 produktionsreife Komponenten in drei Kategorien. Jede verlinkt zu einer interaktiven Live-Demo und einem vollständigen Manual mit allen Props, Typen und Mustern.
20
20
 
21
21
  ### Interaktive UI
22
22
 
23
23
  | Komponente | Wofür | Ausprobieren |
24
24
  |---|---|---|
25
25
  | [`GanttChart`](#ganttchart) | Drag-and-Drop-Projekt-Timelines mit Meilensteinen, Abhängigkeiten und CSV-Export | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-ganttchart--default) · [Docs](user-manuals/GanttChart.de.md) |
26
+ | [`KanbanBoard`](#kanbanboard) | Drag-and-Drop-Kanban-Board mit eingebauten CRUD-Dialogen, WIP-Limits und i18n | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-kanbanboard--default) · [Docs](user-manuals/KanbanBoard.de.md) |
26
27
  | [`DateRangePicker`](#daterangepicker) | Start- und Enddatum in einem Inline-Picker — schließt die MUI X Pro-Lücke, kostenlos und ohne zusätzliche Abhängigkeiten | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-daterangepicker--default) · [Docs](user-manuals/DateRangePicker.de.md) |
27
28
  | [`TagSelection`](#tagselection) | Multi-Tag-Autocomplete mit freier Tag-Erstellung und Suchergebnis-Highlighting | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-tagselection--default) · [Docs](user-manuals/TagSelection.de.md) |
28
29
  | [`PasswordStrengthMeter`](#passwordstrengthmeter) | Echtzeit-Stärke-Feedback mit eingebautem sicheren Passwort-Generator | [Live-Demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-passwordstrengthmeter--default) · [Docs](user-manuals/PasswordStrengthMeter.de.md) |
@@ -101,6 +102,43 @@ const tasks: GanttTask[] = [
101
102
 
102
103
  ---
103
104
 
105
+ ### KanbanBoard
106
+
107
+ Ein Drag-and-Drop-Kanban-Board mit eingebauten Hinzufügen-/Bearbeiten-/Löschen-Dialogen, WIP-Limits und vollständiger i18n. Ideal für Task-Management-Dashboards, Sprint-Boards oder jeden Workflow, bei dem Nutzer Aufgaben zwischen Statusspalten verschieben sollen — mit Kartenfarben, Zuständige-Person-Chips, Fälligkeitsdatum-Chips und konfigurierbarer Chip-Darstellung.
108
+
109
+ ```tsx
110
+ import { KanbanBoard } from '@thebuoyant-tsdev/mui-ts-library';
111
+ import type { KanbanColumn, KanbanTask } from '@thebuoyant-tsdev/mui-ts-library';
112
+ import { useState } from 'react';
113
+
114
+ const columns: KanbanColumn[] = [
115
+ { id: 'todo', label: 'Zu erledigen', color: '#9e9e9e' },
116
+ { id: 'in-progress', label: 'In Arbeit', color: '#2196f3' },
117
+ { id: 'done', label: 'Erledigt', color: '#4caf50' },
118
+ ];
119
+
120
+ function App() {
121
+ const [tasks, setTasks] = useState<KanbanTask[]>([
122
+ { id: '1', title: 'Projekt aufsetzen', status: 'todo', assignee: 'Alice' },
123
+ { id: '2', title: 'Feature umsetzen', status: 'in-progress', assignee: 'Bob', dueDate: new Date('2026-08-01') },
124
+ { id: '3', title: 'Tests schreiben', status: 'done' },
125
+ ]);
126
+
127
+ return (
128
+ <KanbanBoard
129
+ columns={columns}
130
+ tasks={tasks}
131
+ onTasksChange={setTasks}
132
+ height={500}
133
+ />
134
+ );
135
+ }
136
+ ```
137
+
138
+ → [Vollständige Dokumentation](user-manuals/KanbanBoard.de.md)
139
+
140
+ ---
141
+
104
142
  ### DateRangePicker
105
143
 
106
144
  Start- und Enddatum in einem einzigen Inline-Picker — kein MUI X Pro-Lizenz erforderlich. Entwickelt für Formulare, Filter und Buchungsflows. Unterstützt Controlled/Uncontrolled-Modus, `minDate`/`maxDate`, `required`, Inline-Validierung und vollständige i18n. `onChange` gibt für jedes Datum sowohl ein `Date`-Objekt als auch einen ISO-String zurück.
@@ -458,6 +496,9 @@ import type {
458
496
  // GanttChart
459
497
  GanttTask, GanttTranslations, GanttTheme, GanttToolbarConfig,
460
498
 
499
+ // KanbanBoard
500
+ KanbanTask, KanbanColumn, KanbanBoardProps, KanbanBoardTranslation,
501
+
461
502
  // DateRangePicker
462
503
  DateRange, DateRangeEntry, DateRangeInput, DateRangePickerProps, DateRangePickerTranslation,
463
504
 
@@ -514,6 +555,13 @@ Dieses Projekt folgt [Semantic Versioning](https://semver.org/):
514
555
 
515
556
  ## Changelog
516
557
 
558
+ ### [3.30.0] — 2026-07-17
559
+
560
+ **Hinzugefügt**
561
+ - **KanbanBoard** — neue Drag-and-Drop-Kanban-Board-Komponente mit eingebauten CRUD-Dialogen, WIP-Limits, Kartenfarben, Zuständige-Person- und Fälligkeitsdatum-Chips, `chipVariant`-Prop, vollständiger i18n und CSS-Klassen-API (`kanbanBoardClasses`). Siehe [Vollständiger Changelog](https://github.com/thebuoyant/mui-ts-library/blob/main/CHANGELOG.de.md) für Details.
562
+
563
+ ---
564
+
517
565
  ### [3.29.2] — 2026-07-16
518
566
 
519
567
  **Behoben**
package/README.md CHANGED
@@ -16,13 +16,14 @@ A type-safe React component library built on **TypeScript** and **MUI (Material
16
16
 
17
17
  ## Components
18
18
 
19
- 13 production-ready components across three categories. Each links to a live, interactive demo and a full manual covering every prop, type, and pattern.
19
+ 15 production-ready components across three categories. Each links to a live, interactive demo and a full manual covering every prop, type, and pattern.
20
20
 
21
21
  ### Interactive UI
22
22
 
23
23
  | Component | What it's for | Try it |
24
24
  |---|---|---|
25
25
  | [`GanttChart`](#ganttchart) | Drag-and-drop project timelines with milestones, dependencies, and CSV export | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-ganttchart--default) · [Docs](user-manuals/GanttChart.md) |
26
+ | [`KanbanBoard`](#kanbanboard) | Drag-and-drop Kanban board with built-in CRUD dialogs, WIP limits, and i18n | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-kanbanboard--default) · [Docs](user-manuals/KanbanBoard.md) |
26
27
  | [`DateRangePicker`](#daterangepicker) | Start + end date in one inline picker — fills the MUI X Pro gap, free and dependency-free | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-daterangepicker--default) · [Docs](user-manuals/DateRangePicker.md) |
27
28
  | [`TagSelection`](#tagselection) | Multi-tag autocomplete with free-form tag creation and search highlighting | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-tagselection--default) · [Docs](user-manuals/TagSelection.md) |
28
29
  | [`PasswordStrengthMeter`](#passwordstrengthmeter) | Real-time strength feedback with a built-in secure password generator | [Live demo](https://thebuoyant.github.io/mui-ts-library/?path=/story/components-passwordstrengthmeter--default) · [Docs](user-manuals/PasswordStrengthMeter.md) |
@@ -101,6 +102,43 @@ const tasks: GanttTask[] = [
101
102
 
102
103
  ---
103
104
 
105
+ ### KanbanBoard
106
+
107
+ A drag-and-drop Kanban board with built-in Add / Edit / Delete dialogs, WIP limits, and full i18n. Use it for task management dashboards, sprint boards, or any workflow where users move work items between status columns — with card colors, assignee chips, due-date chips, and a configurable chip style.
108
+
109
+ ```tsx
110
+ import { KanbanBoard } from '@thebuoyant-tsdev/mui-ts-library';
111
+ import type { KanbanColumn, KanbanTask } from '@thebuoyant-tsdev/mui-ts-library';
112
+ import { useState } from 'react';
113
+
114
+ const columns: KanbanColumn[] = [
115
+ { id: 'todo', label: 'To Do', color: '#9e9e9e' },
116
+ { id: 'in-progress', label: 'In Progress', color: '#2196f3' },
117
+ { id: 'done', label: 'Done', color: '#4caf50' },
118
+ ];
119
+
120
+ function App() {
121
+ const [tasks, setTasks] = useState<KanbanTask[]>([
122
+ { id: '1', title: 'Set up project', status: 'todo', assignee: 'Alice' },
123
+ { id: '2', title: 'Implement feature', status: 'in-progress', assignee: 'Bob', dueDate: new Date('2026-08-01') },
124
+ { id: '3', title: 'Write tests', status: 'done' },
125
+ ]);
126
+
127
+ return (
128
+ <KanbanBoard
129
+ columns={columns}
130
+ tasks={tasks}
131
+ onTasksChange={setTasks}
132
+ height={500}
133
+ />
134
+ );
135
+ }
136
+ ```
137
+
138
+ → [Full documentation](user-manuals/KanbanBoard.md)
139
+
140
+ ---
141
+
104
142
  ### DateRangePicker
105
143
 
106
144
  Start and end date in a single inline picker — no MUI X Pro license required. Built for forms, filters, and booking flows. Supports controlled/uncontrolled mode, `minDate`/`maxDate`, `required`, inline validation, and full i18n. `onChange` returns both a `Date` object and an ISO string for each date.
@@ -458,6 +496,9 @@ import type {
458
496
  // GanttChart
459
497
  GanttTask, GanttTranslations, GanttTheme, GanttToolbarConfig,
460
498
 
499
+ // KanbanBoard
500
+ KanbanTask, KanbanColumn, KanbanBoardProps, KanbanBoardTranslation,
501
+
461
502
  // DateRangePicker
462
503
  DateRange, DateRangeEntry, DateRangeInput, DateRangePickerProps, DateRangePickerTranslation,
463
504
 
@@ -514,6 +555,13 @@ This project follows [Semantic Versioning](https://semver.org/):
514
555
 
515
556
  ## Changelog
516
557
 
558
+ ### [3.30.0] — 2026-07-17
559
+
560
+ **Added**
561
+ - **KanbanBoard** — new drag-and-drop Kanban board component with built-in Add / Edit / Delete dialogs, WIP limits, card colors, assignee and due-date chips, `chipVariant` prop, full i18n, and a CSS classes API (`kanbanBoardClasses`). See [Full Changelog](https://github.com/thebuoyant/mui-ts-library/blob/main/CHANGELOG.md) for details.
562
+
563
+ ---
564
+
517
565
  ### [3.29.2] — 2026-07-16
518
566
 
519
567
  **Fixed**
@@ -1,19 +1,19 @@
1
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 l } from "@mui/material";
4
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
5
- import * as f from "d3";
2
+ import { Box as t, Tooltip as n, Typography as r, useTheme as i } from "@mui/material";
3
+ import { useCallback as a, useLayoutEffect as o, useMemo as s, useRef as ee, useState as c } from "react";
4
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ import * as d from "d3";
6
6
  //#region src/components/chord-chart/ChordChart.tsx
7
- function p(e, t = 0, n = ".", r = ",") {
7
+ function te(e, t = 0, n = ".", r = ",") {
8
8
  if (!isFinite(e)) return String(e);
9
9
  let [i, a] = e.toFixed(Math.max(0, t)).split("."), o = i.replace(/\B(?=(\d{3})+(?!\d))/g, r);
10
10
  return a ? `${o}${n}${a}` : o;
11
11
  }
12
- function m({ name: e, valueOut: t, valueIn: n, fmt: r }) {
13
- return /* @__PURE__ */ d(o, {
12
+ function f({ name: e, valueOut: n, valueIn: i, fmt: a }) {
13
+ return /* @__PURE__ */ u(t, {
14
14
  sx: { py: .25 },
15
15
  children: [
16
- /* @__PURE__ */ u(c, {
16
+ /* @__PURE__ */ l(r, {
17
17
  variant: "caption",
18
18
  sx: {
19
19
  fontWeight: "bold",
@@ -21,30 +21,30 @@ function m({ name: e, valueOut: t, valueIn: n, fmt: r }) {
21
21
  },
22
22
  children: e
23
23
  }),
24
- /* @__PURE__ */ d(c, {
24
+ /* @__PURE__ */ u(r, {
25
25
  variant: "caption",
26
26
  sx: {
27
27
  display: "block",
28
28
  opacity: .85
29
29
  },
30
- children: [r(t), " outgoing →"]
30
+ children: [a(n), " outgoing →"]
31
31
  }),
32
- /* @__PURE__ */ d(c, {
32
+ /* @__PURE__ */ u(r, {
33
33
  variant: "caption",
34
34
  sx: {
35
35
  display: "block",
36
36
  opacity: .85
37
37
  },
38
- children: [r(n), " incoming ←"]
38
+ children: [a(i), " incoming ←"]
39
39
  })
40
40
  ]
41
41
  });
42
42
  }
43
- function h({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, directed: i, fmt: a }) {
44
- return /* @__PURE__ */ d(o, {
43
+ function p({ sourceName: e, targetName: n, sourceValue: i, targetValue: a, directed: o, fmt: s }) {
44
+ return /* @__PURE__ */ u(t, {
45
45
  sx: { py: .25 },
46
46
  children: [
47
- /* @__PURE__ */ d(c, {
47
+ /* @__PURE__ */ u(r, {
48
48
  variant: "caption",
49
49
  sx: {
50
50
  fontWeight: "bold",
@@ -53,18 +53,18 @@ function h({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, direc
53
53
  children: [
54
54
  e,
55
55
  " → ",
56
- t
56
+ n
57
57
  ]
58
58
  }),
59
- /* @__PURE__ */ u(c, {
59
+ /* @__PURE__ */ l(r, {
60
60
  variant: "caption",
61
61
  sx: {
62
62
  display: "block",
63
63
  opacity: .85
64
64
  },
65
- children: a(n)
65
+ children: s(i)
66
66
  }),
67
- i && r > 0 && r !== n && /* @__PURE__ */ d(c, {
67
+ o && a > 0 && a !== i && /* @__PURE__ */ u(r, {
68
68
  variant: "caption",
69
69
  sx: {
70
70
  display: "block",
@@ -72,56 +72,56 @@ function h({ sourceName: e, targetName: t, sourceValue: n, targetValue: r, direc
72
72
  mt: .25
73
73
  },
74
74
  children: [
75
- t,
75
+ n,
76
76
  " → ",
77
77
  e,
78
78
  ": ",
79
- a(r)
79
+ s(a)
80
80
  ]
81
81
  })
82
82
  ]
83
83
  });
84
84
  }
85
- function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, padAngle: te, ribbonPadAngle: ne, sortSubgroups: v = "descending", sortChords: y = "descending", chartColors: b, groupColorConfigs: x, showGroupLabels: re = !0, labelOffset: ie = 8, ribbonOpacity: ae = .75, ribbonBlendMode: oe, directed: S = !0, valueDecimalCount: C = 0, valueDecimalSeparator: w = ".", valueThousandsSeparator: T = ",", valueFormatter: E, onGroupClick: D, onGroupHover: O, onChordClick: k, onChordHover: A, zoomable: j = !1, disabled: M = !1, translation: se }) {
86
- let N = l(), ce = {
85
+ function m({ data: r, size: m = 500, innerRadius: h, ringThickness: g = 20, padAngle: ne, ribbonPadAngle: re, sortSubgroups: _ = "descending", sortChords: v = "descending", chartColors: y, groupColorConfigs: b, showGroupLabels: ie = !0, labelOffset: ae = 8, ribbonOpacity: oe = .75, ribbonBlendMode: se, directed: x = !0, valueDecimalCount: S = 0, valueDecimalSeparator: C = ".", valueThousandsSeparator: w = ",", valueFormatter: T, onGroupClick: E, onGroupHover: D, onChordClick: O, onChordHover: k, zoomable: A = !1, disabled: j = !1, translation: ce }) {
86
+ let M = i(), le = {
87
87
  ...e,
88
- ...se
89
- }, le = c.length === 0, ue = oe ?? (N.palette.mode === "dark" ? "normal" : "multiply"), de = [
90
- N.palette.primary.main,
91
- N.palette.secondary.main,
92
- N.palette.error.main,
93
- N.palette.warning.main,
94
- N.palette.success.main,
95
- N.palette.info.main
96
- ], P = b && b.length > 0 ? b : de, fe = _ ?? Math.min(g, g) * .5 - 90, F = Math.max(10, fe), I = F + Math.max(1, ee), L = te ?? 10 / F, R = ne ?? 1 / F, z = t((e) => E ? E(e) : p(e, C, w, T), [
97
- E,
88
+ ...ce
89
+ }, ue = r.length === 0, de = se ?? (M.palette.mode === "dark" ? "normal" : "multiply"), fe = [
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 : fe, P = h ?? Math.min(m, m) * .5 - 90, F = Math.max(10, P), I = F + Math.max(1, g), L = ne ?? 10 / F, R = re ?? 1 / F, z = a((e) => T ? T(e) : te(e, S, C, w), [
97
+ T,
98
+ S,
98
99
  C,
99
- w,
100
- T
101
- ]), { names: B, matrix: V } = r(() => {
102
- let e = f.sort(f.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));
103
- for (let { source: e, target: r, value: i } of c) {
104
- let a = t.get(e), o = t.get(r);
105
- a == null || o == null || (n[a][o] += i);
100
+ w
101
+ ]), { names: B, matrix: V } = s(() => {
102
+ let e = d.sort(d.union(r.map((e) => e.source), r.map((e) => e.target))), t = new Map(e.map((e, t) => [e, t])), n = Array.from({ length: e.length }, () => Array(e.length).fill(0));
103
+ for (let { source: e, target: i, value: a } of r) {
104
+ let r = t.get(e), o = t.get(i);
105
+ r == null || o == null || (n[r][o] += a);
106
106
  }
107
107
  return {
108
108
  names: e,
109
109
  matrix: n
110
110
  };
111
- }, [c]), H = r(() => {
112
- let e = (S ? f.chordDirected() : f.chord()).padAngle(L);
113
- return v === "ascending" && (e = e.sortSubgroups(f.ascending)), v === "descending" && (e = e.sortSubgroups(f.descending)), y === "ascending" && (e = e.sortChords(f.ascending)), y === "descending" && (e = e.sortChords(f.descending)), e(V);
111
+ }, [r]), H = s(() => {
112
+ let e = (x ? d.chordDirected() : d.chord()).padAngle(L);
113
+ 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(V);
114
114
  }, [
115
115
  V,
116
116
  L,
117
- S,
118
- v,
119
- y
120
- ]), pe = r(() => f.arc().innerRadius(F).outerRadius(I), [F, I]), U = r(() => (S ? f.ribbonArrow() : f.ribbon()).radius(F - 1).padAngle(R), [
117
+ x,
118
+ _,
119
+ v
120
+ ]), pe = s(() => d.arc().innerRadius(F).outerRadius(I), [F, I]), U = s(() => (x ? d.ribbonArrow() : d.ribbon()).radius(F - 1).padAngle(R), [
121
121
  F,
122
122
  R,
123
- S
124
- ]), me = t((e) => U({
123
+ x
124
+ ]), me = a((e) => U({
125
125
  source: {
126
126
  startAngle: e.source.startAngle,
127
127
  endAngle: e.source.endAngle,
@@ -132,16 +132,16 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
132
132
  endAngle: e.target.endAngle,
133
133
  radius: F - 1
134
134
  }
135
- }) ?? "", [U, F]), W = r(() => f.scaleOrdinal().domain(f.range(B.length)).range(P.length >= B.length ? P : [...Array(Math.ceil(B.length / P.length))].flatMap(() => P).slice(0, B.length)), [P, B.length]), G = t((e) => x?.[B[e]]?.fill ?? W(e), [
136
- x,
135
+ }) ?? "", [U, F]), W = s(() => d.scaleOrdinal().domain(d.range(B.length)).range(N.length >= B.length ? N : [...Array(Math.ceil(B.length / N.length))].flatMap(() => N).slice(0, B.length)), [N, B.length]), G = a((e) => b?.[B[e]]?.fill ?? W(e), [
136
+ b,
137
137
  B,
138
138
  W
139
- ]), K = i(null), [q, J] = a(`-${g / 2} -${g / 2} ${g} ${g}`), [Y, X] = a(1), he = r(() => {
139
+ ]), K = ee(null), [q, J] = c(`-${m / 2} -${m / 2} ${m} ${m}`), [Y, X] = c(1), he = s(() => {
140
140
  if (Y === 1) return q;
141
141
  let [e, t, n, r] = q.split(" ").map(Number), i = n / Y, a = r / Y;
142
142
  return `${e + (n - i) / 2} ${t + (r - a) / 2} ${i} ${a}`;
143
143
  }, [q, Y]);
144
- n(() => {
144
+ o(() => {
145
145
  let e = K.current;
146
146
  if (!e) return;
147
147
  let t = requestAnimationFrame(() => {
@@ -149,27 +149,27 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
149
149
  let t = e.getBBox();
150
150
  J(`${t.x - 8} ${t.y - 8} ${t.width + 16} ${t.height + 16}`);
151
151
  } catch {
152
- J(`-${g / 2} -${g / 2} ${g} ${g}`);
152
+ J(`-${m / 2} -${m / 2} ${m} ${m}`);
153
153
  }
154
154
  });
155
155
  return () => cancelAnimationFrame(t);
156
156
  }, [
157
- g,
157
+ m,
158
158
  F,
159
159
  I,
160
160
  B.length,
161
161
  H
162
162
  ]);
163
- let [Z, Q] = a(null), ge = t((e) => ({
163
+ let [Z, Q] = c(null), ge = a((e) => ({
164
164
  name: B[e.index],
165
165
  index: e.index,
166
- valueOut: f.sum(H, (t) => (t.source.index === e.index ? t.source.value : 0) + (!S && t.target.index === e.index ? t.target.value : 0)),
167
- valueIn: f.sum(H, (t) => (t.target.index === e.index ? t.source.value : 0) + (!S && t.source.index === e.index ? t.target.value : 0))
166
+ valueOut: d.sum(H, (t) => (t.source.index === e.index ? t.source.value : 0) + (!x && t.target.index === e.index ? t.target.value : 0)),
167
+ valueIn: d.sum(H, (t) => (t.target.index === e.index ? t.source.value : 0) + (!x && t.source.index === e.index ? t.target.value : 0))
168
168
  }), [
169
169
  B,
170
170
  H,
171
- S
172
- ]), _e = t((e) => ({
171
+ x
172
+ ]), _e = a((e) => ({
173
173
  source: {
174
174
  name: B[e.source.index],
175
175
  index: e.source.index,
@@ -182,81 +182,81 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
182
182
  }
183
183
  }), [B]), ve = (e) => {
184
184
  let t = (e.startAngle + e.endAngle) / 2, n = t * 180 / Math.PI - 90, r = t > Math.PI ? " rotate(180)" : "";
185
- return `rotate(${n}) translate(${I + ie})${r}`;
186
- }, ye = (e) => (e.startAngle + e.endAngle) / 2 > Math.PI ? "end" : "start", be = t((e) => {
187
- if (!j || M || !e.ctrlKey) return;
185
+ return `rotate(${n}) translate(${I + ae})${r}`;
186
+ }, ye = (e) => (e.startAngle + e.endAngle) / 2 > Math.PI ? "end" : "start", be = a((e) => {
187
+ if (!A || j || !e.ctrlKey) return;
188
188
  e.preventDefault();
189
189
  let t = e.deltaY < 0 ? 1.15 : 1 / 1.15;
190
190
  X((e) => Math.max(.25, Math.min(8, e * t)));
191
- }, [j, M]);
192
- n(() => {
193
- if (!j) return;
191
+ }, [A, j]);
192
+ o(() => {
193
+ if (!A) return;
194
194
  let e = (e) => {
195
195
  e.key === "Escape" && X(1);
196
196
  };
197
197
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
198
- }, [j]);
198
+ }, [A]);
199
199
  let $ = {
200
200
  followCursor: !0,
201
201
  enterDelay: 50,
202
202
  enterNextDelay: 0,
203
- disableHoverListener: M,
203
+ disableHoverListener: j,
204
204
  slotProps: { tooltip: { sx: { maxWidth: 240 } } }
205
- }, xe = N.palette.text.primary, Se = N.typography.fontFamily;
206
- return /* @__PURE__ */ u(o, {
205
+ }, xe = M.palette.text.primary, Se = M.typography.fontFamily;
206
+ return /* @__PURE__ */ l(t, {
207
207
  sx: {
208
208
  display: "inline-flex",
209
- opacity: M ? .5 : 1,
210
- cursor: M ? "not-allowed" : "default",
209
+ opacity: j ? .5 : 1,
210
+ cursor: j ? "not-allowed" : "default",
211
211
  userSelect: "none"
212
212
  },
213
- children: /* @__PURE__ */ u("svg", {
214
- width: g,
215
- height: g,
213
+ children: /* @__PURE__ */ l("svg", {
214
+ width: m,
215
+ height: m,
216
216
  viewBox: he,
217
217
  onWheel: be,
218
218
  style: {
219
219
  fontFamily: Se ?? "sans-serif",
220
- overflow: j && Y > 1 ? "hidden" : "visible"
220
+ overflow: A && Y > 1 ? "hidden" : "visible"
221
221
  },
222
222
  role: "img",
223
223
  "aria-label": "Chord chart",
224
- children: /* @__PURE__ */ d("g", {
224
+ children: /* @__PURE__ */ u("g", {
225
225
  ref: K,
226
226
  children: [
227
- le && /* @__PURE__ */ u("text", {
227
+ ue && /* @__PURE__ */ l("text", {
228
228
  textAnchor: "middle",
229
229
  dy: "0.35em",
230
230
  fontSize: 13,
231
- fill: N.palette.text.secondary,
232
- children: ce.noData
231
+ fill: M.palette.text.secondary,
232
+ children: le.noData
233
233
  }),
234
- /* @__PURE__ */ u("g", { children: H.groups.map((e) => {
235
- let t = ge(e), n = Z === e.index, r = Z !== null && !n;
236
- return /* @__PURE__ */ u(s, {
234
+ /* @__PURE__ */ l("g", { children: H.groups.map((e) => {
235
+ let t = ge(e), r = Z === e.index, i = Z !== null && !r;
236
+ return /* @__PURE__ */ l(n, {
237
237
  ...$,
238
- title: /* @__PURE__ */ u(m, {
238
+ title: /* @__PURE__ */ l(f, {
239
239
  name: t.name,
240
240
  valueOut: t.valueOut,
241
241
  valueIn: t.valueIn,
242
242
  fmt: z
243
243
  }),
244
- children: /* @__PURE__ */ d("g", {
245
- style: { cursor: M ? "not-allowed" : "pointer" },
244
+ children: /* @__PURE__ */ u("g", {
245
+ style: { cursor: j ? "not-allowed" : "pointer" },
246
246
  onMouseEnter: (n) => {
247
- M || (Q(e.index), O?.(t, n));
247
+ j || (Q(e.index), D?.(t, n));
248
248
  },
249
249
  onMouseLeave: (e) => {
250
- Q(null), O?.(null, e);
250
+ Q(null), D?.(null, e);
251
251
  },
252
- onClick: (e) => !M && D?.(t, e),
253
- children: [/* @__PURE__ */ u("path", {
252
+ onClick: (e) => !j && E?.(t, e),
253
+ children: [/* @__PURE__ */ l("path", {
254
254
  d: pe(e) || "",
255
255
  fill: G(e.index),
256
- stroke: N.palette.divider,
257
- opacity: r ? .35 : 1,
256
+ stroke: M.palette.divider,
257
+ opacity: i ? .35 : 1,
258
258
  style: { transition: "opacity 0.15s" }
259
- }), re && /* @__PURE__ */ u("text", {
259
+ }), ie && /* @__PURE__ */ l("text", {
260
260
  dy: "0.35em",
261
261
  fontSize: 11,
262
262
  fill: xe,
@@ -268,37 +268,37 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
268
268
  })
269
269
  }, `grp-tt-${e.index}`);
270
270
  }) }),
271
- /* @__PURE__ */ u("g", {
272
- fillOpacity: ae,
273
- style: { mixBlendMode: ue },
271
+ /* @__PURE__ */ l("g", {
272
+ fillOpacity: oe,
273
+ style: { mixBlendMode: de },
274
274
  children: H.map((e, t) => {
275
- let n = _e(e), r = Z === null || e.source.index === Z || e.target.index === Z;
276
- return /* @__PURE__ */ u(s, {
275
+ let r = _e(e), i = Z === null || e.source.index === Z || e.target.index === Z;
276
+ return /* @__PURE__ */ l(n, {
277
277
  ...$,
278
- title: /* @__PURE__ */ u(h, {
279
- sourceName: n.source.name,
280
- targetName: n.target.name,
281
- sourceValue: n.source.value,
282
- targetValue: n.target.value,
283
- directed: S,
278
+ title: /* @__PURE__ */ l(p, {
279
+ sourceName: r.source.name,
280
+ targetName: r.target.name,
281
+ sourceValue: r.source.value,
282
+ targetValue: r.target.value,
283
+ directed: x,
284
284
  fmt: z
285
285
  }),
286
- children: /* @__PURE__ */ u("path", {
286
+ children: /* @__PURE__ */ l("path", {
287
287
  d: me(e),
288
288
  fill: G(e.target.index),
289
289
  stroke: "none",
290
- opacity: r ? 1 : .12,
290
+ opacity: i ? 1 : .12,
291
291
  style: {
292
- cursor: M ? "not-allowed" : "pointer",
292
+ cursor: j ? "not-allowed" : "pointer",
293
293
  transition: "opacity 0.15s"
294
294
  },
295
295
  onMouseEnter: (e) => {
296
- M || A?.(n, e);
296
+ j || k?.(r, e);
297
297
  },
298
298
  onMouseLeave: (e) => {
299
- A?.(null, e);
299
+ k?.(null, e);
300
300
  },
301
- onClick: (e) => !M && k?.(n, e)
301
+ onClick: (e) => !j && O?.(r, e)
302
302
  })
303
303
  }, `chord-tt-${t}`);
304
304
  })
@@ -308,6 +308,6 @@ function g({ data: c, size: g = 500, innerRadius: _, ringThickness: ee = 20, pad
308
308
  })
309
309
  });
310
310
  }
311
- g.displayName = "ChordChart";
311
+ m.displayName = "ChordChart";
312
312
  //#endregion
313
- export { g as ChordChart };
313
+ export { m as ChordChart };