@acronis-platform/ui-react 0.58.0 → 0.61.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 (118) hide show
  1. package/README.md +5 -5
  2. package/dist/components/ui/app-shell/app-shell.js.map +1 -1
  3. package/dist/components/ui/area-chart/area-chart.js +210 -119
  4. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  5. package/dist/components/ui/avatar/avatar.js +26 -23
  6. package/dist/components/ui/avatar/avatar.js.map +1 -1
  7. package/dist/components/ui/bar-chart/bar-chart.js +595 -149
  8. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  9. package/dist/components/ui/calendar/calendar.js +17 -15
  10. package/dist/components/ui/calendar/calendar.js.map +1 -1
  11. package/dist/components/ui/carousel-dialog/carousel-dialog.js +87 -0
  12. package/dist/components/ui/carousel-dialog/carousel-dialog.js.map +1 -0
  13. package/dist/components/ui/category-bar/category-bar.js +147 -0
  14. package/dist/components/ui/category-bar/category-bar.js.map +1 -0
  15. package/dist/components/ui/chart/chart-format.js +170 -0
  16. package/dist/components/ui/chart/chart-format.js.map +1 -0
  17. package/dist/components/ui/chart/chart.js +204 -150
  18. package/dist/components/ui/chart/chart.js.map +1 -1
  19. package/dist/components/ui/composed-chart/composed-chart.js +423 -98
  20. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  21. package/dist/components/ui/confidence-cone/confidence-cone.js +306 -172
  22. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  23. package/dist/components/ui/dialog/dialog.js +29 -29
  24. package/dist/components/ui/dialog/dialog.js.map +1 -1
  25. package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js +57 -0
  26. package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js.map +1 -0
  27. package/dist/components/ui/dialog-footer-default/dialog-footer-default.js +1 -1
  28. package/dist/components/ui/dialog-footer-default/dialog-footer-default.js.map +1 -1
  29. package/dist/components/ui/dialog-welcome/dialog-welcome.js +272 -0
  30. package/dist/components/ui/dialog-welcome/dialog-welcome.js.map +1 -0
  31. package/dist/components/ui/funnel-chart/funnel-chart.js +245 -51
  32. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  33. package/dist/components/ui/histogram/histogram.js +96 -64
  34. package/dist/components/ui/histogram/histogram.js.map +1 -1
  35. package/dist/components/ui/input/input.js.map +1 -1
  36. package/dist/components/ui/line-chart/line-chart.js +230 -159
  37. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  38. package/dist/components/ui/metric/metric.js +88 -70
  39. package/dist/components/ui/metric/metric.js.map +1 -1
  40. package/dist/components/ui/pie-chart/pie-chart.js +234 -80
  41. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  42. package/dist/components/ui/radar-chart/radar-chart.js +210 -57
  43. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  44. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +358 -50
  45. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  46. package/dist/components/ui/sankey-chart/sankey-chart.js +199 -0
  47. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -0
  48. package/dist/components/ui/scatter-chart/scatter-chart.js +86 -50
  49. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  50. package/dist/components/ui/timeline/timeline.js +206 -142
  51. package/dist/components/ui/timeline/timeline.js.map +1 -1
  52. package/dist/components/ui/toolbar/toolbar.js +82 -92
  53. package/dist/components/ui/toolbar/toolbar.js.map +1 -1
  54. package/dist/components/ui/treemap/treemap.js +183 -59
  55. package/dist/components/ui/treemap/treemap.js.map +1 -1
  56. package/dist/index.js +481 -439
  57. package/dist/index.js.map +1 -1
  58. package/dist/lib/breakpoints.js +9 -6
  59. package/dist/lib/breakpoints.js.map +1 -1
  60. package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js +25 -0
  61. package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js.map +1 -0
  62. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +36 -0
  63. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +1 -0
  64. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +1205 -0
  65. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +1 -0
  66. package/dist/react.js +481 -439
  67. package/dist/react.js.map +1 -1
  68. package/dist/src/components/ui/area-chart/area-chart.d.ts +52 -17
  69. package/dist/src/components/ui/area-chart/index.d.ts +1 -1
  70. package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
  71. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +152 -29
  72. package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
  73. package/dist/src/components/ui/button/button.d.ts +1 -1
  74. package/dist/src/components/ui/button-menu/button-menu.d.ts +1 -1
  75. package/dist/src/components/ui/carousel-dialog/carousel-dialog.d.ts +28 -0
  76. package/dist/src/components/ui/carousel-dialog/index.d.ts +1 -0
  77. package/dist/src/components/ui/category-bar/category-bar.d.ts +51 -0
  78. package/dist/src/components/ui/category-bar/index.d.ts +1 -0
  79. package/dist/src/components/ui/chart/__tests__/chart-format.test.d.ts +1 -0
  80. package/dist/src/components/ui/chart/__tests__/chart-layout.d.ts +63 -0
  81. package/dist/src/components/ui/chart/__tests__/chart-layout.test.d.ts +1 -0
  82. package/dist/src/components/ui/chart/chart-format.d.ts +526 -0
  83. package/dist/src/components/ui/chart/chart.d.ts +11 -3
  84. package/dist/src/components/ui/chart/index.d.ts +3 -1
  85. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +154 -20
  86. package/dist/src/components/ui/composed-chart/index.d.ts +1 -1
  87. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +138 -37
  88. package/dist/src/components/ui/confidence-cone/index.d.ts +1 -1
  89. package/dist/src/components/ui/dialog-footer-carousel/dialog-footer-carousel.d.ts +9 -0
  90. package/dist/src/components/ui/dialog-footer-carousel/index.d.ts +1 -0
  91. package/dist/src/components/ui/dialog-welcome/dialog-welcome.d.ts +54 -0
  92. package/dist/src/components/ui/dialog-welcome/dialog-welcome.docs.d.ts +55 -0
  93. package/dist/src/components/ui/dialog-welcome/index.d.ts +1 -0
  94. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +201 -3
  95. package/dist/src/components/ui/funnel-chart/index.d.ts +1 -1
  96. package/dist/src/components/ui/histogram/histogram.d.ts +2 -17
  97. package/dist/src/components/ui/line-chart/index.d.ts +1 -1
  98. package/dist/src/components/ui/line-chart/line-chart.d.ts +50 -17
  99. package/dist/src/components/ui/pie-chart/index.d.ts +1 -1
  100. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +145 -4
  101. package/dist/src/components/ui/radar-chart/index.d.ts +1 -1
  102. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +219 -6
  103. package/dist/src/components/ui/radial-bar-chart/index.d.ts +1 -1
  104. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +215 -9
  105. package/dist/src/components/ui/sankey-chart/index.d.ts +2 -0
  106. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +69 -0
  107. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +2 -17
  108. package/dist/src/components/ui/timeline/index.d.ts +1 -1
  109. package/dist/src/components/ui/timeline/timeline.d.ts +79 -20
  110. package/dist/src/components/ui/treemap/index.d.ts +1 -1
  111. package/dist/src/components/ui/treemap/treemap.d.ts +68 -8
  112. package/dist/src/index.d.ts +5 -1
  113. package/dist/ui-react.css +1 -1
  114. package/package.json +5 -4
  115. package/dist/components/ui/search-global/search-global.js +0 -60
  116. package/dist/components/ui/search-global/search-global.js.map +0 -1
  117. package/dist/src/components/ui/search-global/index.d.ts +0 -1
  118. package/dist/src/components/ui/search-global/search-global.d.ts +0 -7
