orbital-ds 0.7.0 → 0.9.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 (109) hide show
  1. package/AGENTS.md +145 -80
  2. package/README.md +87 -73
  3. package/components.manifest.json +1326 -1267
  4. package/contract.json +226 -168
  5. package/dist/hooks/use-ds-messages.d.ts +36 -0
  6. package/dist/hooks/use-ds-messages.js +12 -0
  7. package/dist/hooks/use-ds-motion.d.ts +17 -0
  8. package/dist/hooks/use-ds-motion.js +50 -0
  9. package/dist/lib/i18n.d.ts +46 -0
  10. package/dist/lib/i18n.js +109 -0
  11. package/dist/lib/motion.d.ts +74 -0
  12. package/dist/lib/motion.js +97 -0
  13. package/dist/styles.css +876 -528
  14. package/dist/themes/friendly.css +362 -318
  15. package/dist/themes/friendly.meta.json +75 -14
  16. package/dist/themes/friendly.scoped.css +362 -318
  17. package/dist/themes/qratia.meta.json +42 -12
  18. package/dist/themes/tactile.css +575 -429
  19. package/dist/themes/tactile.fonts.css +3 -2
  20. package/dist/themes/tactile.guide.md +82 -49
  21. package/dist/themes/tactile.meta.json +175 -16
  22. package/dist/themes/tactile.scoped.css +575 -429
  23. package/dist/themes/twitter.css +354 -298
  24. package/dist/themes/twitter.meta.json +83 -61
  25. package/dist/themes/twitter.scoped.css +354 -298
  26. package/dist/themes/zyro.css +443 -389
  27. package/dist/themes/zyro.meta.json +67 -14
  28. package/dist/themes/zyro.scoped.css +443 -389
  29. package/dist/ui/accordion.js +5 -5
  30. package/dist/ui/alert-dialog.js +3 -3
  31. package/dist/ui/alert.d.ts +1 -1
  32. package/dist/ui/alert.js +9 -3
  33. package/dist/ui/attachment.d.ts +1 -1
  34. package/dist/ui/attachment.js +4 -4
  35. package/dist/ui/avatar.js +6 -6
  36. package/dist/ui/ayuda.js +3 -2
  37. package/dist/ui/badge.d.ts +1 -1
  38. package/dist/ui/badge.js +9 -3
  39. package/dist/ui/banner.d.ts +14 -0
  40. package/dist/ui/banner.js +88 -0
  41. package/dist/ui/breadcrumb.js +7 -3
  42. package/dist/ui/bubble.js +6 -6
  43. package/dist/ui/button-group.js +4 -4
  44. package/dist/ui/button.d.ts +1 -1
  45. package/dist/ui/button.js +5 -5
  46. package/dist/ui/calendar.js +33 -6
  47. package/dist/ui/card.js +4 -4
  48. package/dist/ui/carousel.js +15 -8
  49. package/dist/ui/chart.js +7 -3
  50. package/dist/ui/checkbox.js +1 -1
  51. package/dist/ui/combobox.js +7 -7
  52. package/dist/ui/command.js +13 -11
  53. package/dist/ui/context-menu.js +8 -8
  54. package/dist/ui/dialog.js +10 -6
  55. package/dist/ui/drawer.js +9 -9
  56. package/dist/ui/dropdown-menu.js +8 -8
  57. package/dist/ui/empty.js +3 -3
  58. package/dist/ui/field.js +2 -2
  59. package/dist/ui/hover-card.js +1 -1
  60. package/dist/ui/i18n-provider.d.ts +11 -0
  61. package/dist/ui/i18n-provider.js +18 -0
  62. package/dist/ui/icon-tile.d.ts +1 -1
  63. package/dist/ui/input-group.d.ts +1 -1
  64. package/dist/ui/input-group.js +11 -9
  65. package/dist/ui/input-otp.js +3 -3
  66. package/dist/ui/input.js +1 -1
  67. package/dist/ui/item.d.ts +1 -1
  68. package/dist/ui/item.js +3 -3
  69. package/dist/ui/kbd.js +1 -1
  70. package/dist/ui/label.js +1 -1
  71. package/dist/ui/marker.d.ts +1 -1
  72. package/dist/ui/marker.js +2 -2
  73. package/dist/ui/menubar.js +9 -9
  74. package/dist/ui/message-scroller.js +5 -2
  75. package/dist/ui/message.js +2 -2
  76. package/dist/ui/motion-provider.d.ts +11 -0
  77. package/dist/ui/motion-provider.js +16 -0
  78. package/dist/ui/native-select.js +4 -4
  79. package/dist/ui/navigation-menu.js +7 -6
  80. package/dist/ui/pagination.js +19 -11
  81. package/dist/ui/popover.js +2 -2
  82. package/dist/ui/progress.js +2 -2
  83. package/dist/ui/questionnaire.js +20 -15
  84. package/dist/ui/radio-group.js +2 -2
  85. package/dist/ui/resizable.js +2 -2
  86. package/dist/ui/scroll-area.js +3 -3
  87. package/dist/ui/select.js +6 -6
  88. package/dist/ui/separator.js +1 -1
  89. package/dist/ui/sheet.js +6 -4
  90. package/dist/ui/sidebar.js +42 -30
  91. package/dist/ui/skeleton.js +1 -1
  92. package/dist/ui/slider.js +6 -6
  93. package/dist/ui/sonner.js +25 -8
  94. package/dist/ui/spinner.js +4 -1
  95. package/dist/ui/switch.js +2 -2
  96. package/dist/ui/table.js +3 -3
  97. package/dist/ui/tabs.js +5 -5
  98. package/dist/ui/textarea.js +1 -1
  99. package/dist/ui/toast.js +15 -12
  100. package/dist/ui/toggle-group.js +2 -2
  101. package/dist/ui/toggle.js +6 -4
  102. package/dist/ui/tooltip.js +2 -2
  103. package/docs/CONTRACT.md +183 -153
  104. package/package.json +160 -142
  105. package/scripts/brand-core.mjs +153 -0
  106. package/scripts/doctor.mjs +128 -7
  107. package/scripts/i18n.mjs +111 -0
  108. package/scripts/init.mjs +294 -57
  109. 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
