xertica-ui 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +1 -1
  3. package/bin/cli.ts +1 -1
  4. package/bin/generate-tokens.ts +13 -7
  5. package/components/assistant/xertica-assistant/index.ts +2 -0
  6. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +97 -0
  7. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -0
  8. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -0
  9. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +86 -0
  10. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +77 -0
  11. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +573 -0
  12. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +65 -0
  13. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -0
  14. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +98 -0
  15. package/components/assistant/xertica-assistant/parts/index.ts +16 -0
  16. package/components/assistant/xertica-assistant/types.ts +139 -0
  17. package/components/assistant/xertica-assistant/use-assistant.ts +559 -0
  18. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +200 -0
  19. package/components/assistant/xertica-assistant/xertica-assistant.tsx +198 -1460
  20. package/components/brand/theme-toggle/ThemeToggle.tsx +8 -27
  21. package/components/hooks/index.ts +3 -0
  22. package/components/hooks/use-layout-shortcuts.ts +46 -0
  23. package/components/layout/sidebar/index.ts +2 -0
  24. package/components/layout/sidebar/sidebar.stories.tsx +160 -8
  25. package/components/layout/sidebar/sidebar.tsx +606 -497
  26. package/components/layout/sidebar/use-sidebar.ts +104 -0
  27. package/components/media/audio-player/AudioPlayer.tsx +131 -206
  28. package/components/media/audio-player/use-audio-player.ts +298 -0
  29. package/components/pages/home-page/HomePage.tsx +1 -1
  30. package/components/pages/template-content/TemplateContent.tsx +5 -5
  31. package/components/pages/template-page/TemplatePage.tsx +5 -5
  32. package/components/shared/CustomTooltipContent.tsx +52 -0
  33. package/components/shared/layout-constants.ts +1 -1
  34. package/components/ui/chart/chart.stories.tsx +966 -7
  35. package/components/ui/chart/chart.tsx +918 -45
  36. package/components/ui/file-upload/file-upload.stories.tsx +100 -0
  37. package/components/ui/file-upload/file-upload.tsx +14 -74
  38. package/components/ui/file-upload/index.ts +1 -0
  39. package/components/ui/file-upload/use-file-upload.ts +181 -0
  40. package/components/ui/pagination/index.ts +2 -0
  41. package/components/ui/pagination/pagination.stories.tsx +94 -0
  42. package/components/ui/pagination/use-pagination.ts +194 -0
  43. package/components/ui/rich-text-editor/index.ts +2 -0
  44. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +129 -1
  45. package/components/ui/rich-text-editor/rich-text-editor.tsx +86 -305
  46. package/components/ui/rich-text-editor/use-rich-text-editor.ts +439 -0
  47. package/components/ui/stepper/index.ts +3 -1
  48. package/components/ui/stepper/stepper.stories.tsx +116 -0
  49. package/components/ui/stepper/stepper.tsx +4 -4
  50. package/components/ui/stepper/use-stepper.ts +137 -0
  51. package/components/ui/tree-view/index.ts +4 -1
  52. package/components/ui/tree-view/tree-view.stories.tsx +110 -4
  53. package/components/ui/tree-view/tree-view.tsx +17 -125
  54. package/components/ui/tree-view/use-tree-view.ts +229 -0
  55. package/contexts/AssistenteContext.tsx +17 -54
  56. package/contexts/BrandColorsContext.tsx +6 -17
  57. package/contexts/LayoutContext.tsx +5 -31
  58. package/dist/AssistantChart-BAudAfne.cjs +3591 -0
  59. package/dist/AssistantChart-BP8upjMk.js +3565 -0
  60. package/dist/AudioPlayer-1ypwE2Wh.cjs +936 -0
  61. package/dist/AudioPlayer-DuKXrCfy.js +937 -0
  62. package/dist/CustomTooltipContent-DHjkY0ww.js +40 -0
  63. package/dist/CustomTooltipContent-c_K-DWRr.cjs +56 -0
  64. package/dist/LanguageContext-BwhwC3G2.js +657 -0
  65. package/dist/LanguageContext-DvUt5jBg.cjs +656 -0
  66. package/dist/LayoutContext-BDmcZfMH.cjs +84 -0
  67. package/dist/LayoutContext-dbQvdC4O.js +85 -0
  68. package/dist/ThemeContext-RTy1m2Uq.js +82 -0
  69. package/dist/ThemeContext-bSzuOit2.cjs +81 -0
  70. package/dist/VerifyEmailPage-C_ihbcth.js +2828 -0
  71. package/dist/VerifyEmailPage-Dt7zgA4w.cjs +2827 -0
  72. package/dist/XerticaProvider-CW9hpCdF.cjs +39 -0
  73. package/dist/XerticaProvider-siSt9uG2.js +40 -0
  74. package/dist/XerticaXLogo-D8jf0SNv.cjs +214 -0
  75. package/dist/XerticaXLogo-fAJMy3H4.js +215 -0
  76. package/dist/assistant.cjs.js +2 -1
  77. package/dist/assistant.es.js +3 -2
  78. package/dist/brand.cjs.js +2 -2
  79. package/dist/brand.es.js +2 -2
  80. package/dist/cli.js +14 -8
  81. package/dist/components/assistant/xertica-assistant/index.d.ts +2 -0
  82. package/dist/components/assistant/xertica-assistant/parts/AssistantCollapsedView.d.ts +13 -0
  83. package/dist/components/assistant/xertica-assistant/parts/AssistantConversationList.d.ts +16 -0
  84. package/dist/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.d.ts +17 -0
  85. package/dist/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.d.ts +19 -0
  86. package/dist/components/assistant/xertica-assistant/parts/AssistantHeader.d.ts +11 -0
  87. package/dist/components/assistant/xertica-assistant/parts/AssistantMessageBubble.d.ts +29 -0
  88. package/dist/components/assistant/xertica-assistant/parts/AssistantTabBar.d.ts +13 -0
  89. package/dist/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.d.ts +4 -0
  90. package/dist/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.d.ts +17 -0
  91. package/dist/components/assistant/xertica-assistant/parts/index.d.ts +16 -0
  92. package/dist/components/assistant/xertica-assistant/types.d.ts +106 -0
  93. package/dist/components/assistant/xertica-assistant/use-assistant.d.ts +125 -0
  94. package/dist/components/assistant/xertica-assistant/xertica-assistant.d.ts +8 -97
  95. package/dist/components/hooks/index.d.ts +3 -0
  96. package/dist/components/hooks/use-layout-shortcuts.d.ts +22 -0
  97. package/dist/components/layout/sidebar/index.d.ts +2 -0
  98. package/dist/components/layout/sidebar/sidebar.d.ts +80 -0
  99. package/dist/components/layout/sidebar/use-sidebar.d.ts +22 -0
  100. package/dist/components/media/audio-player/AudioPlayer.d.ts +4 -1
  101. package/dist/components/media/audio-player/use-audio-player.d.ts +72 -0
  102. package/dist/components/shared/CustomTooltipContent.d.ts +20 -0
  103. package/dist/components/shared/layout-constants.d.ts +1 -1
  104. package/dist/components/ui/alert/alert.d.ts +1 -1
  105. package/dist/components/ui/badge/badge.d.ts +1 -1
  106. package/dist/components/ui/button/button.d.ts +2 -2
  107. package/dist/components/ui/chart/chart.d.ts +162 -5
  108. package/dist/components/ui/file-upload/file-upload.d.ts +2 -0
  109. package/dist/components/ui/file-upload/index.d.ts +1 -0
  110. package/dist/components/ui/file-upload/use-file-upload.d.ts +49 -0
  111. package/dist/components/ui/pagination/index.d.ts +2 -0
  112. package/dist/components/ui/pagination/use-pagination.d.ts +78 -0
  113. package/dist/components/ui/rich-text-editor/index.d.ts +2 -0
  114. package/dist/components/ui/rich-text-editor/use-rich-text-editor.d.ts +107 -0
  115. package/dist/components/ui/stepper/index.d.ts +3 -1
  116. package/dist/components/ui/stepper/stepper.d.ts +2 -2
  117. package/dist/components/ui/stepper/use-stepper.d.ts +60 -0
  118. package/dist/components/ui/tree-view/index.d.ts +4 -1
  119. package/dist/components/ui/tree-view/tree-view.d.ts +4 -6
  120. package/dist/components/ui/tree-view/use-tree-view.d.ts +60 -0
  121. package/dist/contexts/AssistenteContext.d.ts +10 -49
  122. package/dist/hooks.cjs.js +30 -10
  123. package/dist/hooks.es.js +25 -4
  124. package/dist/index.cjs.js +20 -9
  125. package/dist/index.es.js +38 -27
  126. package/dist/layout.cjs.js +82 -1
  127. package/dist/layout.es.js +83 -2
  128. package/dist/media.cjs.js +1 -1
  129. package/dist/media.es.js +1 -1
  130. package/dist/pages.cjs.js +1 -1
  131. package/dist/pages.es.js +1 -1
  132. package/dist/rich-text-editor-BmsjY03B.js +2949 -0
  133. package/dist/rich-text-editor-GS2kpTAK.cjs +2966 -0
  134. package/dist/sidebar-CVUGHOS_.cjs +756 -0
  135. package/dist/sidebar-CmvwjnVb.js +757 -0
  136. package/dist/ui.cjs.js +12 -2
  137. package/dist/ui.es.js +24 -14
  138. package/dist/use-audio-player-Bkh23vQ3.js +177 -0
  139. package/dist/use-audio-player-Dn1NR9xN.cjs +176 -0
  140. package/dist/utils/color-utils.d.ts +51 -0
  141. package/dist/xertica-assistant-BMqdyRVi.js +2082 -0
  142. package/dist/xertica-assistant-Bj3vBCq_.cjs +2081 -0
  143. package/dist/xertica-ui.css +1 -1
  144. package/docs/ai-usage.md +28 -10
  145. package/docs/architecture-improvements.md +463 -0
  146. package/docs/architecture.md +77 -1
  147. package/docs/components/assistant-chart.md +1 -1
  148. package/docs/components/assistant.md +159 -0
  149. package/docs/components/audio-player.md +46 -0
  150. package/docs/components/branding.md +251 -0
  151. package/docs/components/chart.md +354 -39
  152. package/docs/components/code-block.md +108 -0
  153. package/docs/components/file-upload.md +119 -2
  154. package/docs/components/formatted-document.md +113 -0
  155. package/docs/components/hooks.md +430 -0
  156. package/docs/components/image-with-fallback.md +106 -0
  157. package/docs/components/map-layers.md +140 -0
  158. package/docs/components/modern-chat-input.md +163 -0
  159. package/docs/components/pages.md +351 -0
  160. package/docs/components/pagination.md +187 -0
  161. package/docs/components/rich-text-editor.md +164 -0
  162. package/docs/components/sidebar.md +153 -4
  163. package/docs/components/stepper.md +157 -12
  164. package/docs/components/tree-view.md +164 -6
  165. package/docs/doc-audit.md +223 -0
  166. package/docs/getting-started.md +155 -1
  167. package/docs/guidelines.md +14 -8
  168. package/docs/layout.md +2 -2
  169. package/docs/llms.md +29 -9
  170. package/docs/patterns/detail-page.md +276 -0
  171. package/docs/patterns/settings.md +346 -0
  172. package/docs/patterns/wizard.md +217 -0
  173. package/guidelines/Guidelines.md +5 -3
  174. package/llms.txt +1 -1
  175. package/package.json +10 -10
  176. package/styles/xertica/tokens.css +41 -12
  177. package/templates/CLAUDE.md +16 -6
  178. package/templates/guidelines/Guidelines.md +16 -4
  179. package/templates/package.json +3 -3
  180. package/templates/src/styles/xertica/tokens.css +39 -10
  181. package/utils/color-utils.ts +72 -0