@@ -0,0 +1,272 @@
1
+ import { jsx as e, jsxs as w, Fragment as L } from "react/jsx-runtime";
2
+ import * as c from "react";
3
+ import U from "../../../node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js";
4
+ import { cn as _ } from "../../../lib/utils.js";
5
+ import { useDocDir as q } from "../../../lib/use-doc-dir.js";
6
+ import { DialogRoot as G, DialogContent as H, DialogClose as J, DialogTitle as K, DialogDescription as O } from "../dialog/dialog.js";
7
+ import { DialogFooterCarousel as Q } from "../dialog-footer-carousel/dialog-footer-carousel.js";
8
+ import { Button as M } from "../button/button.js";
9
+ function F({
10
+ image: s,
11
+ title: l,
12
+ description: r,
13
+ active: a,
14
+ withBottomPadding: i = !0
15
+ }) {
16
+ return /* @__PURE__ */ w(
17
+ "div",
18
+ {
19
+ className: _(
20
+ "flex w-full flex-col items-center gap-3 pt-4",
21
+ i && "pb-4"
22
+ ),
23
+ children: [
24
+ /* @__PURE__ */ e("div", { className: "w-full overflow-hidden rounded-lg px-4", children: /* @__PURE__ */ e("div", { className: "flex h-[272px] w-full items-center justify-center rounded bg-[var(--ui-background-surface-active)]", children: s }) }),
25
+ /* @__PURE__ */ w("div", { className: "flex w-full flex-col items-center gap-1 px-4 text-center", children: [
26
+ a ? /* @__PURE__ */ e(K, { className: "w-full flex-none text-center", children: l }) : /* @__PURE__ */ e("p", { className: "w-full text-2xl font-normal leading-8 text-foreground", children: l }),
27
+ a ? /* @__PURE__ */ e(O, { className: "w-full flex-none text-center text-sm leading-6 text-foreground", children: r }) : /* @__PURE__ */ e("p", { className: "w-full text-sm leading-6 text-foreground", children: r })
28
+ ] })
29
+ ]
30
+ }
31
+ );
32
+ }
33
+ const E = [
34
+ { title: "Title", description: "Feature description." },
35
+ { title: "Title", description: "Feature description." },
36
+ { title: "Title", description: "Feature description." }
37
+ ];
38
+ function X({
39
+ slideCount: s,
40
+ selectedIndexProp: l,
41
+ onSelectedIndexChange: r
42
+ }) {
43
+ const a = q(), i = l !== void 0, d = Math.min(
44
+ Math.max(l ?? 0, 0),
45
+ Math.max(s - 1, 0)
46
+ ), [p, t] = U({
47
+ loop: !1,
48
+ direction: a,
49
+ startIndex: d
50
+ }), [v, N] = c.useState(0), o = Math.min(
51
+ Math.max(l ?? v, 0),
52
+ Math.max(s - 1, 0)
53
+ ), f = c.useRef(r);
54
+ c.useEffect(() => {
55
+ f.current = r;
56
+ }, [r]);
57
+ const m = c.useRef(i);
58
+ m.current = i;
59
+ const n = c.useRef(o);
60
+ n.current = o, c.useEffect(() => {
61
+ if (!t) return;
62
+ const u = () => {
63
+ var x;
64
+ const h = t.selectedScrollSnap();
65
+ if (m.current) {
66
+ if (!f.current) {
67
+ h !== n.current && t.scrollTo(n.current, !0);
68
+ return;
69
+ }
70
+ h !== n.current && f.current(h);
71
+ return;
72
+ }
73
+ N(h), (x = f.current) == null || x.call(f, h);
74
+ };
75
+ return u(), t.on("select", u), t.on("reInit", u), () => {
76
+ t.off("select", u), t.off("reInit", u);
77
+ };
78
+ }, [t]), c.useEffect(() => {
79
+ l === void 0 || !t || t.selectedScrollSnap() !== o && t.scrollTo(o, !0);
80
+ }, [t, l, o]);
81
+ const D = c.useRef(!0);
82
+ c.useEffect(() => {
83
+ if (t) {
84
+ if (D.current) {
85
+ D.current = !1;
86
+ return;
87
+ }
88
+ t.reInit({ direction: a });
89
+ }
90
+ }, [t, a]);
91
+ const R = c.useCallback(
92
+ (u) => {
93
+ i ? r == null || r(u) : t == null || t.scrollTo(u);
94
+ },
95
+ [i, t, r]
96
+ ), g = c.useCallback(() => {
97
+ i ? r == null || r(Math.max(o - 1, 0)) : t == null || t.scrollPrev();
98
+ }, [i, t, r, o]), k = c.useCallback(() => {
99
+ i ? r == null || r(Math.min(o + 1, s - 1)) : t == null || t.scrollNext();
100
+ }, [i, t, r, o, s]), T = o === s - 1 ? "end" : o === 0 ? "start" : "middle";
101
+ return {
102
+ emblaRef: p,
103
+ selectedIndex: o,
104
+ handleSelectIndex: R,
105
+ handleBack: g,
106
+ handleNext: k,
107
+ footerVariant: T
108
+ };
109
+ }
110
+ function Y({
111
+ slides: s,
112
+ selectedIndex: l,
113
+ emblaRef: r,
114
+ footerVariant: a,
115
+ onSelectIndex: i,
116
+ onBack: d,
117
+ onNext: p,
118
+ onPrimaryAction: t,
119
+ backLabel: v,
120
+ nextLabel: N,
121
+ primaryLabel: o,
122
+ goToSlideLabel: f
123
+ }) {
124
+ return /* @__PURE__ */ w(L, { children: [
125
+ /* @__PURE__ */ e("div", { ref: r, className: "w-full overflow-hidden", children: /* @__PURE__ */ e("div", { className: "flex", children: s.map((m, n) => /* @__PURE__ */ e(
126
+ "div",
127
+ {
128
+ className: "min-w-0 shrink-0 grow-0 basis-full",
129
+ "aria-hidden": n !== l || void 0,
130
+ inert: n !== l,
131
+ children: /* @__PURE__ */ e(
132
+ F,
133
+ {
134
+ image: m.image,
135
+ title: m.title,
136
+ description: m.description,
137
+ active: n === l
138
+ }
139
+ )
140
+ },
141
+ n
142
+ )) }) }),
143
+ /* @__PURE__ */ e(
144
+ Q,
145
+ {
146
+ variant: a,
147
+ slideCount: s.length,
148
+ selectedIndex: l,
149
+ onSelectIndex: i,
150
+ onBack: d,
151
+ onNext: p,
152
+ onPrimaryAction: t,
153
+ backLabel: v,
154
+ nextLabel: N,
155
+ primaryLabel: o,
156
+ goToSlideLabel: f
157
+ }
158
+ )
159
+ ] });
160
+ }
161
+ function Z({
162
+ image: s,
163
+ title: l,
164
+ description: r,
165
+ primaryLabel: a,
166
+ onPrimaryAction: i,
167
+ closeLabel: d,
168
+ onCloseAction: p
169
+ }) {
170
+ return /* @__PURE__ */ w("div", { className: "flex w-full flex-col items-center gap-3 pb-4", children: [
171
+ /* @__PURE__ */ e(
172
+ F,
173
+ {
174
+ image: s,
175
+ title: l,
176
+ description: r,
177
+ active: !0,
178
+ withBottomPadding: !1
179
+ }
180
+ ),
181
+ /* @__PURE__ */ w("div", { className: "flex w-full flex-col items-center gap-2 px-4", children: [
182
+ /* @__PURE__ */ e(M, { onClick: i, children: a ?? "Call to action" }),
183
+ /* @__PURE__ */ e(
184
+ J,
185
+ {
186
+ onClick: p,
187
+ render: /* @__PURE__ */ e(M, { variant: "ghost", children: d })
188
+ }
189
+ )
190
+ ] })
191
+ ] });
192
+ }
193
+ const $ = c.forwardRef(
194
+ ({
195
+ variant: s = "carousel",
196
+ slides: l = E,
197
+ selectedIndex: r,
198
+ onSelectedIndexChange: a,
199
+ backLabel: i,
200
+ nextLabel: d,
201
+ goToSlideLabel: p,
202
+ image: t,
203
+ title: v = "Title",
204
+ description: N = "Feature description.",
205
+ closeLabel: o = "Close",
206
+ onCloseAction: f,
207
+ primaryLabel: m,
208
+ onPrimaryAction: n,
209
+ portal: D,
210
+ portalContainer: R,
211
+ keepMounted: g,
212
+ className: k,
213
+ ...T
214
+ }, u) => {
215
+ const h = s === "carousel", x = l.length > 0 ? l : E, B = x.length, {
216
+ emblaRef: b,
217
+ selectedIndex: W,
218
+ handleSelectIndex: j,
219
+ handleBack: V,
220
+ handleNext: y,
221
+ footerVariant: z
222
+ } = X({
223
+ slideCount: B,
224
+ selectedIndexProp: r,
225
+ onSelectedIndexChange: a
226
+ });
227
+ return /* @__PURE__ */ e(G, { ...T, children: /* @__PURE__ */ e(
228
+ H,
229
+ {
230
+ ref: u,
231
+ size: "sm",
232
+ portal: D,
233
+ portalContainer: R,
234
+ keepMounted: g,
235
+ className: k,
236
+ children: h ? /* @__PURE__ */ e(
237
+ Y,
238
+ {
239
+ slides: x,
240
+ selectedIndex: W,
241
+ emblaRef: b,
242
+ footerVariant: z,
243
+ onSelectIndex: j,
244
+ onBack: V,
245
+ onNext: y,
246
+ onPrimaryAction: n,
247
+ backLabel: i,
248
+ nextLabel: d,
249
+ primaryLabel: m,
250
+ goToSlideLabel: p
251
+ }
252
+ ) : /* @__PURE__ */ e(
253
+ Z,
254
+ {
255
+ image: t,
256
+ title: v,
257
+ description: N,
258
+ primaryLabel: m,
259
+ onPrimaryAction: n,
260
+ closeLabel: o,
261
+ onCloseAction: f
262
+ }
263
+ )
264
+ }
265
+ ) });
266
+ }
267
+ );
268
+ $.displayName = "DialogWelcome";
269
+ export {
270
+ $ as DialogWelcome
271
+ };
272
+ //# sourceMappingURL=dialog-welcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-welcome.js","sources":["../../../../src/components/ui/dialog-welcome/dialog-welcome.tsx"],"sourcesContent":["import * as React from 'react';\nimport useEmblaCarousel from 'embla-carousel-react';\n\nimport { cn } from '@/lib/utils';\nimport { useDocDir } from '@/lib/use-doc-dir';\n\nimport { Button } from '../button';\nimport {\n DialogClose,\n DialogContent,\n type DialogContentProps,\n DialogDescription,\n DialogRoot,\n DialogTitle,\n} from '../dialog';\nimport {\n DialogFooterCarousel,\n type DialogFooterCarouselVariant,\n} from '../dialog-footer-carousel';\n\n// Ports Figma's \"DialogWelcome\" component (node 7162:26459, variants\n// carousel/single): a `Container` (reuses the generic `DialogContent` popup\n// chrome — bg/radius/shadow already match the `--ui-dialog-container-*` tier)\n// around a `DialogBody` (Image + Title + Description) and, for\n// `variant=\"carousel\"`, a `DialogFooterCarousel` driven by a real Embla\n// instance built from scratch here — no import from any existing carousel\n// implementation.\n\nexport interface DialogWelcomeSlide {\n /** Illustration/media for the slide. Falls back to a placeholder surface when omitted. */\n image?: React.ReactNode;\n title: string;\n description: string;\n}\n\nexport type DialogWelcomeVariant = 'carousel' | 'single';\n\ninterface DialogWelcomeSlideBodyProps {\n image?: React.ReactNode;\n title: string;\n description: string;\n /** Whether this slide currently owns the dialog's accessible name/description. */\n active: boolean;\n /**\n * Whether this renders the DialogBody's own bottom padding (Figma's\n * `py-16` applied around the whole body). `false` when more DialogBody\n * content (e.g. the `single` variant's buttons) follows, so the caller can\n * apply the correct `gap-12` between them instead of stacking padding on\n * top of a gap.\n */\n withBottomPadding?: boolean;\n}\n\nfunction DialogWelcomeSlideBody({\n image,\n title,\n description,\n active,\n withBottomPadding = true,\n}: DialogWelcomeSlideBodyProps) {\n return (\n <div\n className={cn(\n 'flex w-full flex-col items-center gap-3 pt-4',\n withBottomPadding && 'pb-4'\n )}\n >\n <div className=\"w-full overflow-hidden rounded-lg px-4\">\n <div className=\"flex h-[272px] w-full items-center justify-center rounded bg-[var(--ui-background-surface-active)]\">\n {image}\n </div>\n </div>\n <div className=\"flex w-full flex-col items-center gap-1 px-4 text-center\">\n {active ? (\n <DialogTitle className=\"w-full flex-none text-center\">\n {title}\n </DialogTitle>\n ) : (\n <p className=\"w-full text-2xl font-normal leading-8 text-foreground\">\n {title}\n </p>\n )}\n {active ? (\n <DialogDescription className=\"w-full flex-none text-center text-sm leading-6 text-foreground\">\n {description}\n </DialogDescription>\n ) : (\n <p className=\"w-full text-sm leading-6 text-foreground\">\n {description}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nconst DEFAULT_SLIDES: DialogWelcomeSlide[] = [\n { title: 'Title', description: 'Feature description.' },\n { title: 'Title', description: 'Feature description.' },\n { title: 'Title', description: 'Feature description.' },\n];\n\ninterface UseDialogWelcomeCarouselOptions {\n slideCount: number;\n selectedIndexProp?: number;\n onSelectedIndexChange?: (index: number) => void;\n}\n\nfunction useDialogWelcomeCarousel({\n slideCount,\n selectedIndexProp,\n onSelectedIndexChange,\n}: UseDialogWelcomeCarouselOptions) {\n const dir = useDocDir();\n const isControlled = selectedIndexProp !== undefined;\n // Mount Embla already on the (clamped) controlled slide instead of its\n // default 0 — otherwise the initial `onSelect()` below reports a phantom\n // \"slide 0\" before the resync effect corrects it, which a consumer wiring\n // analytics off `onSelectedIndexChange` would log as a real event.\n const initialIndex = Math.min(\n Math.max(selectedIndexProp ?? 0, 0),\n Math.max(slideCount - 1, 0)\n );\n const [emblaRef, emblaApi] = useEmblaCarousel({\n loop: false,\n direction: dir,\n startIndex: initialIndex,\n });\n const [internalIndex, setInternalIndex] = React.useState(0);\n // Two-sided: an out-of-range (e.g. negative) `selectedIndex` must still\n // resolve to a real slide, or no slide would carry the dialog's\n // Title/Description (see dialog-welcome/accessibility.md's one-active-slide\n // invariant).\n const selectedIndex = Math.min(\n Math.max(selectedIndexProp ?? internalIndex, 0),\n Math.max(slideCount - 1, 0)\n );\n\n // `onSelectedIndexChange` is read from a ref, not a `useEffect` dependency,\n // so an inline (non-memoized) consumer callback can't force this effect to\n // re-subscribe — which would call `onSelect()` again on the same slide and,\n // if the consumer's callback triggers a re-render, loop indefinitely.\n const onSelectedIndexChangeRef = React.useRef(onSelectedIndexChange);\n React.useEffect(() => {\n onSelectedIndexChangeRef.current = onSelectedIndexChange;\n }, [onSelectedIndexChange]);\n\n // Read fresh on every Embla event without forcing the subscription effect\n // below to resubscribe (same reasoning as `onSelectedIndexChangeRef`).\n const isControlledRef = React.useRef(isControlled);\n isControlledRef.current = isControlled;\n const selectedIndexRef = React.useRef(selectedIndex);\n selectedIndexRef.current = selectedIndex;\n\n React.useEffect(() => {\n if (!emblaApi) return;\n const onSelect = () => {\n const index = emblaApi.selectedScrollSnap();\n if (isControlledRef.current) {\n if (!onSelectedIndexChangeRef.current) {\n // Embla is draggable regardless of controlled state, so a swipe can\n // still move it physically even though clicks are correctly no-ops\n // in this configuration (controlled with no way to move the prop\n // forward). Snap back instead of leaving the visible slide diverged\n // from the one carrying the dialog's accessible name.\n if (index !== selectedIndexRef.current) {\n emblaApi.scrollTo(selectedIndexRef.current, true);\n }\n return;\n }\n // A click/dot handler reports the new index directly, then the resync\n // effect below drives Embla to match via `scrollTo`, which re-emits\n // this same `select` event. Only forward it when it disagrees with\n // the last known controlled index, or a single navigation double-\n // fires the consumer's `onSelectedIndexChange` (e.g. analytics).\n if (index !== selectedIndexRef.current) {\n onSelectedIndexChangeRef.current(index);\n }\n return;\n }\n setInternalIndex(index);\n onSelectedIndexChangeRef.current?.(index);\n };\n onSelect();\n emblaApi.on('select', onSelect);\n emblaApi.on('reInit', onSelect);\n return () => {\n emblaApi.off('select', onSelect);\n emblaApi.off('reInit', onSelect);\n };\n }, [emblaApi]);\n\n React.useEffect(() => {\n if (selectedIndexProp === undefined || !emblaApi) return;\n if (emblaApi.selectedScrollSnap() !== selectedIndex) {\n // `jump: true` — a controlled `selectedIndex` change snaps instantly\n // rather than animating. Without it, the initial sync on mount races\n // the smooth-scroll animation, so an immediate screenshot (e.g. VR)\n // can catch a mid-scroll frame instead of the settled slide.\n emblaApi.scrollTo(selectedIndex, true);\n }\n }, [emblaApi, selectedIndexProp, selectedIndex]);\n\n // Skip the first time this effect sees a non-null `emblaApi` — Embla was\n // already constructed with that render's `dir` (see `useEmblaCarousel`\n // above), so re-running `reInit` immediately is redundant. Worse, Embla's\n // `reInit` synchronously re-emits `'reInit'` even when nothing changed,\n // which would re-invoke the `onSelect` listener registered by the mount\n // effect above and double-fire `onSelectedIndexChange` on mount. Only a\n // genuine post-mount `dir` change (e.g. `useDocDir`'s SSR-safe resync, or\n // the document's `dir` actually flipping at runtime) should call `reInit`.\n const skipNextReInitRef = React.useRef(true);\n React.useEffect(() => {\n if (!emblaApi) return;\n if (skipNextReInitRef.current) {\n skipNextReInitRef.current = false;\n return;\n }\n emblaApi.reInit({ direction: dir });\n }, [emblaApi, dir]);\n\n // Controlled mode never drives Embla directly from Back/Next/dot clicks —\n // only the resync effect above (keyed to `selectedIndexProp`) does. This\n // keeps Embla's physical position from drifting away from the prop when a\n // consumer passes `selectedIndex` without wiring `onSelectedIndexChange`.\n const handleSelectIndex = React.useCallback(\n (index: number) => {\n if (isControlled) {\n onSelectedIndexChange?.(index);\n } else {\n emblaApi?.scrollTo(index);\n }\n },\n [isControlled, emblaApi, onSelectedIndexChange]\n );\n const handleBack = React.useCallback(() => {\n if (isControlled) {\n onSelectedIndexChange?.(Math.max(selectedIndex - 1, 0));\n } else {\n emblaApi?.scrollPrev();\n }\n }, [isControlled, emblaApi, onSelectedIndexChange, selectedIndex]);\n const handleNext = React.useCallback(() => {\n if (isControlled) {\n onSelectedIndexChange?.(Math.min(selectedIndex + 1, slideCount - 1));\n } else {\n emblaApi?.scrollNext();\n }\n }, [isControlled, emblaApi, onSelectedIndexChange, selectedIndex, slideCount]);\n\n // Check `slideCount - 1` first: for a single-slide carousel, index 0 is\n // both the first AND last slide, and 'end' (unlocking the primary action)\n // must win.\n const footerVariant: DialogFooterCarouselVariant =\n selectedIndex === slideCount - 1\n ? 'end'\n : selectedIndex === 0\n ? 'start'\n : 'middle';\n\n return {\n emblaRef,\n selectedIndex,\n handleSelectIndex,\n handleBack,\n handleNext,\n footerVariant,\n };\n}\n\ninterface ContainerCarouselProps {\n slides: DialogWelcomeSlide[];\n selectedIndex: number;\n emblaRef: ReturnType<typeof useEmblaCarousel>[0];\n footerVariant: DialogFooterCarouselVariant;\n onSelectIndex: (index: number) => void;\n onBack: () => void;\n onNext: () => void;\n onPrimaryAction?: () => void;\n backLabel?: string;\n nextLabel?: string;\n primaryLabel?: string;\n goToSlideLabel?: (index: number, count: number) => string;\n}\n\nfunction ContainerCarousel({\n slides,\n selectedIndex,\n emblaRef,\n footerVariant,\n onSelectIndex,\n onBack,\n onNext,\n onPrimaryAction,\n backLabel,\n nextLabel,\n primaryLabel,\n goToSlideLabel,\n}: ContainerCarouselProps) {\n return (\n <>\n <div ref={emblaRef} className=\"w-full overflow-hidden\">\n <div className=\"flex\">\n {slides.map((slide, index) => (\n <div\n key={index}\n className=\"min-w-0 shrink-0 grow-0 basis-full\"\n aria-hidden={index !== selectedIndex || undefined}\n inert={index !== selectedIndex}\n >\n <DialogWelcomeSlideBody\n image={slide.image}\n title={slide.title}\n description={slide.description}\n active={index === selectedIndex}\n />\n </div>\n ))}\n </div>\n </div>\n <DialogFooterCarousel\n variant={footerVariant}\n slideCount={slides.length}\n selectedIndex={selectedIndex}\n onSelectIndex={onSelectIndex}\n onBack={onBack}\n onNext={onNext}\n onPrimaryAction={onPrimaryAction}\n backLabel={backLabel}\n nextLabel={nextLabel}\n primaryLabel={primaryLabel}\n goToSlideLabel={goToSlideLabel}\n />\n </>\n );\n}\n\ninterface ContainerNoSlidesProps {\n image?: React.ReactNode;\n title: string;\n description: string;\n primaryLabel?: string;\n onPrimaryAction?: () => void;\n closeLabel: string;\n onCloseAction?: () => void;\n}\n\nfunction ContainerNoSlides({\n image,\n title,\n description,\n primaryLabel,\n onPrimaryAction,\n closeLabel,\n onCloseAction,\n}: ContainerNoSlidesProps) {\n return (\n <div className=\"flex w-full flex-col items-center gap-3 pb-4\">\n <DialogWelcomeSlideBody\n image={image}\n title={title}\n description={description}\n active\n withBottomPadding={false}\n />\n <div className=\"flex w-full flex-col items-center gap-2 px-4\">\n <Button onClick={onPrimaryAction}>\n {primaryLabel ?? 'Call to action'}\n </Button>\n <DialogClose\n onClick={onCloseAction}\n render={<Button variant=\"ghost\">{closeLabel}</Button>}\n />\n </div>\n </div>\n );\n}\n\ntype DialogRootProps = React.ComponentPropsWithoutRef<typeof DialogRoot>;\n\nexport interface DialogWelcomeProps extends Omit<DialogRootProps, 'children'> {\n /** Selects the Figma-defined layout. Defaults to `'carousel'`. */\n variant?: DialogWelcomeVariant;\n /** Slides shown one at a time (`variant=\"carousel\"`). Defaults to a 3-slide placeholder. */\n slides?: DialogWelcomeSlide[];\n /** Controls the active slide (`variant=\"carousel\"`). Uncontrolled when omitted. */\n selectedIndex?: number;\n /** Fires whenever the active slide changes (`variant=\"carousel\"`). */\n onSelectedIndexChange?: (index: number) => void;\n /** `Back` button label (`variant=\"carousel\"`). Defaults to `'Back'`. */\n backLabel?: string;\n /** `Next` button label (`variant=\"carousel\"`). Defaults to `'Next'`. */\n nextLabel?: string;\n /** Builds each carousel dot's accessible name (`variant=\"carousel\"`). */\n goToSlideLabel?: (index: number, count: number) => string;\n /** Illustration/media (`variant=\"single\"`). */\n image?: React.ReactNode;\n /** Title (`variant=\"single\"`). Defaults to `'Title'`. */\n title?: string;\n /** Description (`variant=\"single\"`). Defaults to `'Feature description.'`. */\n description?: string;\n /** `Close` link label (`variant=\"single\"`). Defaults to `'Close'`. */\n closeLabel?: string;\n /** Fires when `Close` (`variant=\"single\"`) is activated, before the dialog closes. */\n onCloseAction?: () => void;\n /**\n * Call-to-action button label — the last carousel slide's button\n * (`variant=\"carousel\"`) or the single body's primary button\n * (`variant=\"single\"`). Defaults to `'Call to action'`.\n */\n primaryLabel?: string;\n /** Fires when the call-to-action button is activated. */\n onPrimaryAction?: () => void;\n /** Render inside a portal (forwarded to `DialogContent`). Defaults to `true`. */\n portal?: boolean;\n /** Portal container (forwarded to `DialogContent`). */\n portalContainer?: DialogContentProps['portalContainer'];\n /** Keep the content mounted while closed (forwarded to `DialogContent`). */\n keepMounted?: DialogContentProps['keepMounted'];\n /** Extra classes merged onto the popup container. */\n className?: string;\n}\n\nconst DialogWelcome = React.forwardRef<HTMLDivElement, DialogWelcomeProps>(\n (\n {\n variant = 'carousel',\n slides = DEFAULT_SLIDES,\n selectedIndex: selectedIndexProp,\n onSelectedIndexChange,\n backLabel,\n nextLabel,\n goToSlideLabel,\n image,\n title = 'Title',\n description = 'Feature description.',\n closeLabel = 'Close',\n onCloseAction,\n primaryLabel,\n onPrimaryAction,\n portal,\n portalContainer,\n keepMounted,\n className,\n ...rootProps\n },\n ref\n ) => {\n const isCarousel = variant === 'carousel';\n // An explicit `slides={[]}` would otherwise mount no Title/Description\n // and suppress the footer, leaving the dialog with no accessible name —\n // fall back to the default placeholder slides instead.\n const resolvedSlides = slides.length > 0 ? slides : DEFAULT_SLIDES;\n const slideCount = resolvedSlides.length;\n\n const {\n emblaRef,\n selectedIndex,\n handleSelectIndex,\n handleBack,\n handleNext,\n footerVariant,\n } = useDialogWelcomeCarousel({\n slideCount,\n selectedIndexProp,\n onSelectedIndexChange,\n });\n\n return (\n <DialogRoot {...rootProps}>\n <DialogContent\n ref={ref}\n size=\"sm\"\n portal={portal}\n portalContainer={portalContainer}\n keepMounted={keepMounted}\n className={className}\n >\n {isCarousel ? (\n <ContainerCarousel\n slides={resolvedSlides}\n selectedIndex={selectedIndex}\n emblaRef={emblaRef}\n footerVariant={footerVariant}\n onSelectIndex={handleSelectIndex}\n onBack={handleBack}\n onNext={handleNext}\n onPrimaryAction={onPrimaryAction}\n backLabel={backLabel}\n nextLabel={nextLabel}\n primaryLabel={primaryLabel}\n goToSlideLabel={goToSlideLabel}\n />\n ) : (\n <ContainerNoSlides\n image={image}\n title={title}\n description={description}\n primaryLabel={primaryLabel}\n onPrimaryAction={onPrimaryAction}\n closeLabel={closeLabel}\n onCloseAction={onCloseAction}\n />\n )}\n </DialogContent>\n </DialogRoot>\n );\n }\n);\nDialogWelcome.displayName = 'DialogWelcome';\n\nexport { DialogWelcome };\n"],"names":["DialogWelcomeSlideBody","image","title","description","active","withBottomPadding","jsxs","cn","jsx","DialogTitle","DialogDescription","DEFAULT_SLIDES","useDialogWelcomeCarousel","slideCount","selectedIndexProp","onSelectedIndexChange","dir","useDocDir","isControlled","initialIndex","emblaRef","emblaApi","useEmblaCarousel","internalIndex","setInternalIndex","React","selectedIndex","onSelectedIndexChangeRef","isControlledRef","selectedIndexRef","onSelect","index","_a","skipNextReInitRef","handleSelectIndex","handleBack","handleNext","footerVariant","ContainerCarousel","slides","onSelectIndex","onBack","onNext","onPrimaryAction","backLabel","nextLabel","primaryLabel","goToSlideLabel","Fragment","slide","DialogFooterCarousel","ContainerNoSlides","closeLabel","onCloseAction","Button","DialogClose","DialogWelcome","variant","portal","portalContainer","keepMounted","className","rootProps","ref","isCarousel","resolvedSlides","DialogRoot","DialogContent"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
- import { jsx as t, jsxs as i } from "react/jsx-runtime";
2
- import * as g from "react";
3
- import { cva as v } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
4
- import { FunnelChart as F, Funnel as N, Cell as b, LabelList as x } from "recharts";
5
- import { cn as L } from "../../../lib/utils.js";
6
- import { ChartContainer as T, ChartTooltip as $, ChartTooltipContent as j } from "../chart/chart.js";
7
- const A = v("", {
1
+ import { jsx as c, jsxs as B } from "react/jsx-runtime";
2
+ import * as A from "react";
3
+ import { cva as ur } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
4
+ import { FunnelChart as fr, Funnel as dr, Cell as mr, LabelList as V } from "recharts";
5
+ import { cn as vr } from "../../../lib/utils.js";
6
+ import { resolveAnimation as hr, resolveLabelFillClass as O } from "../chart/chart-format.js";
7
+ import { ChartContainer as pr, ChartTooltip as br, ChartTooltipContent as Lr, ChartLegend as Cr, ChartLegendContent as Ar } from "../chart/chart.js";
8
+ const Nr = ur("", {
8
9
  variants: {
9
10
  lastShape: {
10
11
  triangle: "",
@@ -14,60 +15,248 @@ const A = v("", {
14
15
  defaultVariants: {
15
16
  lastShape: "triangle"
16
17
  }
17
- }), R = g.forwardRef(
18
+ }), R = {
19
+ right: "right",
20
+ left: "left",
21
+ inside: "center"
22
+ };
23
+ function _r(r) {
24
+ switch (r) {
25
+ case "right":
26
+ return "left";
27
+ case "left":
28
+ return "right";
29
+ case "inside":
30
+ return "right";
31
+ }
32
+ }
33
+ const D = "__stageLabel", G = "__stageValueLabel", Er = 45, Tr = {
34
+ stroke: "var(--ui-border-on-surface-border-active)",
35
+ strokeWidth: 2
36
+ }, U = 96, j = {
37
+ top: 8,
38
+ right: U,
39
+ bottom: 8,
40
+ left: 24
41
+ }, $r = "75%";
42
+ function Ir(r) {
43
+ return r.includes("-");
44
+ }
45
+ function gr(r) {
46
+ const { showLabels: e, labelPosition: t, labelFormat: o } = r;
47
+ return e && t === "right" && Ir(o) ? $r : void 0;
48
+ }
49
+ function Fr(r) {
50
+ const { showLabels: e, labelPosition: t, showValueLabels: o, valuePosition: n } = r;
51
+ return {
52
+ ...j,
53
+ left: (e ? t : void 0) === "left" || (o ? n : void 0) === "left" ? U : j.left
54
+ };
55
+ }
56
+ const xr = (r) => {
57
+ const e = typeof r == "number" ? r : Number(r);
58
+ return Number.isFinite(e) ? `${(e * 100).toFixed(1)}%` : String(r);
59
+ };
60
+ function H(r) {
61
+ const {
62
+ name: e,
63
+ value: t,
64
+ base: o,
65
+ format: n,
66
+ formatter: d,
67
+ percentFormatter: b = xr
68
+ } = r, u = d ? d(t) : String(t), v = typeof t == "number" ? t : Number(t), a = o > 0 && Number.isFinite(v) ? b(v / o) : "";
69
+ switch (n) {
70
+ case "name":
71
+ return e;
72
+ case "value":
73
+ return u;
74
+ case "percent":
75
+ return a;
76
+ case "name-value":
77
+ return `${e}: ${u}`;
78
+ case "name-percent":
79
+ return a ? `${e}: ${a}` : e;
80
+ case "value-percent":
81
+ return a ? `${u} (${a})` : u;
82
+ }
83
+ }
84
+ function Mr(r, e, t) {
85
+ if (t <= 1) return r;
86
+ const o = 100 - (100 - Er) * e / (t - 1);
87
+ return `color-mix(in oklab, ${r} ${o.toFixed(1)}%, var(--ui-background-surface-primary))`;
88
+ }
89
+ const Pr = A.forwardRef(
18
90
  ({
19
- className: n,
20
- config: o,
21
- data: s,
22
- dataKey: c,
23
- nameKey: a,
24
- lastShape: e = "triangle",
25
- reversed: f = !1,
26
- showLabels: h = !0,
27
- showTooltip: m = !0,
28
- tooltipContent: p,
29
- ...d
30
- }, u) => {
31
- const l = s.map((r) => ({
32
- ...r,
33
- fill: `var(--color-${r[a]})`
34
- }));
35
- return /* @__PURE__ */ t(
91
+ className: r,
92
+ config: e,
93
+ data: t,
94
+ dataKey: o,
95
+ nameKey: n,
96
+ lastShape: d = "triangle",
97
+ reversed: b = !1,
98
+ showLabels: u = !0,
99
+ labelFormat: v = "name",
100
+ labelPosition: a = "right",
101
+ showValueLabels: N = !1,
102
+ valuePosition: W,
103
+ labelFill: L,
104
+ labelFormatter: _,
105
+ percentFormatter: E,
106
+ showLegend: Y = !1,
107
+ legendPos: T = "bottom",
108
+ colorMode: $ = "palette",
109
+ gradientColor: I,
110
+ stageSettings: i,
111
+ showActiveShape: z = !1,
112
+ stroke: X,
113
+ strokeWidth: g,
114
+ funnelWidth: q,
115
+ margin: w,
116
+ showTooltip: y = !0,
117
+ tooltipContent: J,
118
+ animate: Q,
119
+ animationDuration: Z,
120
+ animationBegin: K,
121
+ animationEasing: rr,
122
+ ...er
123
+ }, tr) => {
124
+ const nr = hr({
125
+ animate: Q,
126
+ animationDuration: Z,
127
+ animationBegin: K,
128
+ animationEasing: rr
129
+ }), C = A.useMemo(() => {
130
+ var P;
131
+ const l = t.filter(
132
+ (f) => {
133
+ var p;
134
+ return !((p = i == null ? void 0 : i[String(f[n])]) != null && p.hidden);
135
+ }
136
+ ), s = l.length ? String(l[0][n]) : void 0, h = I ?? (s === void 0 ? void 0 : ((P = i == null ? void 0 : i[s]) == null ? void 0 : P.color) ?? `var(--color-${s})`), sr = l.reduce((f, p) => {
137
+ const m = Number(p[o]);
138
+ return Number.isFinite(m) && m > f ? m : f;
139
+ }, 0);
140
+ return l.map((f, p) => {
141
+ var S;
142
+ const m = String(f[n]), cr = ((S = i == null ? void 0 : i[m]) == null ? void 0 : S.color) ?? ($ === "gradient" && h ? Mr(h, p, l.length) : `var(--color-${m})`), k = {
143
+ name: m,
144
+ value: f[o],
145
+ base: sr,
146
+ formatter: _,
147
+ percentFormatter: E
148
+ };
149
+ return {
150
+ ...f,
151
+ fill: cr,
152
+ [D]: H({
153
+ ...k,
154
+ format: v
155
+ }),
156
+ [G]: H({
157
+ ...k,
158
+ format: "value"
159
+ })
160
+ };
161
+ });
162
+ }, [
163
+ $,
164
+ t,
165
+ o,
166
+ I,
167
+ v,
168
+ _,
169
+ n,
170
+ E,
171
+ i
172
+ ]), or = A.useMemo(() => {
173
+ const l = /* @__PURE__ */ new Set();
174
+ return C.flatMap((s) => {
175
+ const h = String(s[n]);
176
+ return l.has(h) ? [] : (l.add(h), [
177
+ {
178
+ value: h,
179
+ dataKey: n,
180
+ type: "rect",
181
+ color: String(s.fill),
182
+ payload: s
183
+ }
184
+ ]);
185
+ });
186
+ }, [n, C]), F = W ?? _r(a), x = R[a], M = R[F], ar = {
187
+ ...Fr({
188
+ showLabels: u,
189
+ labelPosition: a,
190
+ showValueLabels: N,
191
+ valuePosition: F
192
+ }),
193
+ ...w
194
+ }, ir = q ?? gr({ showLabels: u, labelPosition: a, labelFormat: v }), lr = X ?? (g != null ? "var(--ui-border-on-surface-border)" : void 0);
195
+ return /* @__PURE__ */ c(
36
196
  "div",
37
197
  {
38
- ref: u,
39
- "data-last-shape": e,
40
- className: L(A({ lastShape: e }), n),
41
- ...d,
42
- children: /* @__PURE__ */ t(T, { config: o, className: "size-full", children: /* @__PURE__ */ i(F, { margin: { top: 8, right: 96, bottom: 8, left: 24 }, children: [
43
- m && /* @__PURE__ */ t(
44
- $,
198
+ ref: tr,
199
+ "data-last-shape": d,
200
+ className: vr(Nr({ lastShape: d }), r),
201
+ ...er,
202
+ children: /* @__PURE__ */ c(pr, { config: e, className: "size-full", children: /* @__PURE__ */ B(fr, { margin: ar, children: [
203
+ y && /* @__PURE__ */ c(
204
+ br,
205
+ {
206
+ content: J ?? /* @__PURE__ */ c(Lr, { nameKey: n, hideLabel: !0 })
207
+ }
208
+ ),
209
+ Y && /* @__PURE__ */ c(
210
+ Cr,
45
211
  {
46
- content: p ?? /* @__PURE__ */ t(j, { nameKey: a, hideLabel: !0 })
212
+ verticalAlign: T,
213
+ content: () => /* @__PURE__ */ c(
214
+ Ar,
215
+ {
216
+ payload: or,
217
+ verticalAlign: T,
218
+ nameKey: n
219
+ }
220
+ )
47
221
  }
48
222
  ),
49
- /* @__PURE__ */ i(
50
- N,
223
+ /* @__PURE__ */ B(
224
+ dr,
51
225
  {
52
- dataKey: c,
53
- nameKey: a,
54
- data: l,
55
- lastShapeType: e ?? "triangle",
56
- reversed: f,
57
- isAnimationActive: !1,
226
+ dataKey: o,
227
+ nameKey: n,
228
+ data: C,
229
+ lastShapeType: d ?? "triangle",
230
+ reversed: b,
231
+ width: ir,
232
+ stroke: lr,
233
+ strokeWidth: g,
234
+ activeShape: z ? Tr : void 0,
235
+ ...nr,
58
236
  children: [
59
- l.map((r, C) => (
237
+ C.map((l, s) => (
60
238
  // Keyed by index, not the name: two stages could share a nameKey
61
239
  // value, which would collide as a React key. Same-named stages
62
240
  // intentionally share a color/config entry via `--color-<name>`.
63
- /* @__PURE__ */ t(b, { fill: `var(--color-${r[a]})` }, C)
241
+ /* @__PURE__ */ c(mr, { fill: String(l.fill) }, s)
64
242
  )),
65
- h && /* @__PURE__ */ t(
66
- x,
243
+ u && /* @__PURE__ */ c(
244
+ V,
245
+ {
246
+ position: x,
247
+ dataKey: D,
248
+ className: L ? void 0 : O(x),
249
+ fill: L,
250
+ stroke: "none"
251
+ }
252
+ ),
253
+ N && /* @__PURE__ */ c(
254
+ V,
67
255
  {
68
- position: "right",
69
- dataKey: a,
70
- className: "fill-foreground",
256
+ position: M,
257
+ dataKey: G,
258
+ className: L ? void 0 : O(M),
259
+ fill: L,
71
260
  stroke: "none"
72
261
  }
73
262
  )
@@ -79,9 +268,14 @@ const A = v("", {
79
268
  );
80
269
  }
81
270
  );
82
- R.displayName = "FunnelChart";
271
+ Pr.displayName = "FunnelChart";
83
272
  export {
84
- R as FunnelChart,
85
- A as funnelChartVariants
273
+ Pr as FunnelChart,
274
+ Fr as funnelChartLabelMargin,
275
+ gr as funnelChartLabelReserve,
276
+ H as funnelChartLabelText,
277
+ _r as funnelChartOppositeSide,
278
+ xr as funnelChartPercent,
279
+ Nr as funnelChartVariants
86
280
  };
87
281
  //# sourceMappingURL=funnel-chart.js.map