orbital-ds 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/AGENTS.md +162 -80
  2. package/components.manifest.json +1713 -1267
  3. package/contract.json +231 -168
  4. package/dist/hooks/use-ds-messages.d.ts +94 -0
  5. package/dist/hooks/use-ds-messages.js +18 -0
  6. package/dist/hooks/use-ds-motion.d.ts +17 -0
  7. package/dist/hooks/use-ds-motion.js +50 -0
  8. package/dist/lib/echarts-presets.d.ts +153 -0
  9. package/dist/lib/echarts-presets.js +311 -0
  10. package/dist/lib/echarts-server.d.ts +15 -0
  11. package/dist/lib/echarts-server.js +15 -0
  12. package/dist/lib/echarts-setup.d.ts +4 -0
  13. package/dist/lib/echarts-setup.js +60 -0
  14. package/dist/lib/echarts-theme.d.ts +36 -0
  15. package/dist/lib/echarts-theme.js +142 -0
  16. package/dist/lib/i18n.d.ts +102 -0
  17. package/dist/lib/i18n.js +275 -0
  18. package/dist/lib/motion.d.ts +74 -0
  19. package/dist/lib/motion.js +97 -0
  20. package/dist/styles.css +914 -528
  21. package/dist/themes/friendly.css +364 -318
  22. package/dist/themes/friendly.meta.json +75 -14
  23. package/dist/themes/friendly.scoped.css +364 -318
  24. package/dist/themes/friendly.tokens.json +45 -0
  25. package/dist/themes/qratia.meta.json +42 -12
  26. package/dist/themes/qratia.tokens.json +49 -0
  27. package/dist/themes/tactile.css +577 -430
  28. package/dist/themes/tactile.fonts.css +3 -2
  29. package/dist/themes/tactile.guide.md +82 -49
  30. package/dist/themes/tactile.meta.json +175 -82
  31. package/dist/themes/tactile.scoped.css +577 -430
  32. package/dist/themes/tactile.tokens.json +42 -0
  33. package/dist/themes/twitter.css +356 -298
  34. package/dist/themes/twitter.meta.json +83 -61
  35. package/dist/themes/twitter.scoped.css +356 -298
  36. package/dist/themes/twitter.tokens.json +45 -0
  37. package/dist/themes/zyro.css +445 -389
  38. package/dist/themes/zyro.meta.json +67 -14
  39. package/dist/themes/zyro.scoped.css +445 -389
  40. package/dist/themes/zyro.tokens.json +46 -0
  41. package/dist/ui/accordion.js +5 -5
  42. package/dist/ui/alert-dialog.js +3 -3
  43. package/dist/ui/alert.d.ts +1 -1
  44. package/dist/ui/alert.js +9 -3
  45. package/dist/ui/attachment.d.ts +1 -1
  46. package/dist/ui/attachment.js +4 -4
  47. package/dist/ui/avatar.js +6 -6
  48. package/dist/ui/ayuda.js +3 -2
  49. package/dist/ui/badge.d.ts +1 -1
  50. package/dist/ui/badge.js +9 -3
  51. package/dist/ui/banner.d.ts +14 -0
  52. package/dist/ui/banner.js +88 -0
  53. package/dist/ui/breadcrumb.js +7 -3
  54. package/dist/ui/bubble.js +6 -6
  55. package/dist/ui/button-group.js +4 -4
  56. package/dist/ui/button.d.ts +1 -1
  57. package/dist/ui/button.js +5 -5
  58. package/dist/ui/calendar.js +37 -6
  59. package/dist/ui/card.js +4 -4
  60. package/dist/ui/carousel.js +15 -8
  61. package/dist/ui/chart.js +7 -3
  62. package/dist/ui/checkbox.js +1 -1
  63. package/dist/ui/code-block.d.ts +14 -0
  64. package/dist/ui/code-block.js +106 -0
  65. package/dist/ui/combobox.js +7 -7
  66. package/dist/ui/command.js +13 -11
  67. package/dist/ui/context-menu.js +8 -8
  68. package/dist/ui/data-table.d.ts +185 -0
  69. package/dist/ui/data-table.js +714 -0
  70. package/dist/ui/date-picker.d.ts +65 -0
  71. package/dist/ui/date-picker.js +362 -0
  72. package/dist/ui/dialog.js +10 -6
  73. package/dist/ui/drawer.js +9 -9
  74. package/dist/ui/dropdown-menu.js +8 -8
  75. package/dist/ui/dropzone.d.ts +42 -0
  76. package/dist/ui/dropzone.js +220 -0
  77. package/dist/ui/echart.d.ts +31 -0
  78. package/dist/ui/echart.js +88 -0
  79. package/dist/ui/empty.js +3 -3
  80. package/dist/ui/eyebrow.d.ts +7 -0
  81. package/dist/ui/eyebrow.js +16 -0
  82. package/dist/ui/field.js +2 -2
  83. package/dist/ui/filter-bar.d.ts +36 -0
  84. package/dist/ui/filter-bar.js +193 -0
  85. package/dist/ui/heatmap-grid.d.ts +39 -0
  86. package/dist/ui/heatmap-grid.js +195 -0
  87. package/dist/ui/hover-card.js +1 -1
  88. package/dist/ui/i18n-provider.d.ts +11 -0
  89. package/dist/ui/i18n-provider.js +18 -0
  90. package/dist/ui/icon-tile.d.ts +1 -1
  91. package/dist/ui/input-group.d.ts +1 -1
  92. package/dist/ui/input-group.js +11 -9
  93. package/dist/ui/input-otp.js +3 -3
  94. package/dist/ui/input.js +1 -1
  95. package/dist/ui/item.d.ts +1 -1
  96. package/dist/ui/item.js +3 -3
  97. package/dist/ui/kbd.js +1 -1
  98. package/dist/ui/label.js +1 -1
  99. package/dist/ui/legend.d.ts +30 -0
  100. package/dist/ui/legend.js +124 -0
  101. package/dist/ui/marker.d.ts +1 -1
  102. package/dist/ui/marker.js +2 -2
  103. package/dist/ui/menubar.js +9 -9
  104. package/dist/ui/message-scroller.js +5 -2
  105. package/dist/ui/message.js +2 -2
  106. package/dist/ui/motion-provider.d.ts +11 -0
  107. package/dist/ui/motion-provider.js +16 -0
  108. package/dist/ui/native-select.js +4 -4
  109. package/dist/ui/navigation-menu.js +7 -6
  110. package/dist/ui/notifications.d.ts +69 -0
  111. package/dist/ui/notifications.js +335 -0
  112. package/dist/ui/page-header.d.ts +19 -0
  113. package/dist/ui/page-header.js +132 -0
  114. package/dist/ui/pagination.js +19 -11
  115. package/dist/ui/panel.d.ts +12 -0
  116. package/dist/ui/panel.js +41 -0
  117. package/dist/ui/popover.js +2 -2
  118. package/dist/ui/progress.js +2 -2
  119. package/dist/ui/proportion-bar.d.ts +27 -0
  120. package/dist/ui/proportion-bar.js +92 -0
  121. package/dist/ui/questionnaire.js +20 -15
  122. package/dist/ui/radio-group.js +2 -2
  123. package/dist/ui/resizable.js +2 -2
  124. package/dist/ui/scroll-area.js +3 -3
  125. package/dist/ui/select.js +6 -6
  126. package/dist/ui/separator.js +1 -1
  127. package/dist/ui/sheet.js +6 -4
  128. package/dist/ui/sidebar.js +42 -30
  129. package/dist/ui/skeleton.js +1 -1
  130. package/dist/ui/slider.js +6 -6
  131. package/dist/ui/sonner.js +25 -8
  132. package/dist/ui/sparkline.d.ts +26 -0
  133. package/dist/ui/sparkline.js +97 -0
  134. package/dist/ui/spinner.js +4 -1
  135. package/dist/ui/stat.d.ts +61 -0
  136. package/dist/ui/stat.js +238 -0
  137. package/dist/ui/status-badge.d.ts +38 -0
  138. package/dist/ui/status-badge.js +153 -0
  139. package/dist/ui/stepper.d.ts +20 -0
  140. package/dist/ui/stepper.js +152 -0
  141. package/dist/ui/switch.js +2 -2
  142. package/dist/ui/table.js +3 -3
  143. package/dist/ui/tabs.js +5 -5
  144. package/dist/ui/textarea.js +1 -1
  145. package/dist/ui/timeline.d.ts +29 -0
  146. package/dist/ui/timeline.js +157 -0
  147. package/dist/ui/toast.js +15 -12
  148. package/dist/ui/toggle-group.js +2 -2
  149. package/dist/ui/toggle.js +6 -4
  150. package/dist/ui/tooltip.js +2 -2
  151. package/docs/CONTRACT.md +183 -153
  152. package/docs/GRAFICOS.md +125 -0
  153. package/docs/adr/0001-rtl-clases-logicas.md +78 -0
  154. package/package.json +58 -29
  155. package/scripts/brand-core.mjs +153 -0
  156. package/scripts/doctor.mjs +128 -7
  157. package/scripts/i18n.mjs +111 -0
  158. package/scripts/init.mjs +327 -351
  159. package/scripts/setup.mjs +99 -0
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import { cva } from "class-variance-authority";
@@ -22,10 +23,11 @@ import {
22
23
  TooltipTrigger
23
24
  } from "./tooltip";