@@ -0,0 +1,2966 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const React = require("react");
4
+ const RechartsPrimitive = require("recharts");
5
+ const button = require("./button-0CXwCRTm.cjs");
6
+ const classVarianceAuthority = require("class-variance-authority");
7
+ const lucideReact = require("lucide-react");
8
+ const card = require("./card-DJTsYhLL.cjs");
9
+ const select = require("./select-DT7Zjn42.cjs");
10
+ const DialogPrimitive = require("@radix-ui/react-dialog");
11
+ const dropdownMenu = require("./dropdown-menu-Ze1YZFyc.cjs");
12
+ const input = require("./input-CPl84zAx.cjs");
13
+ function _interopNamespaceDefault(e) {
14
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
15
+ if (e) {
16
+ for (const k in e) {
17
+ if (k !== "default") {
18
+ const d = Object.getOwnPropertyDescriptor(e, k);
19
+ Object.defineProperty(n, k, d.get ? d : {
20
+ enumerable: true,
21
+ get: () => e[k]
22
+ });
23
+ }
24
+ }
25
+ }
26
+ n.default = e;
27
+ return Object.freeze(n);
28
+ }
29
+ const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
30
+ const RechartsPrimitive__namespace = /* @__PURE__ */ _interopNamespaceDefault(RechartsPrimitive);
31
+ const DialogPrimitive__namespace = /* @__PURE__ */ _interopNamespaceDefault(DialogPrimitive);
32
+ const alertVariants = classVarianceAuthority.cva(
33
+ "relative w-full rounded-[var(--radius)] border-l-4 px-4 py-3 grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-5 [&>svg]:translate-y-0.5 [&>svg]:text-current",
34
+ {
35
+ variants: {
36
+ variant: {
37
+ default: "bg-muted/50 border-l-border text-foreground [&>svg]:text-muted-foreground",
38
+ success: "bg-[color:var(--success)]/10 dark:bg-[color:var(--success)]/20 border-l-[color:var(--success)] text-foreground [&>svg]:text-[color:var(--success)]",
39
+ info: "bg-[color:var(--info)]/10 dark:bg-[color:var(--info)]/20 border-l-[color:var(--info)] text-foreground [&>svg]:text-[color:var(--info)]",
40
+ warning: "bg-[color:var(--warning)]/10 dark:bg-[color:var(--warning)]/20 border-l-[color:var(--warning)] text-foreground [&>svg]:text-[color:var(--warning)]",
41
+ destructive: "bg-[color:var(--destructive)]/10 dark:bg-[color:var(--destructive)]/20 border-l-[color:var(--destructive)] text-foreground [&>svg]:text-[color:var(--destructive)]"
42
+ }
43
+ },
44
+ defaultVariants: {
45
+ variant: "default"
46
+ }
47
+ }
48
+ );
49
+ const alertIcons = {
50
+ default: lucideReact.Info,
51
+ success: lucideReact.CheckCircle,
52
+ info: lucideReact.Info,
53
+ warning: lucideReact.AlertTriangle,
54
+ destructive: lucideReact.XCircle
55
+ };
56
+ function Alert({
57
+ className,
58
+ variant,
59
+ icon,
60
+ children,
61
+ ...props
62
+ }) {
63
+ const alertVariant = variant && variant in alertIcons ? variant : "default";
64
+ const DefaultIcon = alertIcons[alertVariant];
65
+ return /* @__PURE__ */ jsxRuntime.jsxs(
66
+ "div",
67
+ {
68
+ "data-slot": "alert",
69
+ role: "alert",
70
+ className: button.cn(alertVariants({ variant }), className),
71
+ ...props,
72
+ children: [
73
+ icon !== void 0 ? icon : /* @__PURE__ */ jsxRuntime.jsx(DefaultIcon, { className: "flex-shrink-0" }),
74
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children })
75
+ ]
76
+ }
77
+ );
78
+ }
79
+ function AlertTitle({ className, ...props }) {
80
+ return /* @__PURE__ */ jsxRuntime.jsx(
81
+ "div",
82
+ {
83
+ "data-slot": "alert-title",
84
+ className: button.cn(
85
+ "font-medium mb-1 leading-tight",
86
+ className
87
+ ),
88
+ ...props
89
+ }
90
+ );
91
+ }
92
+ function AlertDescription({
93
+ className,
94
+ ...props
95
+ }) {
96
+ return /* @__PURE__ */ jsxRuntime.jsx(
97
+ "div",
98
+ {
99
+ "data-slot": "alert-description",
100
+ className: button.cn(
101
+ "leading-relaxed",
102
+ className
103
+ ),
104
+ ...props
105
+ }
106
+ );
107
+ }
108
+ const Empty = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
109
+ "div",
110
+ {
111
+ ref,
112
+ className: button.cn(
113
+ "flex min-h-[400px] flex-col items-center justify-center rounded-[var(--radius-card)] border border-dashed border-border p-8 text-center animate-in fade-in-50",
114
+ className
115
+ ),
116
+ ...props
117
+ }
118
+ ));
119
+ Empty.displayName = "Empty";
120
+ const EmptyIcon = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
121
+ "div",
122
+ {
123
+ ref,
124
+ className: button.cn(
125
+ "mx-auto flex h-20 w-20 items-center justify-center rounded-full bg-muted",
126
+ className
127
+ ),
128
+ ...props
129
+ }
130
+ ));
131
+ EmptyIcon.displayName = "EmptyIcon";
132
+ const EmptyImage = React__namespace.forwardRef(({ className, alt, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
133
+ "img",
134
+ {
135
+ ref,
136
+ alt,
137
+ className: button.cn("mx-auto mb-4 h-48 w-48 object-contain opacity-50", className),
138
+ ...props
139
+ }
140
+ ));
141
+ EmptyImage.displayName = "EmptyImage";
142
+ const EmptyTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
143
+ "h3",
144
+ {
145
+ ref,
146
+ className: button.cn("mt-4 font-semibold text-foreground", className),
147
+ ...props
148
+ }
149
+ ));
150
+ EmptyTitle.displayName = "EmptyTitle";
151
+ const EmptyDescription = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
152
+ "p",
153
+ {
154
+ ref,
155
+ className: button.cn("mt-2 text-sm text-muted-foreground max-w-sm mx-auto", className),
156
+ ...props
157
+ }
158
+ ));
159
+ EmptyDescription.displayName = "EmptyDescription";
160
+ const EmptyAction = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
161
+ "div",
162
+ {
163
+ ref,
164
+ className: button.cn("mt-6 flex flex-col gap-2 sm:flex-row sm:gap-4", className),
165
+ ...props
166
+ }
167
+ ));
168
+ EmptyAction.displayName = "EmptyAction";
169
+ function Skeleton({ className, ...props }) {
170
+ return /* @__PURE__ */ jsxRuntime.jsx(
171
+ "div",
172
+ {
173
+ "data-slot": "skeleton",
174
+ className: button.cn("bg-accent animate-pulse rounded-md", className),
175
+ ...props
176
+ }
177
+ );
178
+ }
179
+ const THEMES = { light: "", dark: ".dark" };
180
+ const defaultPeriods = [
181
+ { value: "7d", label: "7 days" },
182
+ { value: "30d", label: "30 days" },
183
+ { value: "90d", label: "90 days" }
184
+ ];
185
+ const defaultChartColors = [
186
+ "var(--chart-1)",
187
+ "var(--chart-2)",
188
+ "var(--chart-3)",
189
+ "var(--chart-4)",
190
+ "var(--chart-5)",
191
+ "var(--chart-6)",
192
+ "var(--chart-7)",
193
+ "var(--chart-8)"
194
+ ];
195
+ const chartBarSizes = {
196
+ sm: 8,
197
+ md: 14,
198
+ lg: 22,
199
+ xl: 32
200
+ };
201
+ const ChartContext = React__namespace.createContext(null);
202
+ function useChart() {
203
+ const context = React__namespace.useContext(ChartContext);
204
+ if (!context) {
205
+ throw new Error("useChart must be used within a <ChartContainer />");
206
+ }
207
+ return context;
208
+ }
209
+ function ChartContainer({
210
+ id,
211
+ className,
212
+ children,
213
+ config,
214
+ ...props
215
+ }) {
216
+ const uniqueId = React__namespace.useId();
217
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
218
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxRuntime.jsxs(
219
+ "div",
220
+ {
221
+ "data-slot": "chart",
222
+ "data-chart": chartId,
223
+ className: button.cn(
224
+ "[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border relative h-[300px] min-h-[200px] w-full min-w-0 overflow-hidden text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
225
+ className
226
+ ),
227
+ ...props,
228
+ children: [
229
+ /* @__PURE__ */ jsxRuntime.jsx(ChartStyle, { id: chartId, config }),
230
+ /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive__namespace.ResponsiveContainer, { width: "100%", height: "100%", children })
231
+ ]
232
+ }
233
+ ) });
234
+ }
235
+ const ChartStyle = ({ id, config }) => {
236
+ const colorConfig = Object.entries(config).filter(
237
+ ([, config2]) => config2.theme || config2.color
238
+ );
239
+ if (!colorConfig.length) {
240
+ return null;
241
+ }
242
+ return /* @__PURE__ */ jsxRuntime.jsx(
243
+ "style",
244
+ {
245
+ dangerouslySetInnerHTML: {
246
+ __html: Object.entries(THEMES).map(
247
+ ([theme, prefix]) => `
248
+ ${prefix} [data-chart=${id}] {
249
+ ${colorConfig.map(([key, itemConfig]) => {
250
+ var _a;
251
+ const color = ((_a = itemConfig.theme) == null ? void 0 : _a[theme]) || itemConfig.color;
252
+ return color ? ` --color-${key}: ${color};` : null;
253
+ }).join("\n")}
254
+ }
255
+ `
256
+ ).join("\n")
257
+ }
258
+ }
259
+ );
260
+ };
261
+ const ChartTooltip = RechartsPrimitive__namespace.Tooltip;
262
+ function ChartTooltipContent({
263
+ active,
264
+ payload,
265
+ className,
266
+ indicator = "dot",
267
+ hideLabel = false,
268
+ hideIndicator = false,
269
+ label,
270
+ labelFormatter,
271
+ labelClassName,
272
+ formatter,
273
+ color,
274
+ nameKey,
275
+ labelKey
276
+ }) {
277
+ const { config } = useChart();
278
+ const tooltipLabel = React__namespace.useMemo(() => {
279
+ var _a;
280
+ if (hideLabel || !(payload == null ? void 0 : payload.length)) {
281
+ return null;
282
+ }
283
+ const [item] = payload;
284
+ const key = `${labelKey || (item == null ? void 0 : item.dataKey) || (item == null ? void 0 : item.name) || "value"}`;
285
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
286
+ const value = !labelKey && typeof label === "string" ? ((_a = config[label]) == null ? void 0 : _a.label) || label : itemConfig == null ? void 0 : itemConfig.label;
287
+ if (labelFormatter) {
288
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: button.cn("font-medium", labelClassName), children: labelFormatter(value, payload) });
289
+ }
290
+ if (!value) {
291
+ return null;
292
+ }
293
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: button.cn("font-medium", labelClassName), children: value });
294
+ }, [
295
+ label,
296
+ labelFormatter,
297
+ payload,
298
+ hideLabel,
299
+ labelClassName,
300
+ config,
301
+ labelKey
302
+ ]);
303
+ if (!active || !(payload == null ? void 0 : payload.length)) {
304
+ return null;
305
+ }
306
+ const nestLabel = payload.length === 1 && indicator !== "dot";
307
+ return /* @__PURE__ */ jsxRuntime.jsxs(
308
+ "div",
309
+ {
310
+ className: button.cn(
311
+ "border-border/50 bg-background/95 backdrop-blur-sm grid min-w-[8rem] items-start gap-1.5 rounded-xl border px-3 py-2 text-xs shadow-xl",
312
+ className
313
+ ),
314
+ children: [
315
+ !nestLabel ? tooltipLabel : null,
316
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-1.5", children: payload.map((item, index) => {
317
+ var _a;
318
+ const key = `${nameKey || item.name || item.dataKey || "value"}`;
319
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
320
+ const indicatorColor = color || ((_a = item.payload) == null ? void 0 : _a.fill) || item.color;
321
+ return /* @__PURE__ */ jsxRuntime.jsx(
322
+ "div",
323
+ {
324
+ className: button.cn(
325
+ "[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
326
+ indicator === "dot" && "items-center"
327
+ ),
328
+ children: formatter && (item == null ? void 0 : item.value) !== void 0 && item.name ? formatter(item.value, item.name, item, index, item.payload) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
329
+ (itemConfig == null ? void 0 : itemConfig.icon) ? /* @__PURE__ */ jsxRuntime.jsx(itemConfig.icon, {}) : !hideIndicator && /* @__PURE__ */ jsxRuntime.jsx(
330
+ "div",
331
+ {
332
+ className: button.cn(
333
+ "shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
334
+ {
335
+ "h-2.5 w-2.5": indicator === "dot",
336
+ "w-1": indicator === "line",
337
+ "w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
338
+ "my-0.5": nestLabel && indicator === "dashed"
339
+ }
340
+ ),
341
+ style: {
342
+ "--color-bg": indicatorColor,
343
+ "--color-border": indicatorColor
344
+ }
345
+ }
346
+ ),
347
+ /* @__PURE__ */ jsxRuntime.jsxs(
348
+ "div",
349
+ {
350
+ className: button.cn(
351
+ "flex flex-1 justify-between leading-none",
352
+ nestLabel ? "items-end" : "items-center"
353
+ ),
354
+ children: [
355
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-1.5", children: [
356
+ nestLabel ? tooltipLabel : null,
357
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: (itemConfig == null ? void 0 : itemConfig.label) || item.name })
358
+ ] }),
359
+ item.value && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-mono font-semibold tabular-nums", children: item.value.toLocaleString() })
360
+ ]
361
+ }
362
+ )
363
+ ] })
364
+ },
365
+ item.dataKey
366
+ );
367
+ }) })
368
+ ]
369
+ }
370
+ );
371
+ }
372
+ const ChartLegend = RechartsPrimitive__namespace.Legend;
373
+ function ChartLegendContent({
374
+ className,
375
+ hideIcon = false,
376
+ payload,
377
+ verticalAlign = "bottom",
378
+ nameKey
379
+ }) {
380
+ const { config } = useChart();
381
+ if (!(payload == null ? void 0 : payload.length)) {
382
+ return null;
383
+ }
384
+ return /* @__PURE__ */ jsxRuntime.jsx(
385
+ "div",
386
+ {
387
+ className: button.cn(
388
+ "flex items-center justify-center gap-4",
389
+ verticalAlign === "top" ? "pb-3" : "pt-3",
390
+ className
391
+ ),
392
+ children: payload.map((item) => {
393
+ const key = `${nameKey ? item.value : item.dataKey || item.value || "value"}`;
394
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
395
+ return /* @__PURE__ */ jsxRuntime.jsxs(
396
+ "div",
397
+ {
398
+ className: button.cn(
399
+ "[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
400
+ ),
401
+ children: [
402
+ (itemConfig == null ? void 0 : itemConfig.icon) && !hideIcon ? /* @__PURE__ */ jsxRuntime.jsx(itemConfig.icon, {}) : /* @__PURE__ */ jsxRuntime.jsx(
403
+ "div",
404
+ {
405
+ className: "h-2 w-2 shrink-0 rounded-full bg-(--color-bg)",
406
+ style: {
407
+ "--color-bg": item.color || `var(--color-${key})`
408
+ }
409
+ }
410
+ ),
411
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: (itemConfig == null ? void 0 : itemConfig.label) || item.value })
412
+ ]
413
+ },
414
+ item.value
415
+ );
416
+ })
417
+ }
418
+ );
419
+ }
420
+ function getPayloadConfigFromPayload(config, payload, key) {
421
+ if (typeof payload !== "object" || payload === null) {
422
+ return void 0;
423
+ }
424
+ const payloadPayload = "payload" in payload && typeof payload.payload === "object" && payload.payload !== null ? payload.payload : void 0;
425
+ let configLabelKey = key;
426
+ if (key in payload && typeof payload[key] === "string") {
427
+ configLabelKey = payload[key];
428
+ } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key] === "string") {
429
+ configLabelKey = payloadPayload[key];
430
+ }
431
+ return configLabelKey in config ? config[configLabelKey] : config[key];
432
+ }
433
+ function getChartSeries(config, series) {
434
+ if (series == null ? void 0 : series.length) {
435
+ return series;
436
+ }
437
+ return Object.entries(config).map(([key, item]) => ({
438
+ key,
439
+ label: item.label
440
+ }));
441
+ }
442
+ function getSeriesColor(key, index, colors) {
443
+ if (Array.isArray(colors)) {
444
+ return colors[index] || defaultChartColors[index % defaultChartColors.length];
445
+ }
446
+ return (colors == null ? void 0 : colors[key]) || defaultChartColors[index % defaultChartColors.length];
447
+ }
448
+ function getChartConfigWithColors(config, keys, colors) {
449
+ return keys.reduce((nextConfig, key, index) => {
450
+ const item = config[key];
451
+ if ((item == null ? void 0 : item.theme) && !colors) {
452
+ nextConfig[key] = item;
453
+ return nextConfig;
454
+ }
455
+ nextConfig[key] = {
456
+ label: (item == null ? void 0 : item.label) || key,
457
+ icon: item == null ? void 0 : item.icon,
458
+ color: colors ? getSeriesColor(key, index, colors) : (item == null ? void 0 : item.color) || getSeriesColor(key, index)
459
+ };
460
+ return nextConfig;
461
+ }, {});
462
+ }
463
+ function buildChartConfig(keys, colors) {
464
+ return keys.reduce((cfg, key, index) => {
465
+ cfg[key] = {
466
+ label: key,
467
+ color: getSeriesColor(key, index, colors)
468
+ };
469
+ return cfg;
470
+ }, {});
471
+ }
472
+ function formatTick(value) {
473
+ if (typeof value !== "number") {
474
+ return value;
475
+ }
476
+ return Intl.NumberFormat("en", {
477
+ notation: "compact",
478
+ maximumFractionDigits: 1
479
+ }).format(value);
480
+ }
481
+ function defaultFilterData(data, period) {
482
+ const match = period.match(/^(\d+)/);
483
+ if (!match) {
484
+ return data;
485
+ }
486
+ const limit = Number(match[1]);
487
+ return data.slice(Math.max(data.length - limit, 0));
488
+ }
489
+ function getErrorDescription(error) {
490
+ if (typeof error === "string") {
491
+ return error;
492
+ }
493
+ if (error instanceof Error) {
494
+ return error.message;
495
+ }
496
+ return void 0;
497
+ }
498
+ function getBarSize(barSize = "md") {
499
+ return typeof barSize === "number" ? barSize : chartBarSizes[barSize];
500
+ }
501
+ function hasChartData(data, series) {
502
+ if (!data.length || !series.length) {
503
+ return false;
504
+ }
505
+ return data.some(
506
+ (item) => series.some((serie) => {
507
+ const value = item[serie.key];
508
+ return value !== null && value !== void 0 && value !== "";
509
+ })
510
+ );
511
+ }
512
+ function hasPieData(data, nameKey, valueKey) {
513
+ return data.some((item) => {
514
+ const name = item[nameKey];
515
+ const value = item[valueKey];
516
+ return name !== null && name !== void 0 && name !== "" && value !== null && value !== void 0 && value !== "";
517
+ });
518
+ }
519
+ function ChartState({
520
+ type,
521
+ className,
522
+ error,
523
+ onRetry,
524
+ retryLabel = "Try again",
525
+ emptyTitle = "No data available",
526
+ emptyDescription = "There is no data available for this chart yet.",
527
+ errorTitle = "Connection error",
528
+ errorDescription,
529
+ loadingLabel = "Loading chart data"
530
+ }) {
531
+ if (type === "loading") {
532
+ return /* @__PURE__ */ jsxRuntime.jsxs(
533
+ "div",
534
+ {
535
+ className: button.cn(
536
+ "flex min-h-[240px] flex-col justify-end gap-3 rounded-[var(--radius-card)] border border-border p-6",
537
+ className
538
+ ),
539
+ "aria-label": typeof loadingLabel === "string" ? loadingLabel : void 0,
540
+ children: [
541
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-8 w-2/5" }),
542
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-14 w-3/5" }),
543
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-24 w-4/5" }),
544
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-36 w-full" })
545
+ ]
546
+ }
547
+ );
548
+ }
549
+ if (type === "error") {
550
+ return /* @__PURE__ */ jsxRuntime.jsx(
551
+ "div",
552
+ {
553
+ className: button.cn(
554
+ "flex min-h-[240px] items-center justify-center rounded-[var(--radius-card)] border border-border p-6",
555
+ className
556
+ ),
557
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Alert, { variant: "destructive", className: "max-w-xl", children: [
558
+ /* @__PURE__ */ jsxRuntime.jsx(AlertTitle, { children: errorTitle }),
559
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDescription, { children: errorDescription || getErrorDescription(error) || "Unable to load chart data. Check your connection and try again." }),
560
+ onRetry ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { size: "sm", variant: "outline", onClick: onRetry, children: [
561
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
562
+ retryLabel
563
+ ] }) }) : null
564
+ ] })
565
+ }
566
+ );
567
+ }
568
+ return /* @__PURE__ */ jsxRuntime.jsxs(Empty, { className: button.cn("min-h-[240px]", className), children: [
569
+ /* @__PURE__ */ jsxRuntime.jsx(EmptyIcon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BarChart3, { className: "size-10 text-muted-foreground" }) }),
570
+ /* @__PURE__ */ jsxRuntime.jsx(EmptyTitle, { children: emptyTitle }),
571
+ /* @__PURE__ */ jsxRuntime.jsx(EmptyDescription, { children: emptyDescription }),
572
+ onRetry ? /* @__PURE__ */ jsxRuntime.jsx(EmptyAction, { children: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { size: "sm", variant: "outline", onClick: onRetry, children: [
573
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.WifiOff, { className: "size-4" }),
574
+ retryLabel
575
+ ] }) }) : null
576
+ ] });
577
+ }
578
+ function getChartState(state, hasData, className) {
579
+ if (state.isLoading) {
580
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartState, { ...state, type: "loading", className });
581
+ }
582
+ if (state.error) {
583
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartState, { ...state, type: "error", className });
584
+ }
585
+ if (!hasData) {
586
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartState, { ...state, type: "empty", className });
587
+ }
588
+ return null;
589
+ }
590
+ function ChartCard({
591
+ title,
592
+ description,
593
+ action,
594
+ footer,
595
+ children,
596
+ className,
597
+ contentClassName,
598
+ ...props
599
+ }) {
600
+ return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { className: button.cn("w-full min-w-0 overflow-hidden", className), ...props, children: [
601
+ /* @__PURE__ */ jsxRuntime.jsxs(card.CardHeader, { children: [
602
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardTitle, { children: title }),
603
+ description ? /* @__PURE__ */ jsxRuntime.jsx(card.CardDescription, { children: description }) : null,
604
+ action ? /* @__PURE__ */ jsxRuntime.jsx(card.CardAction, { children: action }) : null
605
+ ] }),
606
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardContent, { className: contentClassName, children }),
607
+ footer ? /* @__PURE__ */ jsxRuntime.jsx(card.CardFooter, { children: footer }) : null
608
+ ] });
609
+ }
610
+ function AreaGradientDefs({
611
+ seriesKeys,
612
+ opacity = 0.3
613
+ }) {
614
+ return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: seriesKeys.map((key) => /* @__PURE__ */ jsxRuntime.jsxs(
615
+ "linearGradient",
616
+ {
617
+ id: `gradient-${key}`,
618
+ x1: "0",
619
+ y1: "0",
620
+ x2: "0",
621
+ y2: "1",
622
+ children: [
623
+ /* @__PURE__ */ jsxRuntime.jsx(
624
+ "stop",
625
+ {
626
+ offset: "5%",
627
+ stopColor: `var(--color-${key})`,
628
+ stopOpacity: opacity
629
+ }
630
+ ),
631
+ /* @__PURE__ */ jsxRuntime.jsx(
632
+ "stop",
633
+ {
634
+ offset: "95%",
635
+ stopColor: `var(--color-${key})`,
636
+ stopOpacity: 0
637
+ }
638
+ )
639
+ ]
640
+ },
641
+ key
642
+ )) });
643
+ }
644
+ function DashboardBarChart({
645
+ data,
646
+ config,
647
+ indexKey = "name",
648
+ series,
649
+ colors,
650
+ barSize = "md",
651
+ stacked = false,
652
+ showGrid = true,
653
+ showLegend = true,
654
+ valueFormatter = formatTick,
655
+ isLoading,
656
+ error,
657
+ onRetry,
658
+ retryLabel,
659
+ emptyTitle,
660
+ emptyDescription,
661
+ errorTitle,
662
+ errorDescription,
663
+ loadingLabel,
664
+ stateClassName,
665
+ className,
666
+ ...props
667
+ }) {
668
+ const chartSeries = getChartSeries(config, series);
669
+ const chartConfig = getChartConfigWithColors(
670
+ config,
671
+ chartSeries.map((item) => item.key),
672
+ colors
673
+ );
674
+ const chartState = getChartState(
675
+ {
676
+ isLoading,
677
+ error,
678
+ onRetry,
679
+ retryLabel,
680
+ emptyTitle,
681
+ emptyDescription,
682
+ errorTitle,
683
+ errorDescription,
684
+ loadingLabel
685
+ },
686
+ hasChartData(data, chartSeries),
687
+ button.cn("h-[320px] w-full", stateClassName)
688
+ );
689
+ if (chartState) {
690
+ return chartState;
691
+ }
692
+ return /* @__PURE__ */ jsxRuntime.jsx(
693
+ ChartContainer,
694
+ {
695
+ config: chartConfig,
696
+ className: button.cn("h-[320px] w-full", className),
697
+ ...props,
698
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.BarChart, { data, accessibilityLayer: true, barGap: 4, children: [
699
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
700
+ RechartsPrimitive__namespace.CartesianGrid,
701
+ {
702
+ vertical: false,
703
+ strokeDasharray: "3 3",
704
+ stroke: "var(--border)",
705
+ strokeOpacity: 0.5
706
+ }
707
+ ) : null,
708
+ /* @__PURE__ */ jsxRuntime.jsx(
709
+ RechartsPrimitive__namespace.XAxis,
710
+ {
711
+ dataKey: indexKey,
712
+ tickLine: false,
713
+ axisLine: false,
714
+ tickMargin: 8
715
+ }
716
+ ),
717
+ /* @__PURE__ */ jsxRuntime.jsx(
718
+ RechartsPrimitive__namespace.YAxis,
719
+ {
720
+ tickLine: false,
721
+ axisLine: false,
722
+ tickMargin: 8,
723
+ tickFormatter: valueFormatter
724
+ }
725
+ ),
726
+ /* @__PURE__ */ jsxRuntime.jsx(
727
+ ChartTooltip,
728
+ {
729
+ cursor: { fill: "var(--muted)", opacity: 0.4, radius: 4 },
730
+ content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, {})
731
+ }
732
+ ),
733
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
734
+ (() => {
735
+ const topOfStack = /* @__PURE__ */ new Set();
736
+ if (stacked) {
737
+ const lastByStack = /* @__PURE__ */ new Map();
738
+ chartSeries.forEach((s) => lastByStack.set(s.stackId || "total", s.key));
739
+ lastByStack.forEach((key) => topOfStack.add(key));
740
+ }
741
+ return chartSeries.map((item) => {
742
+ const isTop = !stacked || topOfStack.has(item.key);
743
+ return /* @__PURE__ */ jsxRuntime.jsx(
744
+ RechartsPrimitive__namespace.Bar,
745
+ {
746
+ dataKey: item.key,
747
+ fill: `var(--color-${item.key})`,
748
+ radius: isTop ? [4, 4, 0, 0] : [0, 0, 0, 0],
749
+ barSize: getBarSize(barSize),
750
+ stackId: stacked ? item.stackId || "total" : item.stackId,
751
+ isAnimationActive: true,
752
+ animationDuration: 600,
753
+ animationEasing: "ease-out"
754
+ },
755
+ item.key
756
+ );
757
+ });
758
+ })()
759
+ ] })
760
+ }
761
+ );
762
+ }
763
+ function DashboardLineChart({
764
+ data,
765
+ config,
766
+ indexKey = "name",
767
+ series,
768
+ colors,
769
+ showDots = false,
770
+ showGrid = true,
771
+ showLegend = true,
772
+ curveType = "monotone",
773
+ strokeWidth = 2,
774
+ valueFormatter = formatTick,
775
+ isLoading,
776
+ error,
777
+ onRetry,
778
+ retryLabel,
779
+ emptyTitle,
780
+ emptyDescription,
781
+ errorTitle,
782
+ errorDescription,
783
+ loadingLabel,
784
+ stateClassName,
785
+ className,
786
+ ...props
787
+ }) {
788
+ const chartSeries = getChartSeries(config, series);
789
+ const chartConfig = getChartConfigWithColors(
790
+ config,
791
+ chartSeries.map((item) => item.key),
792
+ colors
793
+ );
794
+ const chartState = getChartState(
795
+ {
796
+ isLoading,
797
+ error,
798
+ onRetry,
799
+ retryLabel,
800
+ emptyTitle,
801
+ emptyDescription,
802
+ errorTitle,
803
+ errorDescription,
804
+ loadingLabel
805
+ },
806
+ hasChartData(data, chartSeries),
807
+ button.cn("h-[320px] w-full", stateClassName)
808
+ );
809
+ if (chartState) {
810
+ return chartState;
811
+ }
812
+ return /* @__PURE__ */ jsxRuntime.jsx(
813
+ ChartContainer,
814
+ {
815
+ config: chartConfig,
816
+ className: button.cn("h-[320px] w-full", className),
817
+ ...props,
818
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.LineChart, { data, accessibilityLayer: true, children: [
819
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
820
+ RechartsPrimitive__namespace.CartesianGrid,
821
+ {
822
+ vertical: false,
823
+ strokeDasharray: "3 3",
824
+ stroke: "var(--border)",
825
+ strokeOpacity: 0.5
826
+ }
827
+ ) : null,
828
+ /* @__PURE__ */ jsxRuntime.jsx(
829
+ RechartsPrimitive__namespace.XAxis,
830
+ {
831
+ dataKey: indexKey,
832
+ tickLine: false,
833
+ axisLine: false,
834
+ tickMargin: 8
835
+ }
836
+ ),
837
+ /* @__PURE__ */ jsxRuntime.jsx(
838
+ RechartsPrimitive__namespace.YAxis,
839
+ {
840
+ tickLine: false,
841
+ axisLine: false,
842
+ tickMargin: 8,
843
+ tickFormatter: valueFormatter
844
+ }
845
+ ),
846
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, { indicator: "line" }) }),
847
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
848
+ chartSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
849
+ RechartsPrimitive__namespace.Line,
850
+ {
851
+ type: curveType,
852
+ dataKey: item.key,
853
+ stroke: `var(--color-${item.key})`,
854
+ strokeWidth,
855
+ dot: showDots ? { r: 3, fill: `var(--color-${item.key})`, strokeWidth: 0 } : false,
856
+ activeDot: { r: 5, strokeWidth: 0 },
857
+ yAxisId: item.yAxisId,
858
+ isAnimationActive: true,
859
+ animationDuration: 600,
860
+ animationEasing: "ease-out"
861
+ },
862
+ item.key
863
+ ))
864
+ ] })
865
+ }
866
+ );
867
+ }
868
+ function HorizontalBarChart({
869
+ data,
870
+ config,
871
+ indexKey = "name",
872
+ series,
873
+ colors,
874
+ barSize = "md",
875
+ stacked = false,
876
+ categoryWidth = 96,
877
+ showGrid = true,
878
+ showLegend = true,
879
+ valueFormatter = formatTick,
880
+ isLoading,
881
+ error,
882
+ onRetry,
883
+ retryLabel,
884
+ emptyTitle,
885
+ emptyDescription,
886
+ errorTitle,
887
+ errorDescription,
888
+ loadingLabel,
889
+ stateClassName,
890
+ className,
891
+ ...props
892
+ }) {
893
+ const chartSeries = getChartSeries(config, series);
894
+ const chartConfig = getChartConfigWithColors(
895
+ config,
896
+ chartSeries.map((item) => item.key),
897
+ colors
898
+ );
899
+ const chartState = getChartState(
900
+ {
901
+ isLoading,
902
+ error,
903
+ onRetry,
904
+ retryLabel,
905
+ emptyTitle,
906
+ emptyDescription,
907
+ errorTitle,
908
+ errorDescription,
909
+ loadingLabel
910
+ },
911
+ hasChartData(data, chartSeries),
912
+ button.cn("h-[320px] w-full", stateClassName)
913
+ );
914
+ if (chartState) {
915
+ return chartState;
916
+ }
917
+ return /* @__PURE__ */ jsxRuntime.jsx(
918
+ ChartContainer,
919
+ {
920
+ config: chartConfig,
921
+ className: button.cn("h-[320px] w-full", className),
922
+ ...props,
923
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
924
+ RechartsPrimitive__namespace.BarChart,
925
+ {
926
+ data,
927
+ layout: "vertical",
928
+ accessibilityLayer: true,
929
+ margin: { left: 8, right: 16 },
930
+ children: [
931
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
932
+ RechartsPrimitive__namespace.CartesianGrid,
933
+ {
934
+ horizontal: false,
935
+ strokeDasharray: "3 3",
936
+ stroke: "var(--border)",
937
+ strokeOpacity: 0.5
938
+ }
939
+ ) : null,
940
+ /* @__PURE__ */ jsxRuntime.jsx(
941
+ RechartsPrimitive__namespace.XAxis,
942
+ {
943
+ type: "number",
944
+ tickLine: false,
945
+ axisLine: false,
946
+ tickMargin: 8,
947
+ tickFormatter: valueFormatter
948
+ }
949
+ ),
950
+ /* @__PURE__ */ jsxRuntime.jsx(
951
+ RechartsPrimitive__namespace.YAxis,
952
+ {
953
+ dataKey: indexKey,
954
+ type: "category",
955
+ tickLine: false,
956
+ axisLine: false,
957
+ tickMargin: 8,
958
+ width: categoryWidth
959
+ }
960
+ ),
961
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, {}) }),
962
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
963
+ chartSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
964
+ RechartsPrimitive__namespace.Bar,
965
+ {
966
+ dataKey: item.key,
967
+ fill: `var(--color-${item.key})`,
968
+ radius: [0, 4, 4, 0],
969
+ barSize: getBarSize(barSize),
970
+ stackId: stacked ? item.stackId || "total" : item.stackId,
971
+ isAnimationActive: true,
972
+ animationDuration: 600,
973
+ animationEasing: "ease-out"
974
+ },
975
+ item.key
976
+ ))
977
+ ]
978
+ }
979
+ )
980
+ }
981
+ );
982
+ }
983
+ function InteractiveTimeSeriesChart({
984
+ data,
985
+ config,
986
+ indexKey = "date",
987
+ series,
988
+ colors,
989
+ periods = defaultPeriods,
990
+ defaultPeriod = ((_a) => (_a = periods[1]) == null ? void 0 : _a.value)() || ((_b) => (_b = periods[0]) == null ? void 0 : _b.value)() || "30d",
991
+ defaultSeries,
992
+ filterData = defaultFilterData,
993
+ showGrid = true,
994
+ showLegend = false,
995
+ showDots = false,
996
+ gradientFill = true,
997
+ curveType = "monotone",
998
+ strokeWidth = 2,
999
+ valueFormatter = formatTick,
1000
+ isLoading,
1001
+ error,
1002
+ onRetry,
1003
+ retryLabel,
1004
+ emptyTitle,
1005
+ emptyDescription,
1006
+ errorTitle,
1007
+ errorDescription,
1008
+ loadingLabel,
1009
+ stateClassName,
1010
+ className,
1011
+ ...props
1012
+ }) {
1013
+ var _a2;
1014
+ const chartSeries = getChartSeries(config, series);
1015
+ const chartConfig = getChartConfigWithColors(
1016
+ config,
1017
+ chartSeries.map((item) => item.key),
1018
+ colors
1019
+ );
1020
+ const [period, setPeriod] = React__namespace.useState(defaultPeriod);
1021
+ const [activeSeries, setActiveSeries] = React__namespace.useState(
1022
+ defaultSeries || ((_a2 = chartSeries[0]) == null ? void 0 : _a2.key) || ""
1023
+ );
1024
+ const filteredData = React__namespace.useMemo(
1025
+ () => filterData(data, period),
1026
+ [data, filterData, period]
1027
+ );
1028
+ const visibleSeries = chartSeries.length > 1 ? chartSeries.filter((item) => item.key === activeSeries) : chartSeries;
1029
+ const chartState = getChartState(
1030
+ {
1031
+ isLoading,
1032
+ error,
1033
+ onRetry,
1034
+ retryLabel,
1035
+ emptyTitle,
1036
+ emptyDescription,
1037
+ errorTitle,
1038
+ errorDescription,
1039
+ loadingLabel
1040
+ },
1041
+ hasChartData(filteredData, visibleSeries),
1042
+ button.cn("h-[320px] w-full", stateClassName)
1043
+ );
1044
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-4", children: [
1045
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
1046
+ chartSeries.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx(
1047
+ "div",
1048
+ {
1049
+ className: "inline-flex h-10 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
1050
+ role: "group",
1051
+ "aria-label": "Selecionar metrica do grafico",
1052
+ children: chartSeries.map((item) => {
1053
+ var _a3;
1054
+ const label = item.label || ((_a3 = config[item.key]) == null ? void 0 : _a3.label) || item.key;
1055
+ return /* @__PURE__ */ jsxRuntime.jsx(
1056
+ button.Button,
1057
+ {
1058
+ type: "button",
1059
+ variant: "ghost",
1060
+ size: "sm",
1061
+ "aria-pressed": activeSeries === item.key,
1062
+ onClick: () => setActiveSeries(item.key),
1063
+ className: button.cn(
1064
+ "h-8 px-3 text-sm font-medium transition-all",
1065
+ activeSeries === item.key ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
1066
+ ),
1067
+ children: label
1068
+ },
1069
+ item.key
1070
+ );
1071
+ })
1072
+ }
1073
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
1074
+ /* @__PURE__ */ jsxRuntime.jsxs(select.Select, { value: period, onValueChange: setPeriod, children: [
1075
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectTrigger, { className: "w-full sm:w-[160px]", size: "sm", "aria-label": "Selecionar periodo do grafico", children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: "Period" }) }),
1076
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectContent, { children: periods.map((item) => /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: item.value, children: item.label }, item.value)) })
1077
+ ] })
1078
+ ] }),
1079
+ chartState || /* @__PURE__ */ jsxRuntime.jsx(
1080
+ ChartContainer,
1081
+ {
1082
+ config: chartConfig,
1083
+ className: button.cn("h-[320px] w-full", className),
1084
+ ...props,
1085
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.AreaChart, { data: filteredData, accessibilityLayer: true, children: [
1086
+ gradientFill && /* @__PURE__ */ jsxRuntime.jsx(
1087
+ AreaGradientDefs,
1088
+ {
1089
+ seriesKeys: visibleSeries.map((s) => s.key),
1090
+ opacity: 0.4
1091
+ }
1092
+ ),
1093
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
1094
+ RechartsPrimitive__namespace.CartesianGrid,
1095
+ {
1096
+ vertical: false,
1097
+ strokeDasharray: "3 3",
1098
+ stroke: "var(--border)",
1099
+ strokeOpacity: 0.5
1100
+ }
1101
+ ) : null,
1102
+ /* @__PURE__ */ jsxRuntime.jsx(
1103
+ RechartsPrimitive__namespace.XAxis,
1104
+ {
1105
+ dataKey: indexKey,
1106
+ tickLine: false,
1107
+ axisLine: false,
1108
+ tickMargin: 8
1109
+ }
1110
+ ),
1111
+ /* @__PURE__ */ jsxRuntime.jsx(
1112
+ RechartsPrimitive__namespace.YAxis,
1113
+ {
1114
+ tickLine: false,
1115
+ axisLine: false,
1116
+ tickMargin: 8,
1117
+ tickFormatter: valueFormatter
1118
+ }
1119
+ ),
1120
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, { indicator: "line" }) }),
1121
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
1122
+ visibleSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
1123
+ RechartsPrimitive__namespace.Area,
1124
+ {
1125
+ type: curveType,
1126
+ dataKey: item.key,
1127
+ stroke: `var(--color-${item.key})`,
1128
+ fill: gradientFill ? `url(#gradient-${item.key})` : `var(--color-${item.key})`,
1129
+ fillOpacity: gradientFill ? 1 : 0.16,
1130
+ strokeWidth,
1131
+ dot: showDots ? { r: 3, fill: `var(--color-${item.key})`, strokeWidth: 0 } : false,
1132
+ activeDot: { r: 5, strokeWidth: 0 },
1133
+ isAnimationActive: true,
1134
+ animationDuration: 600,
1135
+ animationEasing: "ease-out"
1136
+ },
1137
+ item.key
1138
+ ))
1139
+ ] })
1140
+ }
1141
+ )
1142
+ ] });
1143
+ }
1144
+ function ComboMetricChart({
1145
+ data,
1146
+ config,
1147
+ indexKey = "name",
1148
+ series,
1149
+ colors,
1150
+ barSize = "md",
1151
+ showGrid = true,
1152
+ showLegend = true,
1153
+ gradientFill = false,
1154
+ curveType = "monotone",
1155
+ valueFormatter = formatTick,
1156
+ isLoading,
1157
+ error,
1158
+ onRetry,
1159
+ retryLabel,
1160
+ emptyTitle,
1161
+ emptyDescription,
1162
+ errorTitle,
1163
+ errorDescription,
1164
+ loadingLabel,
1165
+ stateClassName,
1166
+ className,
1167
+ ...props
1168
+ }) {
1169
+ const chartSeries = getChartSeries(config, series);
1170
+ const chartConfig = getChartConfigWithColors(
1171
+ config,
1172
+ chartSeries.map((item) => item.key),
1173
+ colors
1174
+ );
1175
+ const chartState = getChartState(
1176
+ {
1177
+ isLoading,
1178
+ error,
1179
+ onRetry,
1180
+ retryLabel,
1181
+ emptyTitle,
1182
+ emptyDescription,
1183
+ errorTitle,
1184
+ errorDescription,
1185
+ loadingLabel
1186
+ },
1187
+ hasChartData(data, chartSeries),
1188
+ button.cn("h-[340px] w-full", stateClassName)
1189
+ );
1190
+ if (chartState) {
1191
+ return chartState;
1192
+ }
1193
+ const areaSeries = gradientFill ? chartSeries.filter((s) => s.type === "area").map((s) => s.key) : [];
1194
+ return /* @__PURE__ */ jsxRuntime.jsx(
1195
+ ChartContainer,
1196
+ {
1197
+ config: chartConfig,
1198
+ className: button.cn("h-[340px] w-full", className),
1199
+ ...props,
1200
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.ComposedChart, { data, accessibilityLayer: true, children: [
1201
+ gradientFill && areaSeries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(AreaGradientDefs, { seriesKeys: areaSeries, opacity: 0.35 }),
1202
+ showGrid ? /* @__PURE__ */ jsxRuntime.jsx(
1203
+ RechartsPrimitive__namespace.CartesianGrid,
1204
+ {
1205
+ vertical: false,
1206
+ strokeDasharray: "3 3",
1207
+ stroke: "var(--border)",
1208
+ strokeOpacity: 0.5
1209
+ }
1210
+ ) : null,
1211
+ /* @__PURE__ */ jsxRuntime.jsx(
1212
+ RechartsPrimitive__namespace.XAxis,
1213
+ {
1214
+ dataKey: indexKey,
1215
+ tickLine: false,
1216
+ axisLine: false,
1217
+ tickMargin: 8
1218
+ }
1219
+ ),
1220
+ /* @__PURE__ */ jsxRuntime.jsx(
1221
+ RechartsPrimitive__namespace.YAxis,
1222
+ {
1223
+ tickLine: false,
1224
+ axisLine: false,
1225
+ tickMargin: 8,
1226
+ tickFormatter: valueFormatter
1227
+ }
1228
+ ),
1229
+ /* @__PURE__ */ jsxRuntime.jsx(ChartTooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, {}) }),
1230
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }) : null,
1231
+ chartSeries.map(
1232
+ (item) => item.type === "line" ? /* @__PURE__ */ jsxRuntime.jsx(
1233
+ RechartsPrimitive__namespace.Line,
1234
+ {
1235
+ type: curveType,
1236
+ dataKey: item.key,
1237
+ stroke: `var(--color-${item.key})`,
1238
+ strokeWidth: 2,
1239
+ dot: false,
1240
+ activeDot: { r: 5, strokeWidth: 0 },
1241
+ yAxisId: item.yAxisId,
1242
+ isAnimationActive: true,
1243
+ animationDuration: 600,
1244
+ animationEasing: "ease-out"
1245
+ },
1246
+ item.key
1247
+ ) : item.type === "area" ? /* @__PURE__ */ jsxRuntime.jsx(
1248
+ RechartsPrimitive__namespace.Area,
1249
+ {
1250
+ type: curveType,
1251
+ dataKey: item.key,
1252
+ stroke: `var(--color-${item.key})`,
1253
+ fill: gradientFill ? `url(#gradient-${item.key})` : `var(--color-${item.key})`,
1254
+ fillOpacity: gradientFill ? 1 : 0.12,
1255
+ strokeWidth: 2,
1256
+ dot: false,
1257
+ activeDot: { r: 5, strokeWidth: 0 },
1258
+ yAxisId: item.yAxisId,
1259
+ isAnimationActive: true,
1260
+ animationDuration: 600,
1261
+ animationEasing: "ease-out"
1262
+ },
1263
+ item.key
1264
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1265
+ RechartsPrimitive__namespace.Bar,
1266
+ {
1267
+ dataKey: item.key,
1268
+ fill: `var(--color-${item.key})`,
1269
+ radius: [4, 4, 0, 0],
1270
+ barSize: getBarSize(barSize),
1271
+ yAxisId: item.yAxisId,
1272
+ isAnimationActive: true,
1273
+ animationDuration: 600,
1274
+ animationEasing: "ease-out"
1275
+ },
1276
+ item.key
1277
+ )
1278
+ )
1279
+ ] })
1280
+ }
1281
+ );
1282
+ }
1283
+ function DonutBreakdownChart({
1284
+ data,
1285
+ config,
1286
+ nameKey = "name",
1287
+ valueKey = "value",
1288
+ colors,
1289
+ centerLabel,
1290
+ centerValue,
1291
+ showLegend = true,
1292
+ innerRadius = "58%",
1293
+ outerRadius = "82%",
1294
+ isLoading,
1295
+ error,
1296
+ onRetry,
1297
+ retryLabel,
1298
+ emptyTitle,
1299
+ emptyDescription,
1300
+ errorTitle,
1301
+ errorDescription,
1302
+ loadingLabel,
1303
+ stateClassName,
1304
+ className,
1305
+ ...props
1306
+ }) {
1307
+ const [activeIndex, setActiveIndex] = React__namespace.useState(0);
1308
+ const chartKeys = data.map(
1309
+ (entry, index) => String(entry[nameKey] || `segment-${index}`)
1310
+ );
1311
+ const chartConfig = getChartConfigWithColors(config, chartKeys, colors);
1312
+ const chartState = getChartState(
1313
+ {
1314
+ isLoading,
1315
+ error,
1316
+ onRetry,
1317
+ retryLabel,
1318
+ emptyTitle,
1319
+ emptyDescription,
1320
+ errorTitle,
1321
+ errorDescription,
1322
+ loadingLabel
1323
+ },
1324
+ hasPieData(data, nameKey, valueKey),
1325
+ button.cn("h-[320px] w-full", stateClassName)
1326
+ );
1327
+ if (chartState) {
1328
+ return chartState;
1329
+ }
1330
+ return /* @__PURE__ */ jsxRuntime.jsx(
1331
+ ChartContainer,
1332
+ {
1333
+ config: chartConfig,
1334
+ className: button.cn("h-[320px] w-full", className),
1335
+ ...props,
1336
+ children: /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.PieChart, { accessibilityLayer: true, children: [
1337
+ /* @__PURE__ */ jsxRuntime.jsx(
1338
+ ChartTooltip,
1339
+ {
1340
+ cursor: false,
1341
+ content: /* @__PURE__ */ jsxRuntime.jsx(ChartTooltipContent, { hideLabel: true, nameKey })
1342
+ }
1343
+ ),
1344
+ showLegend ? /* @__PURE__ */ jsxRuntime.jsx(
1345
+ ChartLegend,
1346
+ {
1347
+ content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, { nameKey }),
1348
+ verticalAlign: "bottom"
1349
+ }
1350
+ ) : null,
1351
+ /* @__PURE__ */ jsxRuntime.jsxs(
1352
+ RechartsPrimitive__namespace.Pie,
1353
+ {
1354
+ data,
1355
+ dataKey: valueKey,
1356
+ nameKey,
1357
+ innerRadius,
1358
+ outerRadius,
1359
+ paddingAngle: 3,
1360
+ activeIndex,
1361
+ onMouseEnter: (_, index) => setActiveIndex(index),
1362
+ isAnimationActive: true,
1363
+ animationDuration: 600,
1364
+ animationEasing: "ease-out",
1365
+ children: [
1366
+ data.map((entry, index) => {
1367
+ const key = String(entry[nameKey] || `segment-${index}`);
1368
+ return /* @__PURE__ */ jsxRuntime.jsx(
1369
+ RechartsPrimitive__namespace.Cell,
1370
+ {
1371
+ fill: `var(--color-${key})`,
1372
+ opacity: index === activeIndex ? 1 : 0.7,
1373
+ stroke: "transparent"
1374
+ },
1375
+ key
1376
+ );
1377
+ }),
1378
+ centerValue || centerLabel ? /* @__PURE__ */ jsxRuntime.jsx(
1379
+ RechartsPrimitive__namespace.Label,
1380
+ {
1381
+ position: "center",
1382
+ content: ({ viewBox }) => {
1383
+ if (!viewBox || !("cx" in viewBox) || !("cy" in viewBox)) {
1384
+ return null;
1385
+ }
1386
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1387
+ "text",
1388
+ {
1389
+ x: viewBox.cx,
1390
+ y: viewBox.cy,
1391
+ textAnchor: "middle",
1392
+ dominantBaseline: "middle",
1393
+ children: [
1394
+ centerValue ? /* @__PURE__ */ jsxRuntime.jsx(
1395
+ "tspan",
1396
+ {
1397
+ x: viewBox.cx,
1398
+ y: viewBox.cy,
1399
+ className: "fill-foreground text-2xl font-semibold",
1400
+ children: centerValue
1401
+ }
1402
+ ) : null,
1403
+ centerLabel ? /* @__PURE__ */ jsxRuntime.jsx(
1404
+ "tspan",
1405
+ {
1406
+ x: viewBox.cx,
1407
+ y: Number(viewBox.cy) + 22,
1408
+ className: "fill-muted-foreground text-xs",
1409
+ children: centerLabel
1410
+ }
1411
+ ) : null
1412
+ ]
1413
+ }
1414
+ );
1415
+ }
1416
+ }
1417
+ ) : null
1418
+ ]
1419
+ }
1420
+ )
1421
+ ] })
1422
+ }
1423
+ );
1424
+ }
1425
+ function SparklineChart({
1426
+ data,
1427
+ dataKey,
1428
+ color = "var(--chart-1)",
1429
+ filled = true,
1430
+ showEndDot = true,
1431
+ curveType = "monotone",
1432
+ strokeWidth = 2,
1433
+ className
1434
+ }) {
1435
+ const sparkId = React__namespace.useId().replace(/:/g, "");
1436
+ const lastPoint = data[data.length - 1];
1437
+ const lastValue = lastPoint ? lastPoint[dataKey] : void 0;
1438
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("relative h-12 w-full min-w-0", className), children: [
1439
+ /* @__PURE__ */ jsxRuntime.jsx(RechartsPrimitive__namespace.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
1440
+ RechartsPrimitive__namespace.AreaChart,
1441
+ {
1442
+ data,
1443
+ margin: { top: 4, right: showEndDot ? 8 : 0, bottom: 0, left: 0 },
1444
+ children: [
1445
+ filled && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
1446
+ "linearGradient",
1447
+ {
1448
+ id: `spark-gradient-${sparkId}`,
1449
+ x1: "0",
1450
+ y1: "0",
1451
+ x2: "0",
1452
+ y2: "1",
1453
+ children: [
1454
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: color, stopOpacity: 0.3 }),
1455
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "95%", stopColor: color, stopOpacity: 0 })
1456
+ ]
1457
+ }
1458
+ ) }),
1459
+ /* @__PURE__ */ jsxRuntime.jsx(
1460
+ RechartsPrimitive__namespace.Area,
1461
+ {
1462
+ type: curveType,
1463
+ dataKey,
1464
+ stroke: color,
1465
+ strokeWidth,
1466
+ fill: filled ? `url(#spark-gradient-${sparkId})` : "none",
1467
+ fillOpacity: 1,
1468
+ dot: false,
1469
+ activeDot: false,
1470
+ isAnimationActive: true,
1471
+ animationDuration: 600,
1472
+ animationEasing: "ease-out"
1473
+ }
1474
+ )
1475
+ ]
1476
+ }
1477
+ ) }),
1478
+ showEndDot && lastValue !== void 0 && lastValue !== null && /* @__PURE__ */ jsxRuntime.jsx(
1479
+ "div",
1480
+ {
1481
+ className: "pointer-events-none absolute right-0 top-1/2 h-2.5 w-2.5 -translate-y-1/2 rounded-full ring-2 ring-background",
1482
+ style: { backgroundColor: color }
1483
+ }
1484
+ )
1485
+ ] });
1486
+ }
1487
+ function RadarMetricChart({
1488
+ data,
1489
+ labelKey,
1490
+ series,
1491
+ colors,
1492
+ filled = true,
1493
+ fillOpacity = 0.25,
1494
+ showDots = false,
1495
+ showGrid = true,
1496
+ showLegend,
1497
+ valueFormatter,
1498
+ isLoading,
1499
+ error,
1500
+ onRetry,
1501
+ retryLabel,
1502
+ emptyTitle,
1503
+ emptyDescription,
1504
+ errorTitle,
1505
+ errorDescription,
1506
+ loadingLabel,
1507
+ stateClassName,
1508
+ className
1509
+ }) {
1510
+ const chartConfig = React__namespace.useMemo(
1511
+ () => buildChartConfig(series.map((s) => s.key), colors),
1512
+ [series, colors]
1513
+ );
1514
+ const hasData = data.length > 0 && series.length > 0;
1515
+ const chartState = getChartState(
1516
+ { isLoading, error, emptyTitle, emptyDescription, errorTitle, errorDescription, loadingLabel, stateClassName, onRetry, retryLabel },
1517
+ hasData,
1518
+ stateClassName
1519
+ );
1520
+ const displayLegend = showLegend ?? series.length > 1;
1521
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[300px] w-full", className), children: chartState ?? /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.RadarChart, { data, accessibilityLayer: true, children: [
1522
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(
1523
+ RechartsPrimitive__namespace.PolarGrid,
1524
+ {
1525
+ stroke: "var(--border)",
1526
+ strokeOpacity: 0.6
1527
+ }
1528
+ ),
1529
+ /* @__PURE__ */ jsxRuntime.jsx(
1530
+ RechartsPrimitive__namespace.PolarAngleAxis,
1531
+ {
1532
+ dataKey: labelKey,
1533
+ tick: { fill: "var(--muted-foreground)", fontSize: 12 }
1534
+ }
1535
+ ),
1536
+ /* @__PURE__ */ jsxRuntime.jsx(
1537
+ RechartsPrimitive__namespace.PolarRadiusAxis,
1538
+ {
1539
+ tick: false,
1540
+ axisLine: false,
1541
+ tickFormatter: valueFormatter
1542
+ }
1543
+ ),
1544
+ /* @__PURE__ */ jsxRuntime.jsx(
1545
+ ChartTooltip,
1546
+ {
1547
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1548
+ ChartTooltipContent,
1549
+ {
1550
+ formatter: valueFormatter ? (v) => valueFormatter(v) : void 0
1551
+ }
1552
+ )
1553
+ }
1554
+ ),
1555
+ displayLegend && /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, {}) }),
1556
+ series.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
1557
+ RechartsPrimitive__namespace.Radar,
1558
+ {
1559
+ name: s.label ?? s.key,
1560
+ dataKey: s.key,
1561
+ stroke: `var(--color-${s.key})`,
1562
+ fill: filled ? `var(--color-${s.key})` : "none",
1563
+ fillOpacity: filled ? fillOpacity : 0,
1564
+ dot: showDots ? { r: 3, fill: `var(--color-${s.key})` } : false,
1565
+ isAnimationActive: true,
1566
+ animationDuration: 600,
1567
+ animationEasing: "ease-out"
1568
+ },
1569
+ s.key
1570
+ ))
1571
+ ] }) });
1572
+ }
1573
+ function PieMetricChart({
1574
+ data,
1575
+ nameKey,
1576
+ valueKey,
1577
+ colors,
1578
+ outerRadius = "80%",
1579
+ innerRadius = 0,
1580
+ showLabels = false,
1581
+ showLegend = true,
1582
+ explodeIndex,
1583
+ explodeOffset = 12,
1584
+ valueFormatter,
1585
+ isLoading,
1586
+ error,
1587
+ onRetry,
1588
+ retryLabel,
1589
+ emptyTitle,
1590
+ emptyDescription,
1591
+ errorTitle,
1592
+ errorDescription,
1593
+ loadingLabel,
1594
+ stateClassName,
1595
+ className
1596
+ }) {
1597
+ const names = React__namespace.useMemo(
1598
+ () => data.map((d) => String(d[nameKey] ?? "")),
1599
+ [data, nameKey]
1600
+ );
1601
+ const chartConfig = React__namespace.useMemo(
1602
+ () => buildChartConfig(names, colors),
1603
+ [names, colors]
1604
+ );
1605
+ const hasData = hasPieData(data, nameKey, valueKey);
1606
+ const chartState = getChartState(
1607
+ { isLoading, error, emptyTitle, emptyDescription, errorTitle, errorDescription, loadingLabel, stateClassName, onRetry, retryLabel },
1608
+ hasData,
1609
+ stateClassName
1610
+ );
1611
+ return /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: button.cn("h-[300px] w-full", className), children: chartState ?? /* @__PURE__ */ jsxRuntime.jsxs(RechartsPrimitive__namespace.PieChart, { accessibilityLayer: true, children: [
1612
+ /* @__PURE__ */ jsxRuntime.jsx(
1613
+ ChartTooltip,
1614
+ {
1615
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1616
+ ChartTooltipContent,
1617
+ {
1618
+ nameKey,
1619
+ formatter: valueFormatter ? (v) => valueFormatter(v) : void 0
1620
+ }
1621
+ )
1622
+ }
1623
+ ),
1624
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(ChartLegend, { content: /* @__PURE__ */ jsxRuntime.jsx(ChartLegendContent, { nameKey }) }),
1625
+ /* @__PURE__ */ jsxRuntime.jsx(
1626
+ RechartsPrimitive__namespace.Pie,
1627
+ {
1628
+ data,
1629
+ dataKey: valueKey,
1630
+ nameKey,
1631
+ outerRadius,
1632
+ innerRadius,
1633
+ paddingAngle: 2,
1634
+ label: showLabels ? ({ cx, cy, midAngle, innerRadius: ir, outerRadius: or, percent }) => {
1635
+ const RADIAN = Math.PI / 180;
1636
+ const radius = Number(ir) + (Number(or) - Number(ir)) * 1.35;
1637
+ const x = Number(cx) + radius * Math.cos(-midAngle * RADIAN);
1638
+ const y = Number(cy) + radius * Math.sin(-midAngle * RADIAN);
1639
+ return percent > 0.04 ? /* @__PURE__ */ jsxRuntime.jsx(
1640
+ "text",
1641
+ {
1642
+ x,
1643
+ y,
1644
+ fill: "var(--foreground)",
1645
+ textAnchor: x > Number(cx) ? "start" : "end",
1646
+ dominantBaseline: "central",
1647
+ fontSize: 12,
1648
+ fontWeight: 500,
1649
+ children: `${(percent * 100).toFixed(0)}%`
1650
+ }
1651
+ ) : null;
1652
+ } : false,
1653
+ labelLine: false,
1654
+ isAnimationActive: true,
1655
+ animationDuration: 600,
1656
+ animationEasing: "ease-out",
1657
+ children: data.map((entry, index) => {
1658
+ var _a, _b;
1659
+ const name = String(entry[nameKey] ?? "");
1660
+ const isExploded = index === explodeIndex;
1661
+ return /* @__PURE__ */ jsxRuntime.jsx(
1662
+ RechartsPrimitive__namespace.Cell,
1663
+ {
1664
+ fill: ((_a = chartConfig[name]) == null ? void 0 : _a.color) ?? `var(--chart-${index % 8 + 1})`,
1665
+ stroke: "var(--background)",
1666
+ strokeWidth: 2,
1667
+ style: isExploded ? { filter: `drop-shadow(0 4px 8px color-mix(in srgb, ${((_b = chartConfig[name]) == null ? void 0 : _b.color) ?? "var(--chart-1)"} 40%, transparent))` } : void 0
1668
+ },
1669
+ `cell-${index}`
1670
+ );
1671
+ })
1672
+ }
1673
+ )
1674
+ ] }) });
1675
+ }
1676
+ function RadialBarMetricChart({
1677
+ data,
1678
+ dataKey = "value",
1679
+ nameKey = "name",
1680
+ colors,
1681
+ innerRadius = "30%",
1682
+ outerRadius = "100%",
1683
+ startAngle = 90,
1684
+ endAngle = -270,
1685
+ showBackground = true,
1686
+ showLegend = true,
1687
+ valueFormatter,
1688
+ isLoading,
1689
+ error,
1690
+ onRetry,
1691
+ retryLabel,
1692
+ emptyTitle,
1693
+ emptyDescription,
1694
+ errorTitle,
1695
+ errorDescription,
1696
+ loadingLabel,
1697
+ stateClassName,
1698
+ className
1699
+ }) {
1700
+ const names = React__namespace.useMemo(
1701
+ () => data.map((d) => String(d[nameKey] ?? "")),
1702
+ [data, nameKey]
1703
+ );
1704
+ const chartConfig = React__namespace.useMemo(
1705
+ () => buildChartConfig(names, colors),
1706
+ [names, colors]
1707
+ );
1708
+ const hasData = data.length > 0;
1709
+ const chartState = getChartState(
1710
+ { isLoading, error, emptyTitle, emptyDescription, errorTitle, errorDescription, loadingLabel, stateClassName, onRetry, retryLabel },
1711
+ hasData,
1712
+ stateClassName
1713
+ );
1714
+ const coloredData = React__namespace.useMemo(
1715
+ () => data.map((item, index) => {
1716
+ var _a;
1717
+ const name = String(item[nameKey] ?? "");
1718
+ return {
1719
+ ...item,
1720
+ fill: ((_a = chartConfig[name]) == null ? void 0 : _a.color) ?? `var(--chart-${index % 8 + 1})`
1721
+ };
1722
+ }),
1723
+ [data, nameKey, chartConfig]
1724
+ );
1725
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("flex w-full flex-col gap-3", className), children: [
1726
+ /* @__PURE__ */ jsxRuntime.jsx(ChartContainer, { config: chartConfig, className: "h-[260px] w-full", children: chartState ?? /* @__PURE__ */ jsxRuntime.jsxs(
1727
+ RechartsPrimitive__namespace.RadialBarChart,
1728
+ {
1729
+ data: coloredData,
1730
+ innerRadius,
1731
+ outerRadius,
1732
+ startAngle,
1733
+ endAngle,
1734
+ accessibilityLayer: true,
1735
+ children: [
1736
+ /* @__PURE__ */ jsxRuntime.jsx(
1737
+ ChartTooltip,
1738
+ {
1739
+ cursor: false,
1740
+ content: /* @__PURE__ */ jsxRuntime.jsx(
1741
+ ChartTooltipContent,
1742
+ {
1743
+ nameKey,
1744
+ formatter: valueFormatter ? (v) => valueFormatter(v) : void 0
1745
+ }
1746
+ )
1747
+ }
1748
+ ),
1749
+ /* @__PURE__ */ jsxRuntime.jsx(
1750
+ RechartsPrimitive__namespace.RadialBar,
1751
+ {
1752
+ dataKey,
1753
+ background: showBackground ? { fill: "var(--muted)" } : false,
1754
+ cornerRadius: 6,
1755
+ isAnimationActive: true,
1756
+ animationDuration: 700,
1757
+ animationEasing: "ease-out"
1758
+ }
1759
+ )
1760
+ ]
1761
+ }
1762
+ ) }),
1763
+ showLegend && !chartState && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-x-4 gap-y-1.5 px-2", children: coloredData.map((item, index) => {
1764
+ const d = item;
1765
+ const name = String(d[nameKey] ?? "");
1766
+ const fillColor = d.fill ?? `var(--chart-${index % 8 + 1})`;
1767
+ const val = d[dataKey];
1768
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
1769
+ /* @__PURE__ */ jsxRuntime.jsx(
1770
+ "span",
1771
+ {
1772
+ className: "inline-block h-2.5 w-2.5 shrink-0 rounded-full",
1773
+ style: { backgroundColor: fillColor }
1774
+ }
1775
+ ),
1776
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
1777
+ name,
1778
+ val !== void 0 && val !== null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 font-medium text-foreground", children: valueFormatter ? valueFormatter(val) : String(val) })
1779
+ ] })
1780
+ ] }, name);
1781
+ }) })
1782
+ ] });
1783
+ }
1784
+ function GaugeChart({
1785
+ value,
1786
+ min = 0,
1787
+ max = 100,
1788
+ thresholds,
1789
+ label,
1790
+ valueFormatter,
1791
+ showNeedle = true,
1792
+ className
1793
+ }) {
1794
+ const percent = Math.min(1, Math.max(0, (value - min) / (max - min)));
1795
+ const percentInt = Math.round(percent * 100);
1796
+ const activeColor = React__namespace.useMemo(() => {
1797
+ if (!thresholds || thresholds.length === 0) return "var(--chart-1)";
1798
+ for (const t of thresholds) {
1799
+ if (percentInt <= t.value) return t.color;
1800
+ }
1801
+ return thresholds[thresholds.length - 1].color;
1802
+ }, [thresholds, percentInt]);
1803
+ const displayText = valueFormatter ? valueFormatter(value, percentInt) : `${percentInt}%`;
1804
+ const cx = 100;
1805
+ const cy = 100;
1806
+ const R = 80;
1807
+ const r = 54;
1808
+ const polar = (angleDeg, radius) => {
1809
+ const rad = angleDeg * Math.PI / 180;
1810
+ return {
1811
+ x: cx + radius * Math.cos(rad),
1812
+ y: cy - radius * Math.sin(rad)
1813
+ };
1814
+ };
1815
+ const trackStart = polar(180, R);
1816
+ const trackEnd = polar(0, R);
1817
+ const trackStartI = polar(180, r);
1818
+ const trackEndI = polar(0, r);
1819
+ const trackPath = [
1820
+ `M ${trackStart.x} ${trackStart.y}`,
1821
+ `A ${R} ${R} 0 0 1 ${trackEnd.x} ${trackEnd.y}`,
1822
+ `L ${trackEndI.x} ${trackEndI.y}`,
1823
+ `A ${r} ${r} 0 0 0 ${trackStartI.x} ${trackStartI.y}`,
1824
+ "Z"
1825
+ ].join(" ");
1826
+ const valueAngle = 180 - percent * 180;
1827
+ const valueEnd = polar(valueAngle, R);
1828
+ const valueEndI = polar(valueAngle, r);
1829
+ const valuePath = percent <= 0 ? "" : percent >= 1 ? trackPath : [
1830
+ `M ${trackStart.x} ${trackStart.y}`,
1831
+ `A ${R} ${R} 0 0 1 ${valueEnd.x} ${valueEnd.y}`,
1832
+ `L ${valueEndI.x} ${valueEndI.y}`,
1833
+ `A ${r} ${r} 0 0 0 ${trackStartI.x} ${trackStartI.y}`,
1834
+ "Z"
1835
+ ].join(" ");
1836
+ const needleAngle = 180 - percent * 180;
1837
+ const needleTip = polar(needleAngle, r - 6);
1838
+ const needleBase1 = polar(needleAngle + 90, 5);
1839
+ const needleBase2 = polar(needleAngle - 90, 5);
1840
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("flex flex-col items-center gap-2", className), children: [
1841
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full max-w-[260px]", children: /* @__PURE__ */ jsxRuntime.jsxs(
1842
+ "svg",
1843
+ {
1844
+ viewBox: "0 0 200 130",
1845
+ className: "w-full",
1846
+ "aria-label": `Gauge: ${displayText}`,
1847
+ children: [
1848
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: trackPath, fill: "var(--muted)" }),
1849
+ valuePath && /* @__PURE__ */ jsxRuntime.jsx("path", { d: valuePath, fill: activeColor }),
1850
+ showNeedle && /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1851
+ /* @__PURE__ */ jsxRuntime.jsx(
1852
+ "polygon",
1853
+ {
1854
+ points: `${needleTip.x},${needleTip.y} ${needleBase1.x},${needleBase1.y} ${needleBase2.x},${needleBase2.y}`,
1855
+ fill: "var(--foreground)",
1856
+ opacity: 0.85
1857
+ }
1858
+ ),
1859
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: 5, fill: "var(--foreground)" })
1860
+ ] }),
1861
+ /* @__PURE__ */ jsxRuntime.jsx(
1862
+ "text",
1863
+ {
1864
+ x: cx,
1865
+ y: cy + 18,
1866
+ textAnchor: "middle",
1867
+ dominantBaseline: "middle",
1868
+ fontSize: 22,
1869
+ fontWeight: 700,
1870
+ fill: "currentColor",
1871
+ className: "fill-foreground",
1872
+ children: displayText
1873
+ }
1874
+ ),
1875
+ label && /* @__PURE__ */ jsxRuntime.jsx(
1876
+ "text",
1877
+ {
1878
+ x: cx,
1879
+ y: cy + 36,
1880
+ textAnchor: "middle",
1881
+ dominantBaseline: "middle",
1882
+ fontSize: 10,
1883
+ fill: "currentColor",
1884
+ className: "fill-muted-foreground",
1885
+ children: label
1886
+ }
1887
+ )
1888
+ ]
1889
+ }
1890
+ ) }),
1891
+ thresholds && thresholds.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-x-3 gap-y-1", children: thresholds.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
1892
+ /* @__PURE__ */ jsxRuntime.jsx(
1893
+ "span",
1894
+ {
1895
+ className: "inline-block h-2 w-2 shrink-0 rounded-full",
1896
+ style: { backgroundColor: t.color }
1897
+ }
1898
+ ),
1899
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: t.label })
1900
+ ] }, i)) })
1901
+ ] });
1902
+ }
1903
+ function Table({ className, ...props }) {
1904
+ return /* @__PURE__ */ jsxRuntime.jsx(
1905
+ "div",
1906
+ {
1907
+ "data-slot": "table-container",
1908
+ className: "relative w-full overflow-x-auto",
1909
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1910
+ "table",
1911
+ {
1912
+ "data-slot": "table",
1913
+ className: button.cn("w-full caption-bottom text-sm", className),
1914
+ ...props
1915
+ }
1916
+ )
1917
+ }
1918
+ );
1919
+ }
1920
+ function TableHeader({ className, ...props }) {
1921
+ return /* @__PURE__ */ jsxRuntime.jsx(
1922
+ "thead",
1923
+ {
1924
+ "data-slot": "table-header",
1925
+ className: button.cn("[&_tr]:border-b", className),
1926
+ ...props
1927
+ }
1928
+ );
1929
+ }
1930
+ function TableBody({ className, ...props }) {
1931
+ return /* @__PURE__ */ jsxRuntime.jsx(
1932
+ "tbody",
1933
+ {
1934
+ "data-slot": "table-body",
1935
+ className: button.cn("[&_tr:last-child]:border-0", className),
1936
+ ...props
1937
+ }
1938
+ );
1939
+ }
1940
+ function TableFooter({ className, ...props }) {
1941
+ return /* @__PURE__ */ jsxRuntime.jsx(
1942
+ "tfoot",
1943
+ {
1944
+ "data-slot": "table-footer",
1945
+ className: button.cn(
1946
+ "bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
1947
+ className
1948
+ ),
1949
+ ...props
1950
+ }
1951
+ );
1952
+ }
1953
+ function TableRow({ className, ...props }) {
1954
+ return /* @__PURE__ */ jsxRuntime.jsx(
1955
+ "tr",
1956
+ {
1957
+ "data-slot": "table-row",
1958
+ className: button.cn(
1959
+ "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
1960
+ className
1961
+ ),
1962
+ ...props
1963
+ }
1964
+ );
1965
+ }
1966
+ function TableHead({ className, ...props }) {
1967
+ return /* @__PURE__ */ jsxRuntime.jsx(
1968
+ "th",
1969
+ {
1970
+ "data-slot": "table-head",
1971
+ className: button.cn(
1972
+ "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1973
+ className
1974
+ ),
1975
+ ...props
1976
+ }
1977
+ );
1978
+ }
1979
+ function TableCell({ className, ...props }) {
1980
+ return /* @__PURE__ */ jsxRuntime.jsx(
1981
+ "td",
1982
+ {
1983
+ "data-slot": "table-cell",
1984
+ className: button.cn(
1985
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
1986
+ className
1987
+ ),
1988
+ ...props
1989
+ }
1990
+ );
1991
+ }
1992
+ function TableCaption({
1993
+ className,
1994
+ ...props
1995
+ }) {
1996
+ return /* @__PURE__ */ jsxRuntime.jsx(
1997
+ "caption",
1998
+ {
1999
+ "data-slot": "table-caption",
2000
+ className: button.cn("text-muted-foreground mt-4 text-sm", className),
2001
+ ...props
2002
+ }
2003
+ );
2004
+ }
2005
+ const Textarea = React__namespace.forwardRef(
2006
+ ({ className, size = "md", ...props }, ref) => {
2007
+ const sizeClasses = {
2008
+ sm: "px-2 py-1 text-sm",
2009
+ md: "px-3 py-2 text-base",
2010
+ lg: "px-4 py-3 text-base"
2011
+ };
2012
+ return /* @__PURE__ */ jsxRuntime.jsx(
2013
+ "textarea",
2014
+ {
2015
+ "data-slot": "textarea",
2016
+ className: button.cn(
2017
+ "flex min-h-16 w-full bg-background rounded-[var(--radius)] border border-border transition-colors outline-none resize-none text-foreground",
2018
+ "placeholder:text-muted-foreground",
2019
+ "focus:ring-2 focus:ring-primary focus:border-transparent",
2020
+ "disabled:cursor-not-allowed disabled:opacity-50",
2021
+ sizeClasses[size],
2022
+ className
2023
+ ),
2024
+ ref,
2025
+ ...props
2026
+ }
2027
+ );
2028
+ }
2029
+ );
2030
+ Textarea.displayName = "Textarea";
2031
+ function Dialog({
2032
+ ...props
2033
+ }) {
2034
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
2035
+ }
2036
+ function DialogTrigger({
2037
+ ...props
2038
+ }) {
2039
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Trigger, { "data-slot": "dialog-trigger", ...props });
2040
+ }
2041
+ function DialogPortal({
2042
+ ...props
2043
+ }) {
2044
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
2045
+ }
2046
+ function DialogClose({
2047
+ ...props
2048
+ }) {
2049
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { "data-slot": "dialog-close", ...props });
2050
+ }
2051
+ const DialogOverlay = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
2052
+ DialogPrimitive__namespace.Overlay,
2053
+ {
2054
+ ref,
2055
+ "data-slot": "dialog-overlay",
2056
+ className: button.cn(
2057
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/40 backdrop-blur-sm",
2058
+ className
2059
+ ),
2060
+ ...props
2061
+ }
2062
+ ));
2063
+ DialogOverlay.displayName = DialogPrimitive__namespace.Overlay.displayName;
2064
+ const dialogVariants = classVarianceAuthority.cva(
2065
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 flex flex-col w-full translate-x-[-50%] translate-y-[-50%] border shadow-elevation-sm duration-200 rounded-[var(--radius-card)] overflow-hidden max-h-[calc(100dvh-2rem)]",
2066
+ {
2067
+ variants: {
2068
+ size: {
2069
+ sm: "max-w-sm",
2070
+ md: "max-w-md",
2071
+ lg: "max-w-lg",
2072
+ xl: "max-w-xl",
2073
+ "2xl": "max-w-2xl",
2074
+ "3xl": "max-w-3xl",
2075
+ "4xl": "max-w-4xl",
2076
+ "5xl": "max-w-5xl",
2077
+ full: "max-w-[calc(100vw-2rem)] h-[calc(100dvh-2rem)]"
2078
+ }
2079
+ },
2080
+ defaultVariants: {
2081
+ size: "lg"
2082
+ }
2083
+ }
2084
+ );
2085
+ const DialogContent = React__namespace.forwardRef(({ className, children, size, showClose = true, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
2086
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
2087
+ /* @__PURE__ */ jsxRuntime.jsxs(
2088
+ DialogPrimitive__namespace.Content,
2089
+ {
2090
+ ref,
2091
+ "data-slot": "dialog-content",
2092
+ className: button.cn(dialogVariants({ size }), className),
2093
+ ...props,
2094
+ children: [
2095
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 p-6 overflow-y-auto flex-1 min-h-0", children }),
2096
+ showClose && /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute top-4 right-4 z-10 rounded-full p-2 opacity-70 transition-all hover:opacity-100 hover:bg-accent focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:outline-none disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
2097
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
2098
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
2099
+ ] })
2100
+ ]
2101
+ }
2102
+ )
2103
+ ] }));
2104
+ DialogContent.displayName = DialogPrimitive__namespace.Content.displayName;
2105
+ function DialogHeader({ className, ...props }) {
2106
+ return /* @__PURE__ */ jsxRuntime.jsx(
2107
+ "div",
2108
+ {
2109
+ "data-slot": "dialog-header",
2110
+ className: button.cn("flex flex-col gap-2 text-left shrink-0", className),
2111
+ ...props
2112
+ }
2113
+ );
2114
+ }
2115
+ function DialogBody({ className, ...props }) {
2116
+ return /* @__PURE__ */ jsxRuntime.jsx(
2117
+ "div",
2118
+ {
2119
+ "data-slot": "dialog-body",
2120
+ className: button.cn("flex-1 overflow-y-auto min-h-0 -mx-6 px-6", className),
2121
+ ...props
2122
+ }
2123
+ );
2124
+ }
2125
+ function DialogFooter({ className, ...props }) {
2126
+ return /* @__PURE__ */ jsxRuntime.jsx(
2127
+ "div",
2128
+ {
2129
+ "data-slot": "dialog-footer",
2130
+ className: button.cn(
2131
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end shrink-0",
2132
+ className
2133
+ ),
2134
+ ...props
2135
+ }
2136
+ );
2137
+ }
2138
+ function DialogTitle({
2139
+ className,
2140
+ ...props
2141
+ }) {
2142
+ return /* @__PURE__ */ jsxRuntime.jsx(
2143
+ DialogPrimitive__namespace.Title,
2144
+ {
2145
+ "data-slot": "dialog-title",
2146
+ className: button.cn("text-foreground font-semibold leading-tight text-[length:var(--text-h4)]", className),
2147
+ ...props
2148
+ }
2149
+ );
2150
+ }
2151
+ function DialogDescription({
2152
+ className,
2153
+ ...props
2154
+ }) {
2155
+ return /* @__PURE__ */ jsxRuntime.jsx(
2156
+ DialogPrimitive__namespace.Description,
2157
+ {
2158
+ "data-slot": "dialog-description",
2159
+ className: button.cn("text-muted-foreground", className),
2160
+ ...props
2161
+ }
2162
+ );
2163
+ }
2164
+ function useRichTextEditor({
2165
+ value,
2166
+ onChange
2167
+ }) {
2168
+ const editorRef = React.useRef(null);
2169
+ const searchInputRef = React.useRef(null);
2170
+ const linkInputRef = React.useRef(null);
2171
+ const savedSelection = React.useRef(null);
2172
+ const [activeFormats, setActiveFormats] = React.useState({
2173
+ bold: false,
2174
+ italic: false,
2175
+ underline: false,
2176
+ justifyLeft: false,
2177
+ justifyCenter: false,
2178
+ justifyRight: false,
2179
+ insertUnorderedList: false,
2180
+ insertOrderedList: false,
2181
+ link: false,
2182
+ h1: false,
2183
+ h2: false,
2184
+ h3: false,
2185
+ p: true
2186
+ });
2187
+ const [isSearchOpen, setIsSearchOpen] = React.useState(false);
2188
+ const [searchQuery, setSearchQuery] = React.useState("");
2189
+ const [linkUrl, setLinkUrl] = React.useState("https://");
2190
+ const [isLinkOpen, setIsLinkOpen] = React.useState(false);
2191
+ const [hasSavedSelection, setHasSavedSelection] = React.useState(false);
2192
+ const findParentTag = React.useCallback((node, tagName) => {
2193
+ let current = node;
2194
+ while (current && current !== editorRef.current) {
2195
+ if (current.nodeName === tagName) return current;
2196
+ current = current.parentNode;
2197
+ }
2198
+ return null;
2199
+ }, []);
2200
+ const updateActiveFormats = React.useCallback(() => {
2201
+ let formatBlock = "";
2202
+ try {
2203
+ formatBlock = document.queryCommandValue("formatBlock");
2204
+ } catch (_e) {
2205
+ }
2206
+ const selection = window.getSelection();
2207
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2208
+ const focusNode = selection == null ? void 0 : selection.focusNode;
2209
+ setActiveFormats({
2210
+ bold: document.queryCommandState("bold"),
2211
+ italic: document.queryCommandState("italic"),
2212
+ underline: document.queryCommandState("underline"),
2213
+ justifyLeft: document.queryCommandState("justifyLeft"),
2214
+ justifyCenter: document.queryCommandState("justifyCenter"),
2215
+ justifyRight: document.queryCommandState("justifyRight"),
2216
+ insertUnorderedList: document.queryCommandState("insertUnorderedList"),
2217
+ insertOrderedList: document.queryCommandState("insertOrderedList"),
2218
+ link: !!(findParentTag(anchorNode || null, "A") || findParentTag(focusNode || null, "A")),
2219
+ h1: formatBlock === "h1" || formatBlock === "H1",
2220
+ h2: formatBlock === "h2" || formatBlock === "H2",
2221
+ h3: formatBlock === "h3" || formatBlock === "H3",
2222
+ p: formatBlock === "p" || formatBlock === "P" || formatBlock === "div" || formatBlock === "DIV" || formatBlock === ""
2223
+ });
2224
+ }, [findParentTag]);
2225
+ React.useEffect(() => {
2226
+ if (editorRef.current && editorRef.current.innerHTML !== value) {
2227
+ editorRef.current.innerHTML = value;
2228
+ }
2229
+ const handleSelectionChange = () => {
2230
+ if (document.activeElement === editorRef.current) {
2231
+ updateActiveFormats();
2232
+ }
2233
+ };
2234
+ document.addEventListener("selectionchange", handleSelectionChange);
2235
+ return () => document.removeEventListener("selectionchange", handleSelectionChange);
2236
+ }, []);
2237
+ const wordCount = (() => {
2238
+ var _a;
2239
+ const text = ((_a = editorRef.current) == null ? void 0 : _a.innerText) || "";
2240
+ return text.trim() ? text.trim().split(/\s+/).length : 0;
2241
+ })();
2242
+ const characterCount = (() => {
2243
+ var _a;
2244
+ const text = ((_a = editorRef.current) == null ? void 0 : _a.innerText) || "";
2245
+ return text.trim() ? text.length : 0;
2246
+ })();
2247
+ const handleInput = React.useCallback(() => {
2248
+ if (editorRef.current) {
2249
+ onChange == null ? void 0 : onChange(editorRef.current.innerHTML);
2250
+ updateActiveFormats();
2251
+ }
2252
+ }, [onChange, updateActiveFormats]);
2253
+ const execCommand = React.useCallback((command, val = "") => {
2254
+ var _a;
2255
+ document.execCommand(command, false, val);
2256
+ updateActiveFormats();
2257
+ (_a = editorRef.current) == null ? void 0 : _a.focus();
2258
+ if (editorRef.current) {
2259
+ onChange == null ? void 0 : onChange(editorRef.current.innerHTML);
2260
+ }
2261
+ }, [onChange, updateActiveFormats]);
2262
+ const performSearch = React.useCallback((text, backward = false) => {
2263
+ var _a, _b;
2264
+ if (!text || !editorRef.current) return;
2265
+ const editor = editorRef.current;
2266
+ const selection = window.getSelection();
2267
+ if (!selection) return;
2268
+ const walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT);
2269
+ const segments = [];
2270
+ let offset = 0;
2271
+ let node;
2272
+ while (node = walker.nextNode()) {
2273
+ segments.push({ node, start: offset });
2274
+ offset += node.length;
2275
+ }
2276
+ const fullText = segments.reduce((acc, s) => acc + (s.node.textContent ?? ""), "");
2277
+ let searchFrom = 0;
2278
+ if (selection.rangeCount > 0) {
2279
+ const range2 = selection.getRangeAt(0);
2280
+ if (editor.contains(range2.startContainer)) {
2281
+ const seg = segments.find((s) => s.node === range2.startContainer);
2282
+ if (seg) {
2283
+ searchFrom = backward ? seg.start + range2.startOffset - 1 : seg.start + range2.endOffset;
2284
+ }
2285
+ }
2286
+ }
2287
+ const lowerFull = fullText.toLowerCase();
2288
+ const lowerQuery = text.toLowerCase();
2289
+ let matchStart = -1;
2290
+ if (backward) {
2291
+ matchStart = lowerFull.lastIndexOf(lowerQuery, Math.max(0, searchFrom));
2292
+ if (matchStart === -1) matchStart = lowerFull.lastIndexOf(lowerQuery);
2293
+ } else {
2294
+ matchStart = lowerFull.indexOf(lowerQuery, searchFrom);
2295
+ if (matchStart === -1) matchStart = lowerFull.indexOf(lowerQuery);
2296
+ }
2297
+ if (matchStart === -1) return;
2298
+ const matchEnd = matchStart + text.length;
2299
+ const range = document.createRange();
2300
+ let startSet = false;
2301
+ let endSet = false;
2302
+ for (let i = 0; i < segments.length && !endSet; i++) {
2303
+ const seg = segments[i];
2304
+ const segEnd = seg.start + seg.node.length;
2305
+ if (!startSet && matchStart < segEnd && matchStart >= seg.start) {
2306
+ range.setStart(seg.node, matchStart - seg.start);
2307
+ startSet = true;
2308
+ }
2309
+ if (startSet && matchEnd <= segEnd) {
2310
+ range.setEnd(seg.node, matchEnd - seg.start);
2311
+ endSet = true;
2312
+ }
2313
+ }
2314
+ if (startSet && endSet) {
2315
+ selection.removeAllRanges();
2316
+ selection.addRange(range);
2317
+ (_b = (_a = range.startContainer.parentElement) == null ? void 0 : _a.scrollIntoView) == null ? void 0 : _b.call(_a, { block: "nearest" });
2318
+ }
2319
+ }, []);
2320
+ const handleCreateLink = React.useCallback(() => {
2321
+ if (savedSelection.current) {
2322
+ const selection2 = window.getSelection();
2323
+ selection2 == null ? void 0 : selection2.removeAllRanges();
2324
+ selection2 == null ? void 0 : selection2.addRange(savedSelection.current);
2325
+ }
2326
+ const selection = window.getSelection();
2327
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2328
+ const existingLink = findParentTag(anchorNode || null, "A");
2329
+ if (existingLink) {
2330
+ if (linkUrl) {
2331
+ existingLink.setAttribute("href", linkUrl);
2332
+ existingLink.setAttribute("target", "_blank");
2333
+ existingLink.setAttribute("rel", "noopener noreferrer");
2334
+ existingLink.style.color = "hsl(var(--primary))";
2335
+ existingLink.style.textDecoration = "underline";
2336
+ existingLink.style.cursor = "pointer";
2337
+ }
2338
+ handleInput();
2339
+ setIsLinkOpen(false);
2340
+ savedSelection.current = null;
2341
+ return;
2342
+ }
2343
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
2344
+ return;
2345
+ }
2346
+ if (linkUrl) {
2347
+ document.execCommand("createLink", false, linkUrl);
2348
+ setTimeout(() => {
2349
+ var _a;
2350
+ const anchor = findParentTag(((_a = window.getSelection()) == null ? void 0 : _a.anchorNode) || null, "A");
2351
+ if (anchor) {
2352
+ anchor.setAttribute("target", "_blank");
2353
+ anchor.setAttribute("rel", "noopener noreferrer");
2354
+ anchor.style.color = "hsl(var(--primary))";
2355
+ anchor.style.textDecoration = "underline";
2356
+ anchor.style.cursor = "pointer";
2357
+ }
2358
+ handleInput();
2359
+ }, 10);
2360
+ setIsLinkOpen(false);
2361
+ savedSelection.current = null;
2362
+ }
2363
+ }, [linkUrl, findParentTag, handleInput]);
2364
+ const handleUnlink = React.useCallback(() => {
2365
+ const selection = window.getSelection();
2366
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2367
+ const existingLink = findParentTag(anchorNode || null, "A");
2368
+ if (existingLink) {
2369
+ const parent = existingLink.parentNode;
2370
+ while (existingLink.firstChild) {
2371
+ parent == null ? void 0 : parent.insertBefore(existingLink.firstChild, existingLink);
2372
+ }
2373
+ parent == null ? void 0 : parent.removeChild(existingLink);
2374
+ handleInput();
2375
+ } else {
2376
+ document.execCommand("unlink", false, "");
2377
+ }
2378
+ }, [findParentTag, handleInput]);
2379
+ const onLinkPopoverOpenChange = React.useCallback((open) => {
2380
+ if (open) {
2381
+ const selection = window.getSelection();
2382
+ const anchorNode = selection == null ? void 0 : selection.anchorNode;
2383
+ const focusNode = selection == null ? void 0 : selection.focusNode;
2384
+ const existingLink = findParentTag(anchorNode || null, "A") || findParentTag(focusNode || null, "A");
2385
+ if (existingLink) {
2386
+ setLinkUrl(existingLink.getAttribute("href") || "https://");
2387
+ } else {
2388
+ setLinkUrl("https://");
2389
+ }
2390
+ if (selection && selection.rangeCount > 0 && (!selection.isCollapsed || existingLink)) {
2391
+ savedSelection.current = selection.getRangeAt(0).cloneRange();
2392
+ setHasSavedSelection(true);
2393
+ } else {
2394
+ savedSelection.current = null;
2395
+ setHasSavedSelection(false);
2396
+ }
2397
+ setTimeout(() => {
2398
+ var _a;
2399
+ return (_a = linkInputRef.current) == null ? void 0 : _a.focus();
2400
+ }, 100);
2401
+ } else {
2402
+ setHasSavedSelection(false);
2403
+ }
2404
+ setIsLinkOpen(open);
2405
+ }, [findParentTag]);
2406
+ return {
2407
+ // Refs
2408
+ editorRef,
2409
+ searchInputRef,
2410
+ linkInputRef,
2411
+ // State
2412
+ activeFormats,
2413
+ isSearchOpen,
2414
+ setIsSearchOpen,
2415
+ searchQuery,
2416
+ setSearchQuery,
2417
+ linkUrl,
2418
+ setLinkUrl,
2419
+ isLinkOpen,
2420
+ hasSavedSelection,
2421
+ // Computed
2422
+ wordCount,
2423
+ characterCount,
2424
+ // Handlers
2425
+ updateActiveFormats,
2426
+ execCommand,
2427
+ handleInput,
2428
+ performSearch,
2429
+ handleCreateLink,
2430
+ handleUnlink,
2431
+ onLinkPopoverOpenChange
2432
+ };
2433
+ }
2434
+ function RichTextEditor({
2435
+ value,
2436
+ onChange,
2437
+ placeholder,
2438
+ className,
2439
+ actionButton,
2440
+ allowSearch = true,
2441
+ allowLinks = true,
2442
+ allowUndoRedo = true,
2443
+ allowHeadings = true,
2444
+ allowFormatting = true,
2445
+ allowAlignment = true,
2446
+ allowLists = true,
2447
+ showWordCount = true,
2448
+ showCharacterCount = true,
2449
+ disabled = false,
2450
+ readOnly = false,
2451
+ onFocus,
2452
+ onBlur,
2453
+ minHeight,
2454
+ maxHeight
2455
+ }) {
2456
+ const isEditable = !disabled && !readOnly;
2457
+ const showToolbar = isEditable;
2458
+ const {
2459
+ editorRef,
2460
+ searchInputRef,
2461
+ linkInputRef,
2462
+ activeFormats,
2463
+ isSearchOpen,
2464
+ setIsSearchOpen,
2465
+ searchQuery,
2466
+ setSearchQuery,
2467
+ linkUrl,
2468
+ setLinkUrl,
2469
+ isLinkOpen,
2470
+ hasSavedSelection,
2471
+ wordCount,
2472
+ characterCount,
2473
+ updateActiveFormats,
2474
+ execCommand,
2475
+ handleInput,
2476
+ performSearch,
2477
+ handleCreateLink,
2478
+ handleUnlink,
2479
+ onLinkPopoverOpenChange
2480
+ } = useRichTextEditor({ value, onChange });
2481
+ const getCurrentBlockLabel = () => {
2482
+ if (activeFormats.h1) return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2483
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading1, { className: "w-4 h-4 mr-1 shrink-0" }),
2484
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Título 1" })
2485
+ ] });
2486
+ if (activeFormats.h2) return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2487
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading2, { className: "w-4 h-4 mr-1 shrink-0" }),
2488
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Título 2" })
2489
+ ] });
2490
+ if (activeFormats.h3) return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2491
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading3, { className: "w-4 h-4 mr-1 shrink-0" }),
2492
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Título 3" })
2493
+ ] });
2494
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2495
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-4 h-4 mr-1 shrink-0" }),
2496
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: "Parágrafo" })
2497
+ ] });
2498
+ };
2499
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: button.cn("flex flex-col h-full w-full bg-background sm:border border-border sm:shadow-sm sm:rounded-lg overflow-hidden", disabled && "opacity-50 pointer-events-none", className), children: [
2500
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
2501
+ [contenteditable]:empty:before {
2502
+ content: attr(data-placeholder);
2503
+ color: hsl(var(--muted-foreground));
2504
+ pointer-events: none;
2505
+ display: block;
2506
+ }
2507
+ .prose-editor ul {
2508
+ list-style-type: disc !important;
2509
+ padding-left: 1.5rem !important;
2510
+ margin-top: 0.5rem !important;
2511
+ margin-bottom: 0.5rem !important;
2512
+ }
2513
+ .prose-editor ol {
2514
+ list-style-type: decimal !important;
2515
+ padding-left: 1.5rem !important;
2516
+ margin-top: 0.5rem !important;
2517
+ margin-bottom: 0.5rem !important;
2518
+ }
2519
+ .prose-editor b, .prose-editor strong {
2520
+ font-weight: 600 !important;
2521
+ }
2522
+ .prose-editor i, .prose-editor em {
2523
+ font-style: italic !important;
2524
+ }
2525
+ .prose-editor u {
2526
+ text-decoration: underline !important;
2527
+ }
2528
+ .prose-editor h1 {
2529
+ font-size: 2.25rem !important;
2530
+ font-weight: 700 !important;
2531
+ margin-bottom: 1.25rem !important;
2532
+ line-height: 1.2 !important;
2533
+ margin-top: 2rem !important;
2534
+ color: hsl(var(--foreground));
2535
+ }
2536
+ .prose-editor h2 {
2537
+ font-size: 1.75rem !important;
2538
+ font-weight: 600 !important;
2539
+ margin-bottom: 1rem !important;
2540
+ margin-top: 1.5rem !important;
2541
+ color: hsl(var(--foreground));
2542
+ }
2543
+ .prose-editor h3 {
2544
+ font-size: 1.35rem !important;
2545
+ font-weight: 600 !important;
2546
+ margin-bottom: 0.75rem !important;
2547
+ margin-top: 1.25rem !important;
2548
+ color: hsl(var(--foreground));
2549
+ }
2550
+ .prose-editor p {
2551
+ margin-bottom: 1rem !important;
2552
+ line-height: 1.6 !important;
2553
+ }
2554
+ .prose-editor a {
2555
+ color: var(--info) !important;
2556
+ text-decoration: underline !important;
2557
+ cursor: pointer !important;
2558
+ }
2559
+ .prose-editor h1:first-child, .prose-editor h2:first-child, .prose-editor h3:first-child, .prose-editor p:first-child {
2560
+ margin-top: 0 !important;
2561
+ }
2562
+ .prose-editor {
2563
+ outline: none !important;
2564
+ }
2565
+ ` }),
2566
+ showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 border-b border-border bg-muted/30 flex items-center gap-1 flex-wrap shrink-0", children: [
2567
+ allowUndoRedo && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2568
+ /* @__PURE__ */ jsxRuntime.jsx(
2569
+ button.Button,
2570
+ {
2571
+ variant: "ghost",
2572
+ size: "icon",
2573
+ className: "h-8 w-8 text-muted-foreground",
2574
+ onClick: () => execCommand("undo"),
2575
+ title: "Desfazer",
2576
+ "aria-label": "Desfazer",
2577
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Undo, { className: "w-4 h-4" })
2578
+ }
2579
+ ),
2580
+ /* @__PURE__ */ jsxRuntime.jsx(
2581
+ button.Button,
2582
+ {
2583
+ variant: "ghost",
2584
+ size: "icon",
2585
+ className: "h-8 w-8 text-muted-foreground",
2586
+ onClick: () => execCommand("redo"),
2587
+ title: "Refazer",
2588
+ "aria-label": "Refazer",
2589
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Redo, { className: "w-4 h-4" })
2590
+ }
2591
+ ),
2592
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2593
+ ] }),
2594
+ allowHeadings && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2595
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenu, { modal: false, children: [
2596
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { variant: "ghost", size: "sm", className: "h-8 gap-0 text-muted-foreground w-[120px] justify-start px-2", children: [
2597
+ getCurrentBlockLabel(),
2598
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-3 h-3 ml-auto opacity-50 shrink-0" })
2599
+ ] }) }),
2600
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuContent, { align: "start", className: "w-[160px]", style: { zIndex: 9999 }, children: [
2601
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuItem, { onPointerDown: (e) => e.preventDefault(), onClick: () => execCommand("formatBlock", "P"), className: "gap-2", children: [
2602
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-4 h-4 text-muted-foreground" }),
2603
+ " Parágrafo"
2604
+ ] }),
2605
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuItem, { onPointerDown: (e) => e.preventDefault(), onClick: () => execCommand("formatBlock", "H1"), className: "gap-2", children: [
2606
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading1, { className: "w-4 h-4 text-muted-foreground" }),
2607
+ " Título 1"
2608
+ ] }),
2609
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuItem, { onPointerDown: (e) => e.preventDefault(), onClick: () => execCommand("formatBlock", "H2"), className: "gap-2", children: [
2610
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading2, { className: "w-4 h-4 text-muted-foreground" }),
2611
+ " Título 2"
2612
+ ] }),
2613
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuItem, { onPointerDown: (e) => e.preventDefault(), onClick: () => execCommand("formatBlock", "H3"), className: "gap-2", children: [
2614
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading3, { className: "w-4 h-4 text-muted-foreground" }),
2615
+ " Título 3"
2616
+ ] })
2617
+ ] })
2618
+ ] }),
2619
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2620
+ ] }),
2621
+ allowFormatting && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2622
+ /* @__PURE__ */ jsxRuntime.jsx(
2623
+ button.Button,
2624
+ {
2625
+ variant: "ghost",
2626
+ size: "icon",
2627
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.bold && "bg-muted text-foreground"),
2628
+ onClick: () => execCommand("bold"),
2629
+ title: "Negrito",
2630
+ "aria-label": "Negrito",
2631
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bold, { className: "w-4 h-4" })
2632
+ }
2633
+ ),
2634
+ /* @__PURE__ */ jsxRuntime.jsx(
2635
+ button.Button,
2636
+ {
2637
+ variant: "ghost",
2638
+ size: "icon",
2639
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.italic && "bg-muted text-foreground"),
2640
+ onClick: () => execCommand("italic"),
2641
+ title: "Itálico",
2642
+ "aria-label": "Itálico",
2643
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Italic, { className: "w-4 h-4" })
2644
+ }
2645
+ ),
2646
+ /* @__PURE__ */ jsxRuntime.jsx(
2647
+ button.Button,
2648
+ {
2649
+ variant: "ghost",
2650
+ size: "icon",
2651
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.underline && "bg-muted text-foreground"),
2652
+ onClick: () => execCommand("underline"),
2653
+ title: "Sublinhado",
2654
+ "aria-label": "Sublinhado",
2655
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Underline, { className: "w-4 h-4" })
2656
+ }
2657
+ ),
2658
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2659
+ ] }),
2660
+ allowAlignment && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2661
+ /* @__PURE__ */ jsxRuntime.jsx(
2662
+ button.Button,
2663
+ {
2664
+ variant: "ghost",
2665
+ size: "icon",
2666
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.justifyLeft && "bg-muted text-foreground"),
2667
+ onClick: () => execCommand("justifyLeft"),
2668
+ title: "Alinhar à esquerda",
2669
+ "aria-label": "Alinhar à esquerda",
2670
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignLeft, { className: "w-4 h-4" })
2671
+ }
2672
+ ),
2673
+ /* @__PURE__ */ jsxRuntime.jsx(
2674
+ button.Button,
2675
+ {
2676
+ variant: "ghost",
2677
+ size: "icon",
2678
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.justifyCenter && "bg-muted text-foreground"),
2679
+ onClick: () => execCommand("justifyCenter"),
2680
+ title: "Centralizar",
2681
+ "aria-label": "Centralizar",
2682
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignCenter, { className: "w-4 h-4" })
2683
+ }
2684
+ ),
2685
+ /* @__PURE__ */ jsxRuntime.jsx(
2686
+ button.Button,
2687
+ {
2688
+ variant: "ghost",
2689
+ size: "icon",
2690
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.justifyRight && "bg-muted text-foreground"),
2691
+ onClick: () => execCommand("justifyRight"),
2692
+ title: "Alinhar à direita",
2693
+ "aria-label": "Alinhar à direita",
2694
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignRight, { className: "w-4 h-4" })
2695
+ }
2696
+ ),
2697
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2698
+ ] }),
2699
+ allowLists && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2700
+ /* @__PURE__ */ jsxRuntime.jsx(
2701
+ button.Button,
2702
+ {
2703
+ variant: "ghost",
2704
+ size: "icon",
2705
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.insertUnorderedList && "bg-muted text-foreground"),
2706
+ onClick: () => execCommand("insertUnorderedList"),
2707
+ title: "Lista com marcadores",
2708
+ "aria-label": "Lista com marcadores",
2709
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.List, { className: "w-4 h-4" })
2710
+ }
2711
+ ),
2712
+ /* @__PURE__ */ jsxRuntime.jsx(
2713
+ button.Button,
2714
+ {
2715
+ variant: "ghost",
2716
+ size: "icon",
2717
+ className: button.cn("h-8 w-8 text-muted-foreground", activeFormats.insertOrderedList && "bg-muted text-foreground"),
2718
+ onClick: () => execCommand("insertOrderedList"),
2719
+ title: "Lista numerada",
2720
+ "aria-label": "Lista numerada",
2721
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrdered, { className: "w-4 h-4" })
2722
+ }
2723
+ ),
2724
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2725
+ ] }),
2726
+ allowLinks && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2727
+ /* @__PURE__ */ jsxRuntime.jsxs(input.Popover, { open: isLinkOpen, onOpenChange: onLinkPopoverOpenChange, modal: false, children: [
2728
+ /* @__PURE__ */ jsxRuntime.jsx(input.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2729
+ button.Button,
2730
+ {
2731
+ variant: "ghost",
2732
+ size: "icon",
2733
+ className: button.cn("h-8 w-8 text-muted-foreground", (activeFormats.link || isLinkOpen) && "bg-muted text-foreground"),
2734
+ title: "Inserir link",
2735
+ "aria-label": "Inserir link",
2736
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link, { className: "w-4 h-4" })
2737
+ }
2738
+ ) }),
2739
+ /* @__PURE__ */ jsxRuntime.jsx(input.PopoverContent, { className: "w-80 p-3", align: "start", style: { zIndex: 9999 }, children: !activeFormats.link && !hasSavedSelection ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground py-1", children: "Selecione um texto para criar um link." }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
2740
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-medium", children: activeFormats.link ? "Editar Link" : "Inserir Link" }),
2741
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
2742
+ /* @__PURE__ */ jsxRuntime.jsx(
2743
+ input.Input,
2744
+ {
2745
+ ref: linkInputRef,
2746
+ placeholder: "https://...",
2747
+ value: linkUrl,
2748
+ onChange: (e) => setLinkUrl(e.target.value),
2749
+ onKeyDown: (e) => {
2750
+ if (e.key === "Enter") {
2751
+ e.preventDefault();
2752
+ e.stopPropagation();
2753
+ handleCreateLink();
2754
+ }
2755
+ },
2756
+ className: "h-8 text-xs"
2757
+ }
2758
+ ),
2759
+ /* @__PURE__ */ jsxRuntime.jsx(button.Button, { size: "sm", className: "h-8", onClick: handleCreateLink, children: "Aplicar" })
2760
+ ] })
2761
+ ] }) })
2762
+ ] }),
2763
+ /* @__PURE__ */ jsxRuntime.jsx(
2764
+ button.Button,
2765
+ {
2766
+ variant: "ghost",
2767
+ size: "icon",
2768
+ className: "h-8 w-8 text-muted-foreground",
2769
+ onClick: handleUnlink,
2770
+ title: "Remover link",
2771
+ "aria-label": "Remover link",
2772
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
2773
+ }
2774
+ ),
2775
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border mx-1 hidden sm:block" })
2776
+ ] }),
2777
+ (allowFormatting || allowHeadings || allowAlignment || allowLists || allowLinks) && /* @__PURE__ */ jsxRuntime.jsx(
2778
+ button.Button,
2779
+ {
2780
+ variant: "ghost",
2781
+ size: "icon",
2782
+ className: "h-8 w-8 text-muted-foreground",
2783
+ onClick: () => execCommand("removeFormat"),
2784
+ title: "Limpar formatação",
2785
+ "aria-label": "Limpar formatação",
2786
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-4 h-4" })
2787
+ }
2788
+ ),
2789
+ allowSearch && /* @__PURE__ */ jsxRuntime.jsx(
2790
+ button.Button,
2791
+ {
2792
+ variant: "ghost",
2793
+ size: "icon",
2794
+ className: button.cn("h-8 w-8 text-muted-foreground", isSearchOpen && "bg-muted text-foreground"),
2795
+ onClick: () => {
2796
+ setIsSearchOpen(!isSearchOpen);
2797
+ if (!isSearchOpen) setTimeout(() => {
2798
+ var _a;
2799
+ return (_a = searchInputRef.current) == null ? void 0 : _a.focus();
2800
+ }, 100);
2801
+ },
2802
+ title: "Buscar",
2803
+ "aria-label": "Buscar",
2804
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "w-4 h-4" })
2805
+ }
2806
+ ),
2807
+ actionButton && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2808
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
2809
+ actionButton
2810
+ ] })
2811
+ ] }),
2812
+ isSearchOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-1.5 border-b border-border bg-muted/20 flex items-center gap-2", children: [
2813
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm", children: [
2814
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground" }),
2815
+ /* @__PURE__ */ jsxRuntime.jsx(
2816
+ input.Input,
2817
+ {
2818
+ ref: searchInputRef,
2819
+ placeholder: "Buscar no texto...",
2820
+ value: searchQuery,
2821
+ onChange: (e) => setSearchQuery(e.target.value),
2822
+ onKeyDown: (e) => {
2823
+ if (e.key === "Enter") {
2824
+ e.preventDefault();
2825
+ performSearch(searchQuery, e.shiftKey);
2826
+ }
2827
+ if (e.key === "Escape") {
2828
+ setIsSearchOpen(false);
2829
+ }
2830
+ },
2831
+ className: "h-8 pl-8 text-xs bg-background"
2832
+ }
2833
+ )
2834
+ ] }),
2835
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
2836
+ /* @__PURE__ */ jsxRuntime.jsx(
2837
+ button.Button,
2838
+ {
2839
+ variant: "ghost",
2840
+ size: "icon",
2841
+ className: "h-7 w-7",
2842
+ onMouseDown: (e) => e.preventDefault(),
2843
+ onClick: () => performSearch(searchQuery, true),
2844
+ title: "Anterior",
2845
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "w-4 h-4" })
2846
+ }
2847
+ ),
2848
+ /* @__PURE__ */ jsxRuntime.jsx(
2849
+ button.Button,
2850
+ {
2851
+ variant: "ghost",
2852
+ size: "icon",
2853
+ className: "h-7 w-7",
2854
+ onMouseDown: (e) => e.preventDefault(),
2855
+ onClick: () => performSearch(searchQuery, false),
2856
+ title: "Próximo",
2857
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "w-4 h-4" })
2858
+ }
2859
+ ),
2860
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-4 bg-border mx-1" }),
2861
+ /* @__PURE__ */ jsxRuntime.jsx(
2862
+ button.Button,
2863
+ {
2864
+ variant: "ghost",
2865
+ size: "icon",
2866
+ className: "h-7 w-7 text-muted-foreground hover:text-foreground",
2867
+ onClick: () => setIsSearchOpen(false),
2868
+ title: "Fechar busca",
2869
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-4 h-4" })
2870
+ }
2871
+ )
2872
+ ] }),
2873
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block text-[10px] text-muted-foreground ml-auto uppercase tracking-wider font-medium", children: "Pressione Enter para buscar" })
2874
+ ] }),
2875
+ /* @__PURE__ */ jsxRuntime.jsx(
2876
+ "div",
2877
+ {
2878
+ className: "flex-1 overflow-y-auto p-4 sm:p-8 bg-background scrollbar-thin",
2879
+ style: { minHeight, maxHeight },
2880
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2881
+ "div",
2882
+ {
2883
+ ref: editorRef,
2884
+ contentEditable: isEditable,
2885
+ onInput: handleInput,
2886
+ onSelect: isEditable ? updateActiveFormats : void 0,
2887
+ onFocus: () => {
2888
+ updateActiveFormats();
2889
+ onFocus == null ? void 0 : onFocus();
2890
+ },
2891
+ onBlur,
2892
+ className: "prose-editor min-h-full max-w-none focus:outline-none",
2893
+ "data-placeholder": placeholder
2894
+ }
2895
+ )
2896
+ }
2897
+ ),
2898
+ (showWordCount || showCharacterCount) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2 border-t border-border bg-muted/20 flex items-center justify-between", children: [
2899
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[10px] sm:text-xs text-muted-foreground font-medium uppercase tracking-wider flex items-center gap-2", children: [
2900
+ showWordCount && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2901
+ wordCount,
2902
+ " ",
2903
+ wordCount === 1 ? "palavra" : "palavras"
2904
+ ] }),
2905
+ showWordCount && showCharacterCount && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "•" }),
2906
+ showCharacterCount && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2907
+ characterCount,
2908
+ " ",
2909
+ characterCount === 1 ? "caractere" : "caracteres"
2910
+ ] })
2911
+ ] }),
2912
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] sm:text-xs text-muted-foreground italic", children: "Auto-save ativo" })
2913
+ ] })
2914
+ ] });
2915
+ }
2916
+ exports.Alert = Alert;
2917
+ exports.AlertDescription = AlertDescription;
2918
+ exports.AlertTitle = AlertTitle;
2919
+ exports.ChartCard = ChartCard;
2920
+ exports.ChartContainer = ChartContainer;
2921
+ exports.ChartLegend = ChartLegend;
2922
+ exports.ChartLegendContent = ChartLegendContent;
2923
+ exports.ChartStyle = ChartStyle;
2924
+ exports.ChartTooltip = ChartTooltip;
2925
+ exports.ChartTooltipContent = ChartTooltipContent;
2926
+ exports.ComboMetricChart = ComboMetricChart;
2927
+ exports.DashboardBarChart = DashboardBarChart;
2928
+ exports.DashboardLineChart = DashboardLineChart;
2929
+ exports.Dialog = Dialog;
2930
+ exports.DialogBody = DialogBody;
2931
+ exports.DialogClose = DialogClose;
2932
+ exports.DialogContent = DialogContent;
2933
+ exports.DialogDescription = DialogDescription;
2934
+ exports.DialogFooter = DialogFooter;
2935
+ exports.DialogHeader = DialogHeader;
2936
+ exports.DialogOverlay = DialogOverlay;
2937
+ exports.DialogPortal = DialogPortal;
2938
+ exports.DialogTitle = DialogTitle;
2939
+ exports.DialogTrigger = DialogTrigger;
2940
+ exports.DonutBreakdownChart = DonutBreakdownChart;
2941
+ exports.Empty = Empty;
2942
+ exports.EmptyAction = EmptyAction;
2943
+ exports.EmptyDescription = EmptyDescription;
2944
+ exports.EmptyIcon = EmptyIcon;
2945
+ exports.EmptyImage = EmptyImage;
2946
+ exports.EmptyTitle = EmptyTitle;
2947
+ exports.GaugeChart = GaugeChart;
2948
+ exports.HorizontalBarChart = HorizontalBarChart;
2949
+ exports.InteractiveTimeSeriesChart = InteractiveTimeSeriesChart;
2950
+ exports.PieMetricChart = PieMetricChart;
2951
+ exports.RadarMetricChart = RadarMetricChart;
2952
+ exports.RadialBarMetricChart = RadialBarMetricChart;
2953
+ exports.RichTextEditor = RichTextEditor;
2954
+ exports.Skeleton = Skeleton;
2955
+ exports.SparklineChart = SparklineChart;
2956
+ exports.Table = Table;
2957
+ exports.TableBody = TableBody;
2958
+ exports.TableCaption = TableCaption;
2959
+ exports.TableCell = TableCell;
2960
+ exports.TableFooter = TableFooter;
2961
+ exports.TableHead = TableHead;
2962
+ exports.TableHeader = TableHeader;
2963
+ exports.TableRow = TableRow;
2964
+ exports.Textarea = Textarea;
2965
+ exports.useChart = useChart;
2966
+ exports.useRichTextEditor = useRichTextEditor;