@@ -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
package/dist/ui/switch.js CHANGED
@@ -13,7 +13,7 @@ function Switch({
13
13
  "data-slot": "switch",
14
14
  "data-size": size,
15
15
  className: cn(
16
- "peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-(length:--ds-ring-width) aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
16
+ "peer group/switch relative inline-flex shrink-0 items-center rounded-(--ds-radius-pill) border border-transparent transition-all duration-(--ds-motion-snap) outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-(--ds-ring-color) aria-invalid:border-(--ds-invalid-border) aria-invalid:ring-(length:--ds-ring-width) aria-invalid:ring-(--ds-invalid-ring) data-[size=default]:h-(--ds-switch-h) data-[size=default]:w-(--ds-switch-w) data-[size=sm]:h-(--ds-switch-h-sm) data-[size=sm]:w-(--ds-switch-w-sm) data-checked:bg-primary data-unchecked:bg-(--ds-switch-track-off) data-disabled:cursor-not-allowed data-disabled:opacity-(--ds-disabled-opacity)",
17
17
  className
18
18
  ),
19
19
  ...props,
@@ -21,7 +21,7 @@ function Switch({
21
21
  SwitchPrimitive.Thumb,
22
22
  {
23
23
  "data-slot": "switch-thumb",
24
- className: "pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"
24
+ className: "pointer-events-none block rounded-(--ds-radius-pill) bg-(--ds-switch-thumb-bg) ring-0 transition-transform duration-(--ds-motion-snap) data-checked:bg-(--ds-switch-thumb-checked-bg) group-data-[size=default]/switch:size-(--ds-switch-thumb) group-data-[size=sm]/switch:size-(--ds-switch-thumb-sm) group-data-[size=default]/switch:data-checked:translate-x-[calc(var(--ds-switch-w)-var(--ds-switch-thumb)-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(var(--ds-switch-w-sm)-var(--ds-switch-thumb-sm)-2px)] group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0"
25
25
  }
26
26
  )
27
27
  }
package/dist/ui/table.js CHANGED
@@ -43,7 +43,7 @@ function TableFooter({ className, ...props }) {
43
43
  {
44
44
  "data-slot": "table-footer",
45
45
  className: cn(
46
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
46
+ "border-t bg-(--ds-row-hover) font-medium [&>tr]:last:border-b-0",
47
47
  className
48
48
  ),
49
49
  ...props
@@ -56,7 +56,7 @@ function TableRow({ className, ...props }) {
56
56
  {
57
57
  "data-slot": "table-row",
58
58
  className: cn(
59
- "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
59
+ "border-b transition-colors duration-(--ds-motion-snap) hover:bg-(--ds-row-hover) has-aria-expanded:bg-(--ds-row-hover) data-[state=selected]:bg-muted",
60
60
  className
61
61
  ),
62
62
  ...props
@@ -69,7 +69,7 @@ function TableHead({ className, ...props }) {
69
69
  {
70
70
  "data-slot": "table-head",
71
71
  className: cn(
72
- "h-12 px-(--ds-cell-p) text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
72
+ "h-(--ds-table-head-h) px-(--ds-cell-p) text-left align-middle font-(--ds-table-head-weight) whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
73
73
  className
74
74
  ),
75
75
  ...props
package/dist/ui/tabs.js CHANGED
@@ -22,12 +22,12 @@ function Tabs({
22
22
  );
23
23
  }
24
24
  const tabsListVariants = cva(
25
- "group/tabs-list inline-flex w-fit items-center justify-center rounded-control p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col group-data-[orientation=vertical]/tabs:rounded-2xl data-[variant=line]:rounded-none",
25
+ "group/tabs-list inline-flex w-fit items-center justify-center rounded-control p-(--ds-tabs-list-p) text-muted-foreground group-data-[orientation=horizontal]/tabs:h-(--ds-control-h-md) group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col group-data-[orientation=vertical]/tabs:rounded-2xl data-[variant=line]:rounded-none",
26
26
  {
27
27
  variants: {
28
28
  variant: {
29
29
  default: "bg-muted",
30
- line: "gap-1 bg-transparent"
30
+ line: "gap-(--ds-tabs-gap) bg-transparent"
31
31
  }
32
32
  },
33
33
  defaultVariants: {
@@ -56,10 +56,10 @@ function TabsTrigger({ className, ...props }) {
56
56
  {
57
57
  "data-slot": "tabs-trigger",
58
58
  className: cn(
59
- "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-xl border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start group-data-[orientation=vertical]/tabs:px-2.5 group-data-[orientation=vertical]/tabs:py-1.5 hover:text-foreground focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
59
+ "relative inline-flex h-full flex-1 items-center justify-center gap-1.5 rounded-tab border border-transparent px-2 py-1 text-sm font-(--ds-tab-weight) whitespace-nowrap text-(--ds-tab-foreground) transition-all duration-(--ds-motion-snap) group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start group-data-[orientation=vertical]/tabs:px-2.5 group-data-[orientation=vertical]/tabs:py-1.5 hover:text-foreground focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-(--ds-ring-color) focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-(--ds-disabled-opacity) has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
60
60
  "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
61
- "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
62
- "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
61
+ "data-active:bg-background data-active:font-(--ds-tab-active-weight) data-active:text-foreground dark:data-active:border-input dark:data-active:bg-(--ds-field-bg) dark:data-active:text-foreground",
62
+ "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity after:duration-(--ds-motion-snap) group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-(--ds-tab-line-offset) group-data-[orientation=horizontal]/tabs:after:h-(--ds-tab-line-w) group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-(--ds-tab-line-w) group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
63
63
  className
64
64
  ),
65
65
  ...props
@@ -6,7 +6,7 @@ function Textarea({ className, ...props }) {
6
6
  {
7
7
  "data-slot": "textarea",
8
8
  className: cn(
9
- "min-h-16 w-full min-w-0 rounded-md border border-input bg-input/30 px-(--ds-field-px) py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-(length:--ds-ring-width) aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
9
+ "min-h-16 w-full min-w-0 rounded-field-multiline border border-input bg-(--ds-field-bg) px-(--ds-field-px) py-2 text-base transition-colors duration-(--ds-motion-snap) outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-(--ds-ring-color) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-(--ds-disabled-opacity) aria-invalid:border-(--ds-invalid-border) aria-invalid:ring-(length:--ds-ring-width) aria-invalid:ring-(--ds-invalid-ring) md:text-sm",
10
10
  className
11
11
  ),
12
12
  ...props
package/dist/ui/toast.js CHANGED
@@ -4,6 +4,7 @@ import { Toast as ToastPrimitive } from "@base-ui/react/toast";
4
4
  import { cn } from "../lib/utils";
5
5
  import { Button } from "./button";
6
6
  import { XIcon, CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react";
7
+ import { useDsMessages } from "../hooks/use-ds-messages";
7
8
  const toast = ToastPrimitive.createToastManager();
8
9
  function ToastProvider({ ...props }) {
9
10
  return /* @__PURE__ */ jsx(ToastPrimitive.Provider, { ...props });
@@ -17,7 +18,7 @@ function ToastViewport({ className, ...props }) {
17
18
  {
18
19
  "data-slot": "toast-viewport",
19
20
  className: cn(
20
- "pointer-events-none fixed inset-x-4 bottom-4 z-(--ds-z-overlay) mx-auto w-auto max-w-sm outline-none sm:right-4 sm:left-auto sm:mx-0 sm:w-full",
21
+ "pointer-events-none fixed inset-x-(--ds-toast-offset) bottom-(--ds-toast-offset) z-(--ds-z-toast) mx-auto w-auto max-w-(--ds-toast-w) outline-none sm:right-(--ds-toast-offset) sm:left-auto sm:mx-0 sm:w-full",
21
22
  className
22
23
  ),
23
24
  ...props
@@ -29,10 +30,11 @@ function Toast({ className, ...props }) {
29
30
  ToastPrimitive.Root,
30
31
  {
31
32
  "data-slot": "toast",
33
+ "data-type": props.toast?.type,
32
34
  className: cn(
33
- "group/toast pointer-events-auto absolute right-0 bottom-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom rounded-2xl border bg-popover text-popover-foreground shadow-overlay will-change-transform outline-none select-none focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-ring/50",
34
- "[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]",
35
- "h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]",
35
+ "group/toast pointer-events-auto absolute right-0 bottom-0 z-[calc(var(--ds-z-stack)-var(--toast-index))] w-full origin-bottom rounded-popover border bg-popover text-popover-foreground shadow-overlay will-change-transform outline-none select-none focus-visible:border-ring focus-visible:ring-(length:--ds-ring-width) focus-visible:ring-(--ds-ring-color)",
36
+ "[--gap:var(--ds-toast-gap)] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:var(--ds-toast-peek)] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]",
37
+ "h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_var(--ds-motion-slower)_var(--ds-ease-standard),opacity_var(--ds-motion-slower),height_var(--ds-motion-snap)]",
36
38
  "after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']",
37
39
  "data-expanded:h-(--toast-height) data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]",
38
40
  "data-limited:opacity-0 data-starting-style:[transform:translateY(150%)]",
@@ -57,7 +59,7 @@ function ToastContent({ className, ...props }) {
57
59
  {
58
60
  "data-slot": "toast-content",
59
61
  className: cn(
60
- "flex h-full items-center gap-3 overflow-hidden p-4 transition-opacity duration-(--ds-motion-base) ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100",
62
+ "flex h-full items-center gap-3 overflow-hidden p-(--ds-popover-p) transition-opacity duration-(--ds-motion-base) ease-(--ds-ease-standard) data-behind:opacity-0 data-expanded:opacity-100",
61
63
  className
62
64
  ),
63
65
  ...props
@@ -69,7 +71,7 @@ function ToastTitle({ className, ...props }) {
69
71
  ToastPrimitive.Title,
70
72
  {
71
73
  "data-slot": "toast-title",
72
- className: cn("text-sm font-medium", className),
74
+ className: cn("text-sm font-(--ds-overlay-title-weight)", className),
73
75
  ...props
74
76
  }
75
77
  );
@@ -108,11 +110,12 @@ function ToastClose({
108
110
  render = /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm" }),
109
111
  ...props
110
112
  }) {
113
+ const t = useDsMessages();
111
114
  return /* @__PURE__ */ jsx(
112
115
  ToastPrimitive.Close,
113
116
  {
114
117
  "data-slot": "toast-close",
115
- "aria-label": "Close toast",
118
+ "aria-label": t.closeNotification,
116
119
  render,
117
120
  className: cn(
118
121
  "relative shrink-0 text-muted-foreground after:absolute after:-inset-2 after:content-[''] hover:text-foreground",
@@ -126,16 +129,16 @@ function ToastClose({
126
129
  function ToastIcon({ type }) {
127
130
  let icon = null;
128
131
  if (type === "success") {
129
- icon = /* @__PURE__ */ jsx(CircleCheckIcon, { "aria-hidden": "true" });
132
+ icon = /* @__PURE__ */ jsx(CircleCheckIcon, { className: "text-success", "aria-hidden": "true" });
130
133
  }
131
134
  if (type === "info") {
132
- icon = /* @__PURE__ */ jsx(InfoIcon, { "aria-hidden": "true" });
135
+ icon = /* @__PURE__ */ jsx(InfoIcon, { className: "text-info", "aria-hidden": "true" });
133
136
  }
134
137
  if (type === "warning") {
135
- icon = /* @__PURE__ */ jsx(TriangleAlertIcon, { "aria-hidden": "true" });
138
+ icon = /* @__PURE__ */ jsx(TriangleAlertIcon, { className: "text-warning", "aria-hidden": "true" });
136
139
  }
137
140
  if (type === "error") {
138
- icon = /* @__PURE__ */ jsx(OctagonXIcon, { className: "text-destructive", "aria-hidden": "true" });
141
+ icon = /* @__PURE__ */ jsx(OctagonXIcon, { className: "text-danger", "aria-hidden": "true" });
139
142
  }
140
143
  if (type === "loading") {
141
144
  icon = /* @__PURE__ */ jsx(Loader2Icon, { className: "animate-spin", "aria-hidden": "true" });
@@ -156,7 +159,7 @@ function ToastList() {
156
159
  const { toasts } = ToastPrimitive.useToastManager();
157
160
  return toasts.map((toastItem) => /* @__PURE__ */ jsx(Toast, { toast: toastItem, children: /* @__PURE__ */ jsxs(ToastContent, { children: [
158
161
  /* @__PURE__ */ jsx(ToastIcon, { type: toastItem.type }),
159
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
162
+ /* @__PURE__ */ jsxs("div", { "data-slot": "toast-text", className: "flex min-w-0 flex-1 flex-col gap-1", children: [
160
163
  /* @__PURE__ */ jsx(ToastTitle, {}),
161
164
  /* @__PURE__ */ jsx(ToastDescription, {})
162
165
  ] }),
@@ -29,7 +29,7 @@ function ToggleGroup({
29
29
  "data-orientation": orientation,
30
30
  style: { "--gap": spacing },
31
31
  className: cn(
32
- "group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-[spacing=0]:data-[variant=outline]:rounded-control data-vertical:flex-col data-vertical:items-stretch",
32
+ "group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-[spacing=0]:data-[variant=outline]:rounded-control data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch",
33
33
  className
34
34
  ),
35
35
  ...props,
@@ -59,7 +59,7 @@ function ToggleGroupItem({
59
59
  "data-size": context.size || size,
60
60
  "data-spacing": context.spacing,
61
61
  className: cn(
62
- "shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-3 group-data-[spacing=0]/toggle-group:shadow-none focus:z-(--ds-z-raised) focus-visible:z-(--ds-z-raised) group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-2.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-2.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-3xl group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-3xl group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-3xl group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-3xl data-[state=on]:bg-muted group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
62
+ "shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-3 group-data-[spacing=0]/toggle-group:shadow-none focus:z-(--ds-z-raised) focus-visible:z-(--ds-z-raised) group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-2.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-2.5 group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:first:rounded-l-control group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:first:rounded-t-control group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:last:rounded-r-control group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:last:rounded-b-control data-pressed:bg-muted group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-[orientation=horizontal]/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-[orientation=vertical]/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
63
63
  toggleVariants({
64
64
  variant: context.variant || variant,
65
65
  size: context.size || size