24
25
  import { PanelLeftIcon } from "lucide-react";
26
+ import { useDsMessages } from "../hooks/use-ds-messages";
25
27
  const SIDEBAR_COOKIE_NAME = "sidebar_state";
26
28
  const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
27
- const SIDEBAR_WIDTH = "17.5rem";
28
- const SIDEBAR_WIDTH_MOBILE = "18rem";
29
+ const SIDEBAR_WIDTH = "var(--ds-sidebar-w)";
30
+ const SIDEBAR_WIDTH_MOBILE = "var(--ds-sidebar-w-mobile)";
29
31
  const SIDEBAR_WIDTH_ICON = "var(--ds-sidebar-rail-w, 4rem)";
30
32
  const SIDEBAR_KEYBOARD_SHORTCUT = "b";
31
33
  const SidebarContext = React.createContext(null);
@@ -115,6 +117,7 @@ function Sidebar({
115
117
  ...props
116
118
  }) {
117
119
  const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
120
+ const t = useDsMessages();
118
121
  if (collapsible === "none") {
119
122
  return /* @__PURE__ */ jsx(
120
123
  "div",
@@ -130,9 +133,10 @@ function Sidebar({
130
133
  );
131
134
  }
132
135
  if (isMobile) {
133
- return /* @__PURE__ */ jsx(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ jsxs(
136
+ return /* @__PURE__ */ jsx(Sheet, { open: openMobile, onOpenChange: setOpenMobile, children: /* @__PURE__ */ jsxs(
134
137
  SheetContent,
135
138
  {
139
+ ...props,
136
140
  dir,
137
141
  "data-sidebar": "sidebar",
138
142
  "data-slot": "sidebar",
@@ -144,8 +148,8 @@ function Sidebar({
144
148
  side,
145
149
  children: [
146
150
  /* @__PURE__ */ jsxs(SheetHeader, { className: "sr-only", children: [
147
- /* @__PURE__ */ jsx(SheetTitle, { children: "Sidebar" }),
148
- /* @__PURE__ */ jsx(SheetDescription, { children: "Displays the mobile sidebar." })
151
+ /* @__PURE__ */ jsx(SheetTitle, { children: t.sidebarTitle }),
152
+ /* @__PURE__ */ jsx(SheetDescription, { children: t.sidebarDescription })
149
153
  ] }),
150
154
  /* @__PURE__ */ jsx("div", { className: "flex h-full w-full flex-col", children })
151
155
  ]
@@ -167,7 +171,7 @@ function Sidebar({
167
171
  {
168
172
  "data-slot": "sidebar-gap",
169
173
  className: cn(
170
- "relative w-(--sidebar-width) bg-transparent transition-[width] duration-(--ds-motion-base) ease-linear",
174
+ "relative w-(--sidebar-width) bg-transparent transition-[width] duration-(--ds-motion-base) ease-(--ds-ease-collapse)",
171
175
  "group-data-[collapsible=offcanvas]:w-0",
172
176
  "group-data-[side=right]:rotate-180",
173
177
  variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(var(--ds-sidebar-pad)*2))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
@@ -180,9 +184,9 @@ function Sidebar({
180
184
  "data-slot": "sidebar-container",
181
185
  "data-side": side,
182
186
  className: cn(
183
- "fixed inset-y-0 z-(--ds-z-sidebar) hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-(--ds-motion-base) ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex",
187
+ "fixed inset-y-0 z-(--ds-z-sidebar) hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-(--ds-motion-base) ease-(--ds-ease-collapse) data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex",
184
188
  // Adjust the padding for floating and inset variants.
185
- variant === "floating" || variant === "inset" ? "p-(--ds-sidebar-pad) group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(var(--ds-sidebar-pad)*2)+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
189
+ variant === "floating" || variant === "inset" ? "p-(--ds-sidebar-pad) group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(var(--ds-sidebar-pad)*2)+(var(--ds-sidebar-ring)*2))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r-(length:--ds-rule-w) group-data-[side=right]:border-l-(length:--ds-rule-w)",
186
190
  className
187
191
  ),
188
192
  ...props,
@@ -207,6 +211,7 @@ function SidebarTrigger({
207
211
  ...props
208
212
  }) {
209
213
  const { toggleSidebar } = useSidebar();
214
+ const t = useDsMessages();
210
215
  return /* @__PURE__ */ jsxs(
211
216
  Button,
212
217
  {
@@ -222,24 +227,25 @@ function SidebarTrigger({
222
227
  ...props,
223
228
  children: [
224
229
  /* @__PURE__ */ jsx(PanelLeftIcon, {}),
225
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Toggle Sidebar" })
230
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: t.sidebarToggle })
226
231
  ]
227
232
  }
228
233
  );
229
234
  }
230
235
  function SidebarRail({ className, ...props }) {
231
236
  const { toggleSidebar } = useSidebar();
237
+ const t = useDsMessages();
232
238
  return /* @__PURE__ */ jsx(
233
239
  "button",
234
240
  {
235
241
  "data-sidebar": "rail",
236
242
  "data-slot": "sidebar-rail",
237
- "aria-label": "Toggle Sidebar",
243
+ "aria-label": t.sidebarToggle,
238
244
  tabIndex: -1,
239
245
  onClick: toggleSidebar,
240
- title: "Toggle Sidebar",
246
+ title: t.sidebarToggle,
241
247
  className: cn(
242
- "absolute inset-y-0 z-(--ds-z-sticky) hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2",
248
+ "absolute inset-y-0 z-(--ds-z-sticky) hidden w-4 transition-all duration-(--ds-motion-snap) ease-(--ds-ease-collapse) group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-(--ds-sidebar-rail-handle-w) hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2",
243
249
  "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
244
250
  "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
245
251
  "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar",
@@ -257,7 +263,7 @@ function SidebarInset({ className, ...props }) {
257
263
  {
258
264
  "data-slot": "sidebar-inset",
259
265
  className: cn(
260
- "relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-raised md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
266
+ "relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-(--ds-sidebar-pad) md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-inset md:peer-data-[variant=inset]:shadow-raised md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-(--ds-sidebar-pad)",
261
267
  className
262
268
  ),
263
269
  ...props
@@ -273,7 +279,7 @@ function SidebarInput({
273
279
  {
274
280
  "data-slot": "sidebar-input",
275
281
  "data-sidebar": "input",
276
- className: cn("h-8 w-full bg-background shadow-none", className),
282
+ className: cn("h-(--ds-control-h-sm) w-full bg-background shadow-none", className),
277
283
  ...props
278
284
  }
279
285
  );
@@ -285,7 +291,7 @@ function SidebarHeader({ className, ...props }) {
285
291
  "data-slot": "sidebar-header",
286
292
  "data-sidebar": "header",
287
293
  className: cn(
288
- "flex flex-col gap-2 p-2 [--radius:var(--radius-xl)]",
294
+ "flex flex-col gap-2 p-2",
289
295
  className
290
296
  ),
291
297
  ...props
@@ -324,7 +330,7 @@ function SidebarContent({ className, ...props }) {
324
330
  "data-slot": "sidebar-content",
325
331
  "data-sidebar": "content",
326
332
  className: cn(
327
- "no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-auto [--radius:var(--radius-xl)] group-data-[collapsible=icon]:overflow-hidden",
333
+ "no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
328
334
  className
329
335
  ),
330
336
  ...props
@@ -352,8 +358,9 @@ function SidebarGroupLabel({
352
358
  props: mergeProps(
353
359
  {
354
360
  "data-sidebar": "group-label",
361
+ "data-slot": "sidebar-group-label",
355
362
  className: cn(
356
- "flex h-8 shrink-0 items-center rounded-md px-3 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-(--ds-motion-base) ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
363
+ "flex h-8 shrink-0 items-center rounded-md px-3 text-xs font-(--ds-nav-weight) text-(--ds-sidebar-label) ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-(--ds-motion-base) ease-(--ds-ease-collapse) group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-(length:--ds-ring-width) [&>svg]:size-4 [&>svg]:shrink-0",
357
364
  className
358
365
  )
359
366
  },
@@ -373,8 +380,9 @@ function SidebarGroupAction({
373
380
  props: mergeProps(
374
381
  {
375
382
  "data-sidebar": "group-action",
383
+ "data-slot": "sidebar-group-action",
376
384
  className: cn(
377
- "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
385
+ "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-(--ds-sidebar-item-radius) p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform duration-(--ds-motion-snap) group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-(length:--ds-ring-width) md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
378
386
  className
379
387
  )
380
388
  },
@@ -421,17 +429,17 @@ function SidebarMenuItem({ className, ...props }) {
421
429
  );
422
430
  }
423
431
  const sidebarMenuButtonVariants = cva(
424
- "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-(--ds-sidebar-item-radius) px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:mx-auto group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
432
+ "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-(--ds-sidebar-item-radius) px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] duration-(--ds-motion-snap) group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:mx-auto hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-(length:--ds-ring-width) active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-(--ds-disabled-opacity) aria-disabled:pointer-events-none aria-disabled:opacity-(--ds-disabled-opacity) data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:font-(--ds-nav-active-weight) data-[active=true]:text-sidebar-accent-foreground [&_svg]:shrink-0 [&>span:last-child]:truncate",
425
433
  {
426
434
  variants: {
427
435
  variant: {
428
436
  default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
429
- outline: "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]"
437
+ outline: "bg-background ring-(length:--ds-sidebar-ring) ring-sidebar-border hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:ring-sidebar-accent focus-visible:ring-sidebar-ring"
430
438
  },
431
439
  size: {
432
- default: "h-9 text-sm",
433
- sm: "h-8 text-xs",
434
- lg: "h-14 px-3 text-sm group-data-[collapsible=icon]:p-0!"
440
+ default: "h-(--ds-sidebar-item-h) text-sm",
441
+ sm: "h-(--ds-control-h-sm) text-xs",
442
+ lg: "h-(--ds-sidebar-item-h-lg) px-3 text-sm"
435
443
  }
436
444
  },
437
445
  defaultVariants: {
@@ -455,8 +463,10 @@ function SidebarMenuButton({
455
463
  props: mergeProps(
456
464
  {
457
465
  "data-sidebar": "menu-button",
466
+ "data-slot": "sidebar-menu-button",
467
+ "data-variant": variant,
458
468
  "data-size": size,
459
- "data-active": isActive,
469
+ "data-active": isActive || void 0,
460
470
  className: cn(sidebarMenuButtonVariants({ variant, size }), className)
461
471
  },
462
472
  props
@@ -496,8 +506,9 @@ function SidebarMenuAction({
496
506
  props: mergeProps(
497
507
  {
498
508
  "data-sidebar": "menu-action",
509
+ "data-slot": "sidebar-menu-action",
499
510
  className: cn(
500
- "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-2 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
511
+ "absolute top-1/2 right-1 flex aspect-square w-5 -translate-y-1/2 items-center justify-center rounded-(--ds-sidebar-item-radius) p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform duration-(--ds-motion-snap) group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-(length:--ds-ring-width) md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
501
512
  showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
502
513
  className
503
514
  )
@@ -518,7 +529,7 @@ function SidebarMenuBadge({
518
529
  "data-slot": "sidebar-menu-badge",
519
530
  "data-sidebar": "menu-badge",
520
531
  className: cn(
521
- "pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
532
+ "pointer-events-none absolute top-1/2 right-1 flex h-5 min-w-5 -translate-y-1/2 items-center justify-center rounded-(--ds-sidebar-item-radius) px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
522
533
  className
523
534
  ),
524
535
  ...props
@@ -541,7 +552,7 @@ function SidebarMenuSkeleton({
541
552
  {
542
553
  "data-slot": "sidebar-menu-skeleton",
543
554
  "data-sidebar": "menu-skeleton",
544
- className: cn("flex h-8 items-center gap-2 rounded-md px-2", className),
555
+ className: cn("flex h-(--ds-control-h-sm) items-center gap-2 rounded-(--ds-sidebar-item-radius) px-2", className),
545
556
  ...props,
546
557
  children: [
547
558
  showIcon && /* @__PURE__ */ jsx(
@@ -572,7 +583,7 @@ function SidebarMenuSub({ className, ...props }) {
572
583
  "data-slot": "sidebar-menu-sub",
573
584
  "data-sidebar": "menu-sub",
574
585
  className: cn(
575
- "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden",
586
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l-(length:--ds-rule-w) border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden",
576
587
  className
577
588
  ),
578
589
  ...props
@@ -605,10 +616,11 @@ function SidebarMenuSubButton({
605
616
  props: mergeProps(
606
617
  {
607
618
  "data-sidebar": "menu-sub-button",
619
+ "data-slot": "sidebar-menu-sub-button",
608
620
  "data-size": size,
609
- "data-active": isActive,
621
+ "data-active": isActive || void 0,
610
622
  className: cn(
611
- "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
623
+ "flex h-(--ds-sidebar-sub-item-h) min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-(--ds-sidebar-item-radius) px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-(length:--ds-ring-width) active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-(--ds-disabled-opacity) aria-disabled:pointer-events-none aria-disabled:opacity-(--ds-disabled-opacity) data-[size=md]:text-sm data-[size=sm]:text-xs data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
612
624
  className
613
625
  )
614
626
  },
@@ -5,7 +5,7 @@ function Skeleton({ className, ...props }) {
5
5
  "div",
6
6
  {
7
7
  "data-slot": "skeleton",
8
- className: cn("animate-pulse rounded-xl bg-muted", className),
8
+ className: cn("animate-pulse rounded-skeleton bg-muted", className),
9
9
  ...props
10
10
  }
11
11
  );
package/dist/ui/slider.js CHANGED
@@ -9,11 +9,11 @@ function Slider({
9
9
  max = 100,
10
10
  ...props
11
11
  }) {
12
- const _values = Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max];
12
+ const _values = Array.isArray(value) ? value : typeof value === "number" ? [value] : Array.isArray(defaultValue) ? defaultValue : typeof defaultValue === "number" ? [defaultValue] : [min, max];
13
13
  return /* @__PURE__ */ jsx(
14
14
  SliderPrimitive.Root,
15
15
  {
16
- className: cn("data-horizontal:w-full data-vertical:h-full", className),
16
+ className: cn("data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full", className),
17
17
  "data-slot": "slider",
18
18
  defaultValue,
19
19
  value,
@@ -21,17 +21,17 @@ function Slider({
21
21
  max,
22
22
  thumbAlignment: "edge",
23
23
  ...props,
24
- children: /* @__PURE__ */ jsxs(SliderPrimitive.Control, { className: "relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col", children: [
24
+ children: /* @__PURE__ */ jsxs(SliderPrimitive.Control, { "data-slot": "slider-control", className: "relative flex w-full touch-none items-center select-none data-disabled:opacity-(--ds-disabled-opacity) data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-40 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col", children: [
25
25
  /* @__PURE__ */ jsx(
26
26
  SliderPrimitive.Track,
27
27
  {
28
28
  "data-slot": "slider-track",
29
- className: "relative grow overflow-hidden rounded-control bg-muted select-none data-horizontal:h-3 data-horizontal:w-full data-vertical:h-full data-vertical:w-3",
29
+ className: "relative grow overflow-hidden rounded-track bg-muted select-none data-[orientation=horizontal]:h-(--ds-track-h) data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-(--ds-track-h)",
30
30
  children: /* @__PURE__ */ jsx(
31
31
  SliderPrimitive.Indicator,
32
32
  {
33
33
  "data-slot": "slider-range",
34
- className: "bg-primary select-none data-horizontal:h-full data-vertical:w-full"
34
+ className: "bg-primary select-none data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
35
35
  }
36
36
  )
37
37
  }
@@ -40,7 +40,7 @@ function Slider({
40
40
  SliderPrimitive.Thumb,
41
41
  {
42
42
  "data-slot": "slider-thumb",
43
- className: "block size-4 shrink-0 rounded-control border border-primary bg-primary-foreground shadow-raised ring-ring/50 transition-colors select-none hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
43
+ className: "block size-(--ds-slider-thumb) shrink-0 rounded-control border border-primary bg-primary-foreground shadow-raised ring-(--ds-ring-color) transition-colors duration-(--ds-motion-snap) select-none hover:ring-(length:--ds-ring-width) focus-visible:ring-(length:--ds-ring-width) focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-(--ds-disabled-opacity)"
44
44
  },
45
45
  index
46
46
  ))
package/dist/ui/sonner.js CHANGED
@@ -10,28 +10,45 @@ import {
10
10
  Loader2Icon
11
11
  } from "lucide-react";
12
12
  const Toaster = ({ ...props }) => {
13
- const { theme = "system" } = useTheme();
13
+ const { resolvedTheme = "system" } = useTheme();
14
14
  return /* @__PURE__ */ jsx(
15
15
  Sonner,
16
16
  {
17
- theme,
17
+ theme: resolvedTheme,
18
18
  className: "toaster group",
19
19
  icons: {
20
- success: /* @__PURE__ */ jsx(CircleCheckIcon, { className: "size-4" }),
21
- info: /* @__PURE__ */ jsx(InfoIcon, { className: "size-4" }),
22
- warning: /* @__PURE__ */ jsx(TriangleAlertIcon, { className: "size-4" }),
23
- error: /* @__PURE__ */ jsx(OctagonXIcon, { className: "size-4" }),
20
+ success: /* @__PURE__ */ jsx(CircleCheckIcon, { className: "size-4 text-success" }),
21
+ info: /* @__PURE__ */ jsx(InfoIcon, { className: "size-4 text-info" }),
22
+ warning: /* @__PURE__ */ jsx(TriangleAlertIcon, { className: "size-4 text-warning" }),
23
+ error: /* @__PURE__ */ jsx(OctagonXIcon, { className: "size-4 text-danger" }),
24
24
  loading: /* @__PURE__ */ jsx(Loader2Icon, { className: "size-4 animate-spin" })
25
25
  },
26
26
  style: {
27
27
  "--normal-bg": "var(--popover)",
28
28
  "--normal-text": "var(--popover-foreground)",
29
29
  "--normal-border": "var(--border)",
30
- "--border-radius": "var(--radius)"
30
+ "--border-radius": "var(--ds-radius-overlay)",
31
+ // Colores por tipo (con richColors): los tokens de estado del tema.
32
+ "--success-bg": "var(--success-soft)",
33
+ "--success-text": "var(--success)",
34
+ "--success-border": "var(--border)",
35
+ "--info-bg": "var(--info-soft)",
36
+ "--info-text": "var(--info)",
37
+ "--info-border": "var(--border)",
38
+ "--warning-bg": "var(--warning-soft)",
39
+ "--warning-text": "var(--warning)",
40
+ "--warning-border": "var(--border)",
41
+ "--error-bg": "var(--danger-soft)",
42
+ "--error-text": "var(--danger)",
43
+ "--error-border": "var(--border)"
31
44
  },
32
45
  toastOptions: {
33
46
  classNames: {
34
- toast: "cn-toast"
47
+ // Gancho para los temas: sonner no admite data-slot; cada toast lleva
48
+ // [data-sonner-toast] y [data-type], que es lo que apunta la personalidad.
49
+ toast: "cn-toast shadow-popover font-sans",
50
+ title: "font-(--ds-overlay-title-weight)",
51
+ description: "text-muted-foreground"
35
52
  }
36
53
  },
37
54
  ...props
@@ -0,0 +1,26 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+
4
+ type SparklineSeries = 1 | 2 | 3 | 4 | 5;
5
+ type SparklineTone = "info" | "success" | "warning" | "danger" | "neutral";
6
+ declare const sparklineVariants: (props?: ({
7
+ color?: "current" | "info" | "success" | "warning" | "danger" | "neutral" | "series-1" | "series-2" | "series-3" | "series-4" | "series-5" | null | undefined;
8
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
9
+ type SparklineProps = Omit<React.ComponentProps<"svg">, "children" | "color"> & {
10
+ /** Serie de valores; `null` = sin dato (hueco), nunca cero. */
11
+ data: ReadonlyArray<number | null | undefined>;
12
+ /** Color de serie del tema (--chart-1..5). */
13
+ series?: SparklineSeries;
14
+ /** Color de un estado. Si no hay `series` ni `tone`, usa el color del texto. */
15
+ tone?: SparklineTone;
16
+ /** Rellena el área bajo la línea con el mismo color, atenuado. */
17
+ area?: boolean;
18
+ /** Límites del eje vertical (por defecto, mínimo y máximo de los datos). */
19
+ min?: number;
20
+ max?: number;
21
+ /** Descripción accesible. Sin ella la línea es decorativa (aria-hidden). */
22
+ label?: string;
23
+ };
24
+ declare function Sparkline({ data, series, tone, area, min, max, label, className, ...props }: SparklineProps): React.JSX.Element;
25
+
26
+ export { Sparkline, type SparklineProps, type SparklineSeries, type SparklineTone, sparklineVariants };
@@ -0,0 +1,97 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cva } from "class-variance-authority";
3
+ import { cn } from "../lib/utils";
4
+ const sparklineVariants = cva(
5
+ "block h-(--ds-sparkline-h) w-full overflow-visible fill-none stroke-current stroke-(length:--ds-sparkline-w)",
6
+ {
7
+ variants: {
8
+ color: {
9
+ current: "",
10
+ "series-1": "text-chart-1",
11
+ "series-2": "text-chart-2",
12
+ "series-3": "text-chart-3",
13
+ "series-4": "text-chart-4",
14
+ "series-5": "text-chart-5",
15
+ info: "text-info",
16
+ success: "text-success",
17
+ warning: "text-warning",
18
+ danger: "text-danger",
19
+ neutral: "text-neutral"
20
+ }
21
+ },
22
+ defaultVariants: { color: "current" }
23
+ }
24
+ );
25
+ const VIEW_W = 100;
26
+ const VIEW_H = 100;
27
+ function segments(data, min, max) {
28
+ const out = [];
29
+ let current = [];
30
+ const span = max - min;
31
+ const step = data.length > 1 ? VIEW_W / (data.length - 1) : 0;
32
+ data.forEach((v, i) => {
33
+ if (v == null || !Number.isFinite(v)) {
34
+ if (current.length) out.push(current);
35
+ current = [];
36
+ return;
37
+ }
38
+ const x = data.length > 1 ? i * step : VIEW_W / 2;
39
+ const y = span === 0 ? VIEW_H / 2 : VIEW_H - (v - min) / span * VIEW_H;
40
+ current.push({ x, y });
41
+ });
42
+ if (current.length) out.push(current);
43
+ return out;
44
+ }
45
+ function linePath(seg) {
46
+ const [first, ...rest] = seg;
47
+ if (!rest.length) return `M${first.x} ${first.y}l0 0`;
48
+ return `M${first.x} ${first.y}` + rest.map((p) => `L${p.x} ${p.y}`).join("");
49
+ }
50
+ function areaPath(seg) {
51
+ if (seg.length < 2) return null;
52
+ const first = seg[0];
53
+ const last = seg[seg.length - 1];
54
+ return `${linePath(seg)}L${last.x} ${VIEW_H}L${first.x} ${VIEW_H}Z`;
55
+ }
56
+ function Sparkline({ data, series, tone, area = false, min, max, label, className, ...props }) {
57
+ const finite = data.filter((v) => v != null && Number.isFinite(v));
58
+ const lo = min ?? (finite.length ? Math.min(...finite) : 0);
59
+ const hi = max ?? (finite.length ? Math.max(...finite) : 0);
60
+ const segs = segments(data, lo, hi);
61
+ const color = series ? `series-${series}` : tone ?? "current";
62
+ return /* @__PURE__ */ jsxs(
63
+ "svg",
64
+ {
65
+ "data-slot": "sparkline",
66
+ "data-state": finite.length ? "filled" : "empty",
67
+ "data-tone": tone,
68
+ "data-series": series,
69
+ viewBox: `0 0 ${VIEW_W} ${VIEW_H}`,
70
+ preserveAspectRatio: "none",
71
+ ...label ? { role: "img", "aria-label": label } : { "aria-hidden": true, focusable: false },
72
+ className: cn(sparklineVariants({ color }), className),
73
+ ...props,
74
+ children: [
75
+ area && segs.map((seg, i) => {
76
+ const d = areaPath(seg);
77
+ return d ? /* @__PURE__ */ jsx("path", { "data-slot": "sparkline-area", d, className: "fill-current/15 stroke-none" }, `a${i}`) : null;
78
+ }),
79
+ segs.map((seg, i) => /* @__PURE__ */ jsx(
80
+ "path",
81
+ {
82
+ "data-slot": "sparkline-line",
83
+ d: linePath(seg),
84
+ vectorEffect: "non-scaling-stroke",
85
+ strokeLinecap: "round",
86
+ strokeLinejoin: "round"
87
+ },
88
+ `l${i}`
89
+ ))
90
+ ]
91
+ }
92
+ );
93
+ }
94
+ export {
95
+ Sparkline,
96
+ sparklineVariants
97
+ };
@@ -1,8 +1,11 @@
1
+ "use client";
1
2
  import { jsx } from "react/jsx-runtime";
2
3
  import { cn } from "../lib/utils";
3
4
  import { Loader2Icon } from "lucide-react";
5
+ import { useDsMessages } from "../hooks/use-ds-messages";
4
6
  function Spinner({ className, ...props }) {
5
- return /* @__PURE__ */ jsx(Loader2Icon, { "data-slot": "spinner", role: "status", "aria-label": "Loading", className: cn("size-4 animate-spin", className), ...props });
7
+ const t = useDsMessages();
8
+ return /* @__PURE__ */ jsx(Loader2Icon, { "data-slot": "spinner", role: "status", "aria-label": t.loading, className: cn("size-4 animate-spin [animation-duration:var(--ds-motion-spin)]", className), ...props });
6
9
  }
7
10
  export {
8
11
  Spinner
@@ -0,0 +1,61 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+
4
+ type StatVariant = "card" | "inline";
5
+ type StatSize = "sm" | "md" | "lg";
6
+ type StatTone = "neutral" | "good" | "warn" | "bad";
7
+ declare const statVariants: (props?: ({
8
+ variant?: "inline" | "card" | null | undefined;
9
+ tone?: "neutral" | "good" | "warn" | "bad" | null | undefined;
10
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
11
+ type StatProps = Omit<React.ComponentProps<"div">, "ref"> & {
12
+ variant?: StatVariant;
13
+ /** Tamaño fijo de la cifra; sin él, se adapta al ancho del contenedor. */
14
+ size?: StatSize;
15
+ tone?: StatTone;
16
+ };
17
+ declare function Stat({ className, variant, size, tone, children, ...props }: StatProps): React.JSX.Element;
18
+ declare function StatLabel({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
19
+ type StatValueProps = Omit<React.ComponentProps<"div">, "children"> & {
20
+ /** Número (se formatea con Intl en el idioma activo), texto ya formateado o null = sin dato. */
21
+ value: number | string | null | undefined;
22
+ /** Unidad o sufijo pegado a la cifra («min», «%», «llamadas»). */
23
+ unit?: React.ReactNode;
24
+ /** Texto antes de la cifra (p. ej. «≈»). */
25
+ prefix?: React.ReactNode;
26
+ /** Opciones de Intl.NumberFormat (moneda, compacto, porcentaje sobre 1…). */
27
+ format?: Intl.NumberFormatOptions;
28
+ /** Decimales fijos (atajo de minimum/maximumFractionDigits). */
29
+ fractionDigits?: number;
30
+ /** Motivo de que no haya dato; se muestra en un tooltip y se lee con «Sin dato». */
31
+ reason?: React.ReactNode;
32
+ /** Cargando: esqueleto en lugar de la cifra. */
33
+ loading?: boolean;
34
+ /** Signo que sustituye a la cifra cuando no hay dato. */
35
+ placeholder?: React.ReactNode;
36
+ };
37
+ declare function StatValue({ value, unit, prefix, format, fractionDigits, reason, loading, placeholder, className, ...props }: StatValueProps): React.JSX.Element;
38
+ type StatDeltaPolarity = "higher-is-better" | "lower-is-better" | "neutral";
39
+ type StatDeltaProps = Omit<React.ComponentProps<"div">, "children"> & {
40
+ /** Variación en PUNTOS PORCENTUALES (4.2 = +4,2 %). null = sin dato (nunca 0). */
41
+ value: number | null | undefined;
42
+ /** Qué dirección es buena: decide el tono (éxito, peligro o neutro). */
43
+ polarity?: StatDeltaPolarity;
44
+ fractionDigits?: number;
45
+ /** Texto propio en lugar de la cifra formateada (p. ej. «+12 llamadas»). */
46
+ children?: React.ReactNode;
47
+ };
48
+ declare function StatDelta({ value, polarity, fractionDigits, className, children, ...props }: StatDeltaProps): React.JSX.Element;
49
+ declare function StatDescription({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
50
+ /** Hueco para una Sparkline u otro gráfico mínimo bajo la cifra. */
51
+ declare function StatChart({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
52
+ type StatSwatchProps = React.ComponentProps<"span"> & {
53
+ /** Color de serie del tema (--chart-1..5). */
54
+ series?: 1 | 2 | 3 | 4 | 5;
55
+ /** O el color de un estado. */
56
+ tone?: "info" | "success" | "warning" | "danger" | "neutral";
57
+ };
58
+ /** Muestra de color que liga el KPI con su serie en un gráfico. Decorativa. */
59
+ declare function StatSwatch({ series, tone, className, ...props }: StatSwatchProps): React.JSX.Element;
60
+
61
+ export { Stat, StatChart, StatDelta, type StatDeltaPolarity, type StatDeltaProps, StatDescription, StatLabel, type StatProps, type StatSize, StatSwatch, type StatSwatchProps, type StatTone, StatValue, type StatValueProps, type StatVariant, statVariants };