@craftzbay/ui 0.10.0 → 0.11.1

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 (187) hide show
  1. package/README.md +18 -12
  2. package/dist-lib/__tests__/helpers/color.d.ts +9 -0
  3. package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
  4. package/dist-lib/components/ui/Accordion.js +18 -7
  5. package/dist-lib/components/ui/Accordion.js.map +1 -1
  6. package/dist-lib/components/ui/Alert.d.ts +16 -0
  7. package/dist-lib/components/ui/Alert.js +47 -34
  8. package/dist-lib/components/ui/Alert.js.map +1 -1
  9. package/dist-lib/components/ui/Avatar.d.ts +1 -1
  10. package/dist-lib/components/ui/Avatar.js +45 -47
  11. package/dist-lib/components/ui/Avatar.js.map +1 -1
  12. package/dist-lib/components/ui/Badge.d.ts +3 -1
  13. package/dist-lib/components/ui/Badge.js +24 -15
  14. package/dist-lib/components/ui/Badge.js.map +1 -1
  15. package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
  16. package/dist-lib/components/ui/Breadcrumbs.js +46 -28
  17. package/dist-lib/components/ui/Breadcrumbs.js.map +1 -1
  18. package/dist-lib/components/ui/Button.d.ts +5 -3
  19. package/dist-lib/components/ui/Button.js +59 -45
  20. package/dist-lib/components/ui/Button.js.map +1 -1
  21. package/dist-lib/components/ui/Calendar.d.ts +1 -1
  22. package/dist-lib/components/ui/Calendar.js +87 -59
  23. package/dist-lib/components/ui/Calendar.js.map +1 -1
  24. package/dist-lib/components/ui/Card.d.ts +2 -0
  25. package/dist-lib/components/ui/Card.js +48 -67
  26. package/dist-lib/components/ui/Card.js.map +1 -1
  27. package/dist-lib/components/ui/Carousel.d.ts +6 -6
  28. package/dist-lib/components/ui/Carousel.js +133 -102
  29. package/dist-lib/components/ui/Carousel.js.map +1 -1
  30. package/dist-lib/components/ui/Chart.d.ts +49 -10
  31. package/dist-lib/components/ui/Chart.js +415 -181
  32. package/dist-lib/components/ui/Chart.js.map +1 -1
  33. package/dist-lib/components/ui/Checkbox.js +42 -28
  34. package/dist-lib/components/ui/Checkbox.js.map +1 -1
  35. package/dist-lib/components/ui/Combobox.d.ts +2 -0
  36. package/dist-lib/components/ui/Combobox.js +142 -111
  37. package/dist-lib/components/ui/Combobox.js.map +1 -1
  38. package/dist-lib/components/ui/CommandPalette.d.ts +6 -3
  39. package/dist-lib/components/ui/CommandPalette.js +92 -87
  40. package/dist-lib/components/ui/CommandPalette.js.map +1 -1
  41. package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
  42. package/dist-lib/components/ui/ContextMenu.js +77 -62
  43. package/dist-lib/components/ui/ContextMenu.js.map +1 -1
  44. package/dist-lib/components/ui/DataGrid.d.ts +17 -4
  45. package/dist-lib/components/ui/DataGrid.js +65 -50
  46. package/dist-lib/components/ui/DataGrid.js.map +1 -1
  47. package/dist-lib/components/ui/DatePicker.js +118 -99
  48. package/dist-lib/components/ui/DatePicker.js.map +1 -1
  49. package/dist-lib/components/ui/DesignSystemProvider.d.ts +94 -40
  50. package/dist-lib/components/ui/DesignSystemProvider.js +111 -55
  51. package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -1
  52. package/dist-lib/components/ui/Dialog.d.ts +18 -3
  53. package/dist-lib/components/ui/Dialog.js +105 -80
  54. package/dist-lib/components/ui/Dialog.js.map +1 -1
  55. package/dist-lib/components/ui/Drawer.d.ts +17 -2
  56. package/dist-lib/components/ui/Drawer.js +89 -55
  57. package/dist-lib/components/ui/Drawer.js.map +1 -1
  58. package/dist-lib/components/ui/DropdownMenu.js +14 -9
  59. package/dist-lib/components/ui/DropdownMenu.js.map +1 -1
  60. package/dist-lib/components/ui/EmptyState.d.ts +2 -0
  61. package/dist-lib/components/ui/EmptyState.js +30 -16
  62. package/dist-lib/components/ui/EmptyState.js.map +1 -1
  63. package/dist-lib/components/ui/ErrorState.d.ts +13 -2
  64. package/dist-lib/components/ui/ErrorState.js +44 -23
  65. package/dist-lib/components/ui/ErrorState.js.map +1 -1
  66. package/dist-lib/components/ui/FileUpload.js +59 -56
  67. package/dist-lib/components/ui/FileUpload.js.map +1 -1
  68. package/dist-lib/components/ui/Form.d.ts +15 -2
  69. package/dist-lib/components/ui/Form.js +97 -71
  70. package/dist-lib/components/ui/Form.js.map +1 -1
  71. package/dist-lib/components/ui/Icon.d.ts +1 -1
  72. package/dist-lib/components/ui/Icon.js +20 -14
  73. package/dist-lib/components/ui/Icon.js.map +1 -1
  74. package/dist-lib/components/ui/IconButton.d.ts +2 -2
  75. package/dist-lib/components/ui/IconButton.js +28 -20
  76. package/dist-lib/components/ui/IconButton.js.map +1 -1
  77. package/dist-lib/components/ui/Input.d.ts +3 -1
  78. package/dist-lib/components/ui/Input.js +102 -79
  79. package/dist-lib/components/ui/Input.js.map +1 -1
  80. package/dist-lib/components/ui/Kbd.js +1 -1
  81. package/dist-lib/components/ui/Kbd.js.map +1 -1
  82. package/dist-lib/components/ui/MultiSelect.js +121 -107
  83. package/dist-lib/components/ui/MultiSelect.js.map +1 -1
  84. package/dist-lib/components/ui/Pagination.js +67 -62
  85. package/dist-lib/components/ui/Pagination.js.map +1 -1
  86. package/dist-lib/components/ui/Popover.js +14 -14
  87. package/dist-lib/components/ui/Popover.js.map +1 -1
  88. package/dist-lib/components/ui/Progress.d.ts +3 -3
  89. package/dist-lib/components/ui/Progress.js +77 -72
  90. package/dist-lib/components/ui/Progress.js.map +1 -1
  91. package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
  92. package/dist-lib/components/ui/RadioGroup.js +69 -52
  93. package/dist-lib/components/ui/RadioGroup.js.map +1 -1
  94. package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
  95. package/dist-lib/components/ui/RelativeTime.js +31 -0
  96. package/dist-lib/components/ui/RelativeTime.js.map +1 -0
  97. package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
  98. package/dist-lib/components/ui/ScrollArea.js +43 -27
  99. package/dist-lib/components/ui/ScrollArea.js.map +1 -1
  100. package/dist-lib/components/ui/Select.d.ts +6 -1
  101. package/dist-lib/components/ui/Select.js +79 -71
  102. package/dist-lib/components/ui/Select.js.map +1 -1
  103. package/dist-lib/components/ui/Separator.js +1 -1
  104. package/dist-lib/components/ui/Separator.js.map +1 -1
  105. package/dist-lib/components/ui/Sheet.d.ts +9 -0
  106. package/dist-lib/components/ui/Sheet.js +69 -46
  107. package/dist-lib/components/ui/Sheet.js.map +1 -1
  108. package/dist-lib/components/ui/Sidebar.d.ts +12 -9
  109. package/dist-lib/components/ui/Sidebar.js +152 -109
  110. package/dist-lib/components/ui/Sidebar.js.map +1 -1
  111. package/dist-lib/components/ui/Skeleton.d.ts +13 -2
  112. package/dist-lib/components/ui/Skeleton.js +15 -14
  113. package/dist-lib/components/ui/Skeleton.js.map +1 -1
  114. package/dist-lib/components/ui/Slider.js +41 -29
  115. package/dist-lib/components/ui/Slider.js.map +1 -1
  116. package/dist-lib/components/ui/Snackbar.js +23 -22
  117. package/dist-lib/components/ui/Snackbar.js.map +1 -1
  118. package/dist-lib/components/ui/Spinner.js +18 -6
  119. package/dist-lib/components/ui/Spinner.js.map +1 -1
  120. package/dist-lib/components/ui/Stepper.d.ts +6 -0
  121. package/dist-lib/components/ui/Stepper.js +71 -48
  122. package/dist-lib/components/ui/Stepper.js.map +1 -1
  123. package/dist-lib/components/ui/Switch.js +46 -43
  124. package/dist-lib/components/ui/Switch.js.map +1 -1
  125. package/dist-lib/components/ui/Table.d.ts +33 -5
  126. package/dist-lib/components/ui/Table.js +141 -119
  127. package/dist-lib/components/ui/Table.js.map +1 -1
  128. package/dist-lib/components/ui/Tabs.js +50 -48
  129. package/dist-lib/components/ui/Tabs.js.map +1 -1
  130. package/dist-lib/components/ui/TagInput.js +45 -45
  131. package/dist-lib/components/ui/TagInput.js.map +1 -1
  132. package/dist-lib/components/ui/Textarea.js +65 -54
  133. package/dist-lib/components/ui/Textarea.js.map +1 -1
  134. package/dist-lib/components/ui/Timeline.js +39 -35
  135. package/dist-lib/components/ui/Timeline.js.map +1 -1
  136. package/dist-lib/components/ui/Toast.js +44 -57
  137. package/dist-lib/components/ui/Toast.js.map +1 -1
  138. package/dist-lib/components/ui/Tooltip.d.ts +4 -1
  139. package/dist-lib/components/ui/Tooltip.js +24 -22
  140. package/dist-lib/components/ui/Tooltip.js.map +1 -1
  141. package/dist-lib/components/ui/TopNav.d.ts +7 -3
  142. package/dist-lib/components/ui/TopNav.js +39 -22
  143. package/dist-lib/components/ui/TopNav.js.map +1 -1
  144. package/dist-lib/components/ui/Tree.d.ts +15 -10
  145. package/dist-lib/components/ui/Tree.js +82 -79
  146. package/dist-lib/components/ui/Tree.js.map +1 -1
  147. package/dist-lib/hooks/use-debounce.d.ts +19 -0
  148. package/dist-lib/hooks/use-debounce.js +36 -0
  149. package/dist-lib/hooks/use-debounce.js.map +1 -0
  150. package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
  151. package/dist-lib/hooks/use-delayed-loading.js +20 -0
  152. package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
  153. package/dist-lib/hooks/use-field-ids.d.ts +2 -1
  154. package/dist-lib/hooks/use-field-ids.js +9 -9
  155. package/dist-lib/hooks/use-field-ids.js.map +1 -1
  156. package/dist-lib/hooks/use-media-query.d.ts +3 -1
  157. package/dist-lib/hooks/use-media-query.js +16 -12
  158. package/dist-lib/hooks/use-media-query.js.map +1 -1
  159. package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
  160. package/dist-lib/hooks/use-modifier-key.js +19 -0
  161. package/dist-lib/hooks/use-modifier-key.js.map +1 -0
  162. package/dist-lib/hooks/use-toast.d.ts +7 -2
  163. package/dist-lib/hooks/use-toast.js +61 -30
  164. package/dist-lib/hooks/use-toast.js.map +1 -1
  165. package/dist-lib/icons/index.d.ts +9 -0
  166. package/dist-lib/icons/index.js +148 -130
  167. package/dist-lib/icons/index.js.map +1 -1
  168. package/dist-lib/illustrations/index.d.ts +1 -0
  169. package/dist-lib/illustrations/index.js +15 -6
  170. package/dist-lib/illustrations/index.js.map +1 -1
  171. package/dist-lib/index.d.ts +6 -0
  172. package/dist-lib/index.js +280 -260
  173. package/dist-lib/index.js.map +1 -1
  174. package/dist-lib/lib/format.d.ts +65 -0
  175. package/dist-lib/lib/format.js +95 -0
  176. package/dist-lib/lib/format.js.map +1 -0
  177. package/dist-lib/lib/return-focus.d.ts +11 -0
  178. package/dist-lib/lib/return-focus.js +12 -0
  179. package/dist-lib/lib/return-focus.js.map +1 -0
  180. package/dist-lib/lib/strings.d.ts +62 -1
  181. package/dist-lib/lib/strings.js +75 -19
  182. package/dist-lib/lib/strings.js.map +1 -1
  183. package/dist-lib/lib/strings.mn.js +50 -5
  184. package/dist-lib/lib/strings.mn.js.map +1 -1
  185. package/dist-lib/styles.css +1 -1
  186. package/dist-lib/theme.css +141 -78
  187. package/package.json +11 -4
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { jsxs as i, jsx as u } from "react/jsx-runtime";
3
- import { forwardRef as l } from "react";
4
- import { cn as e } from "../../lib/utils.js";
5
- import { cva as d } from "class-variance-authority";
6
- const g = d(
2
+ import { jsxs as u, jsx as n } from "react/jsx-runtime";
3
+ import { forwardRef as d } from "react";
4
+ import { cn as a } from "../../lib/utils.js";
5
+ import { cva as g } from "class-variance-authority";
6
+ const b = g(
7
7
  [
8
8
  "inline-flex items-center gap-1 rounded-full px-2 py-0.5",
9
9
  "text-xs font-medium whitespace-nowrap"
@@ -34,34 +34,43 @@ const g = d(
34
34
  // Outline — coloured border + text, transparent fill.
35
35
  { variant: "outline", tone: "neutral", class: "border-border text-foreground-muted" },
36
36
  { variant: "outline", tone: "accent", class: "border-accent text-accent" },
37
- { variant: "outline", tone: "success", class: "border-success-border-soft text-success-text" },
38
- { variant: "outline", tone: "warning", class: "border-warning-border-soft text-warning-text" },
37
+ {
38
+ variant: "outline",
39
+ tone: "success",
40
+ class: "border-success-border-soft text-success-text"
41
+ },
42
+ {
43
+ variant: "outline",
44
+ tone: "warning",
45
+ class: "border-warning-border-soft text-warning-text"
46
+ },
39
47
  { variant: "outline", tone: "danger", class: "border-danger-border-soft text-danger-text" },
40
48
  { variant: "outline", tone: "info", class: "border-info-border-soft text-info-text" }
41
49
  ],
42
50
  defaultVariants: { variant: "subtle", tone: "neutral" }
43
51
  }
44
- ), b = {
52
+ ), f = {
45
53
  neutral: "bg-foreground-subtle",
46
54
  accent: "bg-accent",
47
55
  success: "bg-success",
48
56
  warning: "bg-warning",
49
57
  danger: "bg-danger",
50
58
  info: "bg-info"
51
- }, f = l(function({ className: n, variant: a, tone: t = "neutral", dot: r, children: s, ...o }, c) {
52
- return /* @__PURE__ */ i("span", { ref: c, className: e(g({ variant: a, tone: t }), n), ...o, children: [
53
- r && /* @__PURE__ */ u(
59
+ }, x = d(function({ className: r, variant: s, tone: t = "neutral", dot: o, icon: e, children: i, ...c }, l) {
60
+ return /* @__PURE__ */ u("span", { ref: l, className: a(b({ variant: s, tone: t }), r), ...c, children: [
61
+ e && /* @__PURE__ */ n("span", { "aria-hidden": !0, className: "inline-flex shrink-0 [&_svg]:size-3", children: e }),
62
+ o && !e && /* @__PURE__ */ n(
54
63
  "span",
55
64
  {
56
65
  "aria-hidden": !0,
57
- className: e("inline-block size-1.5 rounded-full", b[t ?? "neutral"])
66
+ className: a("inline-block size-1.5 rounded-full", f[t ?? "neutral"])
58
67
  }
59
68
  ),
60
- s
69
+ i
61
70
  ] });
62
71
  });
63
- f.displayName = "Badge";
72
+ x.displayName = "Badge";
64
73
  export {
65
- f as Badge
74
+ x as Badge
66
75
  };
67
76
  //# sourceMappingURL=Badge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.js","sources":["../../../src/components/ui/Badge.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes } from 'react';\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from '@/lib/cva';\n\nconst badge = cva(\n [\n 'inline-flex items-center gap-1 rounded-full px-2 py-0.5',\n 'text-xs font-medium whitespace-nowrap',\n ],\n {\n variants: {\n variant: {\n subtle: '',\n outline: 'border bg-transparent',\n },\n tone: {\n neutral: '',\n accent: '',\n success: '',\n warning: '',\n danger: '',\n info: '',\n },\n },\n compoundVariants: [\n // Subtle — coloured fill + matching text.\n { variant: 'subtle', tone: 'neutral', class: 'bg-background-muted text-foreground-muted' },\n { variant: 'subtle', tone: 'accent', class: 'bg-accent-soft text-on-accent-soft' },\n { variant: 'subtle', tone: 'success', class: 'bg-success-soft text-success-text' },\n { variant: 'subtle', tone: 'warning', class: 'bg-warning-soft text-warning-text' },\n { variant: 'subtle', tone: 'danger', class: 'bg-danger-soft text-danger-text' },\n { variant: 'subtle', tone: 'info', class: 'bg-info-soft text-info-text' },\n // Outline — coloured border + text, transparent fill.\n { variant: 'outline', tone: 'neutral', class: 'border-border text-foreground-muted' },\n { variant: 'outline', tone: 'accent', class: 'border-accent text-accent' },\n { variant: 'outline', tone: 'success', class: 'border-success-border-soft text-success-text' },\n { variant: 'outline', tone: 'warning', class: 'border-warning-border-soft text-warning-text' },\n { variant: 'outline', tone: 'danger', class: 'border-danger-border-soft text-danger-text' },\n { variant: 'outline', tone: 'info', class: 'border-info-border-soft text-info-text' },\n ],\n defaultVariants: { variant: 'subtle', tone: 'neutral' },\n },\n);\n\nexport interface BadgeProps\n extends HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof badge> {\n /** Show a leading status dot in the same tone. */\n dot?: boolean;\n}\n\nconst dotColour = {\n neutral: 'bg-foreground-subtle',\n accent: 'bg-accent',\n success: 'bg-success',\n warning: 'bg-warning',\n danger: 'bg-danger',\n info: 'bg-info',\n} as const;\n\n/**\n * Status pill. Use `subtle` for high-volume contexts (table cells, lists);\n * `outline` when the badge sits on a busy or coloured background.\n *\n * @example\n * <Badge tone=\"success\" dot>Active</Badge>\n * <Badge tone=\"danger\" variant=\"outline\">Failed</Badge>\n *\n * @do Use badges to summarise state, not to label categories — for taxonomies\n * pick a tone palette and stick with it.\n * @dont Use a badge as a button. Wrap it in a Button or use a Toggle.\n */\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n { className, variant, tone = 'neutral', dot, children, ...props },\n ref,\n) {\n return (\n <span ref={ref} className={cn(badge({ variant, tone }), className)} {...props}>\n {dot && (\n <span\n aria-hidden\n className={cn('inline-block size-1.5 rounded-full', dotColour[tone ?? 'neutral'])}\n />\n )}\n {children}\n </span>\n );\n});\nBadge.displayName = 'Badge';\n"],"names":["badge","cva","dotColour","Badge","forwardRef","className","variant","tone","dot","children","props","ref","jsxs","cn","jsx"],"mappings":";;;;;AAMA,MAAMA,IAAQC;AAAA,EACZ;AAAA,IACE;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,MAAA;AAAA,MAEX,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,kBAAkB;AAAA;AAAA,MAEhB,EAAE,SAAS,UAAU,MAAM,WAAW,OAAO,4CAAA;AAAA,MAC7C,EAAE,SAAS,UAAU,MAAM,UAAU,OAAO,qCAAA;AAAA,MAC5C,EAAE,SAAS,UAAU,MAAM,WAAW,OAAO,oCAAA;AAAA,MAC7C,EAAE,SAAS,UAAU,MAAM,WAAW,OAAO,oCAAA;AAAA,MAC7C,EAAE,SAAS,UAAU,MAAM,UAAU,OAAO,kCAAA;AAAA,MAC5C,EAAE,SAAS,UAAU,MAAM,QAAQ,OAAO,8BAAA;AAAA;AAAA,MAE1C,EAAE,SAAS,WAAW,MAAM,WAAW,OAAO,sCAAA;AAAA,MAC9C,EAAE,SAAS,WAAW,MAAM,UAAU,OAAO,4BAAA;AAAA,MAC7C,EAAE,SAAS,WAAW,MAAM,WAAW,OAAO,+CAAA;AAAA,MAC9C,EAAE,SAAS,WAAW,MAAM,WAAW,OAAO,+CAAA;AAAA,MAC9C,EAAE,SAAS,WAAW,MAAM,UAAU,OAAO,6CAAA;AAAA,MAC7C,EAAE,SAAS,WAAW,MAAM,QAAQ,OAAO,yCAAA;AAAA,IAAyC;AAAA,IAEtF,iBAAiB,EAAE,SAAS,UAAU,MAAM,UAAA;AAAA,EAAU;AAE1D,GASMC,IAAY;AAAA,EAChB,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AACR,GAcaC,IAAQC,EAAwC,SAC3D,EAAE,WAAAC,GAAW,SAAAC,GAAS,MAAAC,IAAO,WAAW,KAAAC,GAAK,UAAAC,GAAU,GAAGC,EAAA,GAC1DC,GACA;AACA,SACE,gBAAAC,EAAC,QAAA,EAAK,KAAAD,GAAU,WAAWE,EAAGb,EAAM,EAAE,SAAAM,GAAS,MAAAC,EAAA,CAAM,GAAGF,CAAS,GAAI,GAAGK,GACrE,UAAA;AAAA,IAAAF,KACC,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAW;AAAA,QACX,WAAWD,EAAG,sCAAsCX,EAAUK,KAAQ,SAAS,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,IAGnFE;AAAA,EAAA,GACH;AAEJ,CAAC;AACDN,EAAM,cAAc;"}
1
+ {"version":3,"file":"Badge.js","sources":["../../../src/components/ui/Badge.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from '@/lib/cva';\n\nconst badge = cva(\n [\n 'inline-flex items-center gap-1 rounded-full px-2 py-0.5',\n 'text-xs font-medium whitespace-nowrap',\n ],\n {\n variants: {\n variant: {\n subtle: '',\n outline: 'border bg-transparent',\n },\n tone: {\n neutral: '',\n accent: '',\n success: '',\n warning: '',\n danger: '',\n info: '',\n },\n },\n compoundVariants: [\n // Subtle — coloured fill + matching text.\n { variant: 'subtle', tone: 'neutral', class: 'bg-background-muted text-foreground-muted' },\n { variant: 'subtle', tone: 'accent', class: 'bg-accent-soft text-on-accent-soft' },\n { variant: 'subtle', tone: 'success', class: 'bg-success-soft text-success-text' },\n { variant: 'subtle', tone: 'warning', class: 'bg-warning-soft text-warning-text' },\n { variant: 'subtle', tone: 'danger', class: 'bg-danger-soft text-danger-text' },\n { variant: 'subtle', tone: 'info', class: 'bg-info-soft text-info-text' },\n // Outline — coloured border + text, transparent fill.\n { variant: 'outline', tone: 'neutral', class: 'border-border text-foreground-muted' },\n { variant: 'outline', tone: 'accent', class: 'border-accent text-accent' },\n {\n variant: 'outline',\n tone: 'success',\n class: 'border-success-border-soft text-success-text',\n },\n {\n variant: 'outline',\n tone: 'warning',\n class: 'border-warning-border-soft text-warning-text',\n },\n { variant: 'outline', tone: 'danger', class: 'border-danger-border-soft text-danger-text' },\n { variant: 'outline', tone: 'info', class: 'border-info-border-soft text-info-text' },\n ],\n defaultVariants: { variant: 'subtle', tone: 'neutral' },\n },\n);\n\nexport interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badge> {\n /** Show a leading status dot in the same tone. */\n dot?: boolean;\n /** Leading icon (decorative — sized 12px, `aria-hidden`). Overrides `dot`. */\n icon?: ReactNode;\n}\n\nconst dotColour = {\n neutral: 'bg-foreground-subtle',\n accent: 'bg-accent',\n success: 'bg-success',\n warning: 'bg-warning',\n danger: 'bg-danger',\n info: 'bg-info',\n} as const;\n\n/**\n * Status pill. Use `subtle` for high-volume contexts (table cells, lists);\n * `outline` when the badge sits on a busy or coloured background.\n *\n * @example\n * <Badge tone=\"success\" dot>Active</Badge>\n * <Badge tone=\"danger\" variant=\"outline\">Failed</Badge>\n *\n * @do Use badges to summarise state, not to label categories — for taxonomies\n * pick a tone palette and stick with it.\n * @dont Use a badge as a button. Wrap it in a Button or use a Toggle.\n */\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n { className, variant, tone = 'neutral', dot, icon, children, ...props },\n ref,\n) {\n return (\n <span ref={ref} className={cn(badge({ variant, tone }), className)} {...props}>\n {icon && (\n <span aria-hidden className=\"inline-flex shrink-0 [&_svg]:size-3\">\n {icon}\n </span>\n )}\n {dot && !icon && (\n <span\n aria-hidden\n className={cn('inline-block size-1.5 rounded-full', dotColour[tone ?? 'neutral'])}\n />\n )}\n {children}\n </span>\n );\n});\nBadge.displayName = 'Badge';\n"],"names":["badge","cva","dotColour","Badge","forwardRef","className","variant","tone","dot","icon","children","props","ref","jsxs","cn","jsx"],"mappings":";;;;;AAMA,MAAMA,IAAQC;AAAA,EACZ;AAAA,IACE;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,MAAA;AAAA,MAEX,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,kBAAkB;AAAA;AAAA,MAEhB,EAAE,SAAS,UAAU,MAAM,WAAW,OAAO,4CAAA;AAAA,MAC7C,EAAE,SAAS,UAAU,MAAM,UAAU,OAAO,qCAAA;AAAA,MAC5C,EAAE,SAAS,UAAU,MAAM,WAAW,OAAO,oCAAA;AAAA,MAC7C,EAAE,SAAS,UAAU,MAAM,WAAW,OAAO,oCAAA;AAAA,MAC7C,EAAE,SAAS,UAAU,MAAM,UAAU,OAAO,kCAAA;AAAA,MAC5C,EAAE,SAAS,UAAU,MAAM,QAAQ,OAAO,8BAAA;AAAA;AAAA,MAE1C,EAAE,SAAS,WAAW,MAAM,WAAW,OAAO,sCAAA;AAAA,MAC9C,EAAE,SAAS,WAAW,MAAM,UAAU,OAAO,4BAAA;AAAA,MAC7C;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,MAET;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,MAET,EAAE,SAAS,WAAW,MAAM,UAAU,OAAO,6CAAA;AAAA,MAC7C,EAAE,SAAS,WAAW,MAAM,QAAQ,OAAO,yCAAA;AAAA,IAAyC;AAAA,IAEtF,iBAAiB,EAAE,SAAS,UAAU,MAAM,UAAA;AAAA,EAAU;AAE1D,GASMC,IAAY;AAAA,EAChB,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AACR,GAcaC,IAAQC,EAAwC,SAC3D,EAAE,WAAAC,GAAW,SAAAC,GAAS,MAAAC,IAAO,WAAW,KAAAC,GAAK,MAAAC,GAAM,UAAAC,GAAU,GAAGC,EAAA,GAChEC,GACA;AACA,SACE,gBAAAC,EAAC,QAAA,EAAK,KAAAD,GAAU,WAAWE,EAAGd,EAAM,EAAE,SAAAM,GAAS,MAAAC,EAAA,CAAM,GAAGF,CAAS,GAAI,GAAGM,GACrE,UAAA;AAAA,IAAAF,uBACE,QAAA,EAAK,eAAW,IAAC,WAAU,uCACzB,UAAAA,GACH;AAAA,IAEDD,KAAO,CAACC,KACP,gBAAAM;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAW;AAAA,QACX,WAAWD,EAAG,sCAAsCZ,EAAUK,KAAQ,SAAS,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,IAGnFG;AAAA,EAAA,GACH;AAEJ,CAAC;AACDP,EAAM,cAAc;"}
@@ -11,6 +11,8 @@ export interface BreadcrumbsProps extends HTMLAttributes<HTMLElement> {
11
11
  maxItems?: number;
12
12
  /** Custom link renderer (for next/link, react-router, etc.). */
13
13
  renderLink?: (href: string, children: ReactNode) => ReactNode;
14
+ /** sr-only text for the collapsed ellipsis. Default "Hidden items". */
15
+ collapsedLabel?: string;
14
16
  }
15
17
  /**
16
18
  * Breadcrumb trail. Collapses with an ellipsis when there are too many crumbs.
@@ -1,34 +1,52 @@
1
1
  "use client";
2
2
  import { jsx as e, jsxs as c } from "react/jsx-runtime";
3
- import { forwardRef as b } from "react";
4
- import { MoreHorizontal as g, ChevronRight as d } from "../../icons/index.js";
5
- import { cn as x } from "../../lib/utils.js";
6
- import { useStrings as N } from "../../hooks/use-strings.js";
7
- const v = b(function({ items: s, maxItems: m = 4, renderLink: l, className: u, ...i }, f) {
8
- const h = N(), n = s.length > m ? [s[0], { collapsed: !0 }, ...s.slice(-2)] : s;
9
- return /* @__PURE__ */ e("nav", { ref: f, "aria-label": i["aria-label"] ?? h.breadcrumbs.label, className: x("text-sm", u), ...i, children: /* @__PURE__ */ e("ol", { className: "flex flex-wrap items-center gap-1.5 text-foreground-subtle", children: n.map((o, a) => {
10
- const t = a === n.length - 1;
11
- if ("collapsed" in o)
12
- return /* @__PURE__ */ c("li", { className: "flex items-center gap-1.5", children: [
13
- /* @__PURE__ */ e(g, { className: "size-4", "aria-hidden": !0 }),
14
- /* @__PURE__ */ e(d, { className: "size-3.5", "aria-hidden": !0 })
15
- ] }, `ellipsis-${a}`);
16
- const r = o, p = t ? /* @__PURE__ */ e("span", { "aria-current": "page", className: "font-medium text-foreground", children: r.label }) : r.href ? l ? l(r.href, r.label) : /* @__PURE__ */ e(
17
- "a",
18
- {
19
- href: r.href,
20
- className: "hover:text-foreground transition-colors duration-[var(--duration-fast)] outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm",
21
- children: r.label
22
- }
23
- ) : /* @__PURE__ */ e("span", { children: r.label });
24
- return /* @__PURE__ */ c("li", { className: "flex items-center gap-1.5", children: [
25
- p,
26
- !t && /* @__PURE__ */ e(d, { className: "size-3.5", "aria-hidden": !0 })
27
- ] }, a);
28
- }) }) });
3
+ import { forwardRef as x } from "react";
4
+ import { MoreHorizontal as v, ChevronRight as d } from "../../icons/index.js";
5
+ import { cn as z } from "../../lib/utils.js";
6
+ import { useStrings as y } from "../../hooks/use-strings.js";
7
+ const B = x(function({
8
+ items: s,
9
+ maxItems: m = 4,
10
+ renderLink: l,
11
+ collapsedLabel: u,
12
+ className: f,
13
+ "aria-label": p,
14
+ ...h
15
+ }, b) {
16
+ const o = y(), g = u ?? o.breadcrumbs.collapsed, n = s.length > m ? [s[0], { collapsed: !0 }, ...s.slice(-2)] : s;
17
+ return /* @__PURE__ */ e(
18
+ "nav",
19
+ {
20
+ ref: b,
21
+ "aria-label": p ?? o.breadcrumbs.label,
22
+ className: z("text-sm", f),
23
+ ...h,
24
+ children: /* @__PURE__ */ e("ol", { className: "text-foreground-subtle flex flex-wrap items-center gap-1.5", children: n.map((i, a) => {
25
+ const t = a === n.length - 1;
26
+ if ("collapsed" in i)
27
+ return /* @__PURE__ */ c("li", { className: "flex items-center gap-1.5", children: [
28
+ /* @__PURE__ */ e(v, { className: "size-4", "aria-hidden": !0 }),
29
+ /* @__PURE__ */ e("span", { className: "sr-only", children: g }),
30
+ /* @__PURE__ */ e(d, { className: "size-3.5", "aria-hidden": !0 })
31
+ ] }, `ellipsis-${a}`);
32
+ const r = i, N = t ? /* @__PURE__ */ e("span", { "aria-current": "page", className: "text-foreground font-medium", children: r.label }) : r.href ? l ? l(r.href, r.label) : /* @__PURE__ */ e(
33
+ "a",
34
+ {
35
+ href: r.href,
36
+ className: "hover:text-foreground focus-visible:ring-ring rounded-sm transition-colors duration-[var(--duration-fast)] outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
37
+ children: r.label
38
+ }
39
+ ) : /* @__PURE__ */ e("span", { children: r.label });
40
+ return /* @__PURE__ */ c("li", { className: "flex items-center gap-1.5", children: [
41
+ N,
42
+ !t && /* @__PURE__ */ e(d, { className: "size-3.5", "aria-hidden": !0 })
43
+ ] }, a);
44
+ }) })
45
+ }
46
+ );
29
47
  });
30
- v.displayName = "Breadcrumbs";
48
+ B.displayName = "Breadcrumbs";
31
49
  export {
32
- v as Breadcrumbs
50
+ B as Breadcrumbs
33
51
  };
34
52
  //# sourceMappingURL=Breadcrumbs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Breadcrumbs.js","sources":["../../../src/components/ui/Breadcrumbs.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { ChevronRight, MoreHorizontal } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\n\nexport interface BreadcrumbItem {\n /** Visible label. */\n label: ReactNode;\n /** Optional URL. Last item is treated as current page even if href is set. */\n href?: string;\n}\n\nexport interface BreadcrumbsProps extends HTMLAttributes<HTMLElement> {\n items: BreadcrumbItem[];\n /** Collapse to first + ellipsis + last `n` when items.length exceeds this. */\n maxItems?: number;\n /** Custom link renderer (for next/link, react-router, etc.). */\n renderLink?: (href: string, children: ReactNode) => ReactNode;\n}\n\n/**\n * Breadcrumb trail. Collapses with an ellipsis when there are too many crumbs.\n *\n * @example\n * <Breadcrumbs items={[\n * { label: 'Projects', href: '/projects' },\n * { label: 'Nova', href: '/projects/nova' },\n * { label: 'Settings' },\n * ]} />\n *\n * @example With react-router\n * <Breadcrumbs items={trail} renderLink={(href, c) => <Link to={href}>{c}</Link>} />\n *\n * @do Always omit `href` on the last item — it represents the current page.\n * @dont Use Breadcrumbs for flat navigation. Use TopNav links instead.\n */\nexport const Breadcrumbs = forwardRef<HTMLElement, BreadcrumbsProps>(function Breadcrumbs(\n { items, maxItems = 4, renderLink, className, ...props },\n ref,\n) {\n const strings = useStrings();\n const shouldCollapse = items.length > maxItems;\n const displayItems =\n !shouldCollapse\n ? items\n : [items[0], { collapsed: true } as const, ...items.slice(-2)];\n\n return (\n <nav ref={ref} aria-label={props['aria-label'] ?? strings.breadcrumbs.label} className={cn('text-sm', className)} {...props}>\n <ol className=\"flex flex-wrap items-center gap-1.5 text-foreground-subtle\">\n {displayItems.map((it, i) => {\n const isLast = i === displayItems.length - 1;\n if ('collapsed' in it) {\n return (\n <li key={`ellipsis-${i}`} className=\"flex items-center gap-1.5\">\n <MoreHorizontal className=\"size-4\" aria-hidden />\n <ChevronRight className=\"size-3.5\" aria-hidden />\n </li>\n );\n }\n const item = it as BreadcrumbItem;\n const labelNode = isLast ? (\n <span aria-current=\"page\" className=\"font-medium text-foreground\">\n {item.label}\n </span>\n ) : item.href ? (\n renderLink ? (\n renderLink(item.href, item.label)\n ) : (\n <a\n href={item.href}\n className=\"hover:text-foreground transition-colors duration-[var(--duration-fast)] outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm\"\n >\n {item.label}\n </a>\n )\n ) : (\n <span>{item.label}</span>\n );\n return (\n <li key={i} className=\"flex items-center gap-1.5\">\n {labelNode}\n {!isLast && <ChevronRight className=\"size-3.5\" aria-hidden />}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n});\nBreadcrumbs.displayName = 'Breadcrumbs';\n"],"names":["Breadcrumbs","forwardRef","items","maxItems","renderLink","className","props","ref","strings","useStrings","displayItems","jsx","cn","it","i","isLast","jsxs","MoreHorizontal","ChevronRight","item","labelNode"],"mappings":";;;;;;AAsCO,MAAMA,IAAcC,EAA0C,SACnE,EAAE,OAAAC,GAAO,UAAAC,IAAW,GAAG,YAAAC,GAAY,WAAAC,GAAW,GAAGC,EAAA,GACjDC,GACA;AACA,QAAMC,IAAUC,EAAA,GAEVC,IADiBR,EAAM,SAASC,IAIhC,CAACD,EAAM,CAAC,GAAG,EAAE,WAAW,MAAiB,GAAGA,EAAM,MAAM,EAAE,CAAC,IAD3DA;AAGN,SACE,gBAAAS,EAAC,OAAA,EAAI,KAAAJ,GAAU,cAAYD,EAAM,YAAY,KAAKE,EAAQ,YAAY,OAAO,WAAWI,EAAG,WAAWP,CAAS,GAAI,GAAGC,GACpH,UAAA,gBAAAK,EAAC,MAAA,EAAG,WAAU,8DACX,UAAAD,EAAa,IAAI,CAACG,GAAIC,MAAM;AAC3B,UAAMC,IAASD,MAAMJ,EAAa,SAAS;AAC3C,QAAI,eAAeG;AACjB,aACE,gBAAAG,EAAC,MAAA,EAAyB,WAAU,6BAClC,UAAA;AAAA,QAAA,gBAAAL,EAACM,GAAA,EAAe,WAAU,UAAS,eAAW,IAAC;AAAA,QAC/C,gBAAAN,EAACO,GAAA,EAAa,WAAU,YAAW,eAAW,GAAA,CAAC;AAAA,MAAA,EAAA,GAFxC,YAAYJ,CAAC,EAGtB;AAGJ,UAAMK,IAAON,GACPO,IAAYL,IAChB,gBAAAJ,EAAC,UAAK,gBAAa,QAAO,WAAU,+BACjC,UAAAQ,EAAK,OACR,IACEA,EAAK,OACPf,IACEA,EAAWe,EAAK,MAAMA,EAAK,KAAK,IAEhC,gBAAAR;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAMQ,EAAK;AAAA,QACX,WAAU;AAAA,QAET,UAAAA,EAAK;AAAA,MAAA;AAAA,IAAA,IAIV,gBAAAR,EAAC,QAAA,EAAM,UAAAQ,EAAK,MAAA,CAAM;AAEpB,WACE,gBAAAH,EAAC,MAAA,EAAW,WAAU,6BACnB,UAAA;AAAA,MAAAI;AAAA,MACA,CAACL,KAAU,gBAAAJ,EAACO,KAAa,WAAU,YAAW,eAAW,GAAA,CAAC;AAAA,IAAA,EAAA,GAFpDJ,CAGT;AAAA,EAEJ,CAAC,GACH,GACF;AAEJ,CAAC;AACDd,EAAY,cAAc;"}
1
+ {"version":3,"file":"Breadcrumbs.js","sources":["../../../src/components/ui/Breadcrumbs.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { ChevronRight, MoreHorizontal } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\n\nexport interface BreadcrumbItem {\n /** Visible label. */\n label: ReactNode;\n /** Optional URL. Last item is treated as current page even if href is set. */\n href?: string;\n}\n\nexport interface BreadcrumbsProps extends HTMLAttributes<HTMLElement> {\n items: BreadcrumbItem[];\n /** Collapse to first + ellipsis + last `n` when items.length exceeds this. */\n maxItems?: number;\n /** Custom link renderer (for next/link, react-router, etc.). */\n renderLink?: (href: string, children: ReactNode) => ReactNode;\n /** sr-only text for the collapsed ellipsis. Default \"Hidden items\". */\n collapsedLabel?: string;\n}\n\n/**\n * Breadcrumb trail. Collapses with an ellipsis when there are too many crumbs.\n *\n * @example\n * <Breadcrumbs items={[\n * { label: 'Projects', href: '/projects' },\n * { label: 'Nova', href: '/projects/nova' },\n * { label: 'Settings' },\n * ]} />\n *\n * @example With react-router\n * <Breadcrumbs items={trail} renderLink={(href, c) => <Link to={href}>{c}</Link>} />\n *\n * @do Always omit `href` on the last item — it represents the current page.\n * @dont Use Breadcrumbs for flat navigation. Use TopNav links instead.\n */\nexport const Breadcrumbs = forwardRef<HTMLElement, BreadcrumbsProps>(function Breadcrumbs(\n {\n items,\n maxItems = 4,\n renderLink,\n collapsedLabel: collapsedLabelProp,\n className,\n 'aria-label': ariaLabel,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n const collapsedLabel = collapsedLabelProp ?? strings.breadcrumbs.collapsed;\n const shouldCollapse = items.length > maxItems;\n const displayItems = !shouldCollapse\n ? items\n : [items[0], { collapsed: true } as const, ...items.slice(-2)];\n\n return (\n <nav\n ref={ref}\n aria-label={ariaLabel ?? strings.breadcrumbs.label}\n className={cn('text-sm', className)}\n {...props}\n >\n <ol className=\"text-foreground-subtle flex flex-wrap items-center gap-1.5\">\n {displayItems.map((it, i) => {\n const isLast = i === displayItems.length - 1;\n if ('collapsed' in it) {\n return (\n <li key={`ellipsis-${i}`} className=\"flex items-center gap-1.5\">\n <MoreHorizontal className=\"size-4\" aria-hidden />\n <span className=\"sr-only\">{collapsedLabel}</span>\n <ChevronRight className=\"size-3.5\" aria-hidden />\n </li>\n );\n }\n const item = it as BreadcrumbItem;\n const labelNode = isLast ? (\n <span aria-current=\"page\" className=\"text-foreground font-medium\">\n {item.label}\n </span>\n ) : item.href ? (\n renderLink ? (\n renderLink(item.href, item.label)\n ) : (\n <a\n href={item.href}\n className=\"hover:text-foreground focus-visible:ring-ring rounded-sm transition-colors duration-[var(--duration-fast)] outline-none focus-visible:ring-2 focus-visible:ring-offset-2\"\n >\n {item.label}\n </a>\n )\n ) : (\n <span>{item.label}</span>\n );\n return (\n <li key={i} className=\"flex items-center gap-1.5\">\n {labelNode}\n {!isLast && <ChevronRight className=\"size-3.5\" aria-hidden />}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n});\nBreadcrumbs.displayName = 'Breadcrumbs';\n"],"names":["Breadcrumbs","forwardRef","items","maxItems","renderLink","collapsedLabelProp","className","ariaLabel","props","ref","strings","useStrings","collapsedLabel","displayItems","jsx","cn","it","i","isLast","jsxs","MoreHorizontal","ChevronRight","item","labelNode"],"mappings":";;;;;;AAwCO,MAAMA,IAAcC,EAA0C,SACnE;AAAA,EACE,OAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,YAAAC;AAAA,EACA,gBAAgBC;AAAA,EAChB,WAAAC;AAAA,EACA,cAAcC;AAAA,EACd,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAUC,EAAA,GACVC,IAAiBP,KAAsBK,EAAQ,YAAY,WAE3DG,IADiBX,EAAM,SAASC,IAGlC,CAACD,EAAM,CAAC,GAAG,EAAE,WAAW,MAAiB,GAAGA,EAAM,MAAM,EAAE,CAAC,IAD3DA;AAGJ,SACE,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,cAAYF,KAAaG,EAAQ,YAAY;AAAA,MAC7C,WAAWK,EAAG,WAAWT,CAAS;AAAA,MACjC,GAAGE;AAAA,MAEJ,UAAA,gBAAAM,EAAC,QAAG,WAAU,8DACX,YAAa,IAAI,CAACE,GAAIC,MAAM;AAC3B,cAAMC,IAASD,MAAMJ,EAAa,SAAS;AAC3C,YAAI,eAAeG;AACjB,iBACE,gBAAAG,EAAC,MAAA,EAAyB,WAAU,6BAClC,UAAA;AAAA,YAAA,gBAAAL,EAACM,GAAA,EAAe,WAAU,UAAS,eAAW,IAAC;AAAA,YAC/C,gBAAAN,EAAC,QAAA,EAAK,WAAU,WAAW,UAAAF,GAAe;AAAA,YAC1C,gBAAAE,EAACO,GAAA,EAAa,WAAU,YAAW,eAAW,GAAA,CAAC;AAAA,UAAA,EAAA,GAHxC,YAAYJ,CAAC,EAItB;AAGJ,cAAMK,IAAON,GACPO,IAAYL,IAChB,gBAAAJ,EAAC,UAAK,gBAAa,QAAO,WAAU,+BACjC,UAAAQ,EAAK,OACR,IACEA,EAAK,OACPlB,IACEA,EAAWkB,EAAK,MAAMA,EAAK,KAAK,IAEhC,gBAAAR;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAMQ,EAAK;AAAA,YACX,WAAU;AAAA,YAET,UAAAA,EAAK;AAAA,UAAA;AAAA,QAAA,IAIV,gBAAAR,EAAC,QAAA,EAAM,UAAAQ,EAAK,MAAA,CAAM;AAEpB,eACE,gBAAAH,EAAC,MAAA,EAAW,WAAU,6BACnB,UAAA;AAAA,UAAAI;AAAA,UACA,CAACL,KAAU,gBAAAJ,EAACO,KAAa,WAAU,YAAW,eAAW,GAAA,CAAC;AAAA,QAAA,EAAA,GAFpDJ,CAGT;AAAA,MAEJ,CAAC,EAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;AACDjB,EAAY,cAAc;"}
@@ -2,7 +2,7 @@ import { ButtonHTMLAttributes, ReactNode } from 'react';
2
2
  import { VariantProps } from '../../lib/cva.js';
3
3
  declare const button: (props?: ({
4
4
  variant?: "link" | "outline" | "primary" | "secondary" | "ghost" | "destructive" | null | undefined;
5
- size?: "icon" | "md" | "sm" | "lg" | null | undefined;
5
+ size?: "icon" | "md" | "sm" | "lg" | "xl" | null | undefined;
6
6
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
7
7
  export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof button> {
8
8
  /**
@@ -12,8 +12,10 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, Va
12
12
  */
13
13
  asChild?: boolean;
14
14
  /**
15
- * Show a spinner in place of the leading icon and disable the button.
16
- * Use for async actions where the user must wait.
15
+ * Show a spinner in place of the leading icon and block interaction while
16
+ * keeping keyboard focus (`aria-disabled` + `aria-busy`, not `disabled`, so
17
+ * focus is not lost mid-submit). With `asChild` no spinner is rendered —
18
+ * the child is only marked busy and made inert.
17
19
  * @default false
18
20
  */
19
21
  loading?: boolean;
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { jsx as s, jsxs as l } from "react/jsx-runtime";
3
- import { forwardRef as f } from "react";
4
- import { Slot as p } from "@radix-ui/react-slot";
5
- import { Loader2 as x } from "../../icons/index.js";
6
- import { cn as h } from "../../lib/utils.js";
7
- import { cva as k } from "class-variance-authority";
8
- const z = k(
2
+ import { jsx as c, jsxs as m } from "react/jsx-runtime";
3
+ import { forwardRef as x } from "react";
4
+ import { Slot as h } from "@radix-ui/react-slot";
5
+ import { Loader2 as k } from "../../icons/index.js";
6
+ import { cn as y } from "../../lib/utils.js";
7
+ import { cva as z } from "class-variance-authority";
8
+ const _ = z(
9
9
  [
10
10
  "inline-flex items-center justify-center gap-2 whitespace-nowrap",
11
11
  "rounded-md text-sm font-medium",
@@ -14,23 +14,21 @@ const z = k(
14
14
  "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
15
15
  "focus-visible:ring-offset-background",
16
16
  "disabled:pointer-events-none disabled:opacity-50",
17
+ // Loading keeps focus (no `disabled`) but blocks interaction.
18
+ "aria-busy:pointer-events-none",
17
19
  "[&_svg]:pointer-events-none [&_svg]:shrink-0"
18
20
  ],
19
21
  {
20
22
  variants: {
21
23
  variant: {
22
- primary: [
23
- "bg-accent text-on-accent",
24
- "hover:bg-accent-hover",
25
- "active:bg-accent-active"
26
- ],
24
+ primary: ["bg-accent text-on-accent", "hover:bg-accent-hover", "active:bg-accent-active"],
27
25
  secondary: [
28
- "bg-background-muted text-foreground border border-border",
26
+ "bg-background-muted text-foreground border border-border-input",
29
27
  "hover:bg-surface-hover",
30
28
  "active:bg-surface-active"
31
29
  ],
32
30
  outline: [
33
- "border border-border bg-transparent text-foreground",
31
+ "border border-border-input bg-transparent text-foreground",
34
32
  "hover:bg-background-muted",
35
33
  "active:bg-background-subtle"
36
34
  ],
@@ -54,6 +52,8 @@ const z = k(
54
52
  sm: "h-8 px-3 text-xs [&_svg]:size-4",
55
53
  md: "h-9 px-3.5 text-sm [&_svg]:size-4",
56
54
  lg: "h-10 px-4 text-sm [&_svg]:size-5",
55
+ // 44px — touch-first screens and marketing CTAs.
56
+ xl: "h-11 px-5 text-base [&_svg]:size-5",
57
57
  icon: "h-9 w-9 [&_svg]:size-4"
58
58
  }
59
59
  },
@@ -61,57 +61,71 @@ const z = k(
61
61
  // The `link` variant ignores horizontal padding from the size variant.
62
62
  { variant: "link", size: "sm", class: "h-auto px-0" },
63
63
  { variant: "link", size: "md", class: "h-auto px-0" },
64
- { variant: "link", size: "lg", class: "h-auto px-0" }
64
+ { variant: "link", size: "lg", class: "h-auto px-0" },
65
+ { variant: "link", size: "xl", class: "h-auto px-0" }
65
66
  ],
66
67
  defaultVariants: {
67
68
  variant: "primary",
68
69
  size: "md"
69
70
  }
70
71
  }
71
- ), y = f(function({
72
- className: o,
73
- variant: i,
74
- size: c,
75
- asChild: d = !1,
72
+ ), w = x(function({
73
+ className: u,
74
+ variant: v,
75
+ size: d,
76
+ asChild: b = !1,
76
77
  loading: e = !1,
77
- leadingIcon: u,
78
- trailingIcon: v,
79
- disabled: b,
80
- children: t,
81
- type: g = "button",
82
- ...r
83
- }, a) {
84
- const m = b || e, n = h(z({ variant: i, size: c }), o);
85
- return d ? /* @__PURE__ */ s(
86
- p,
78
+ leadingIcon: g,
79
+ trailingIcon: l,
80
+ disabled: p,
81
+ children: a,
82
+ type: f = "button",
83
+ onClick: n,
84
+ ...i
85
+ }, o) {
86
+ const s = y(_({ variant: v, size: d }), u);
87
+ return b ? /* @__PURE__ */ c(
88
+ h,
87
89
  {
88
- ref: a,
90
+ ref: o,
89
91
  "aria-busy": e || void 0,
92
+ "aria-disabled": e || void 0,
90
93
  "data-loading": e || void 0,
91
- className: n,
92
- ...r,
93
- children: t
94
+ className: s,
95
+ onClick: n,
96
+ onClickCapture: e ? r : void 0,
97
+ onKeyDownCapture: e ? N : void 0,
98
+ ...i,
99
+ children: a
94
100
  }
95
- ) : /* @__PURE__ */ l(
101
+ ) : /* @__PURE__ */ m(
96
102
  "button",
97
103
  {
98
- ref: a,
99
- type: g,
104
+ ref: o,
105
+ type: f,
100
106
  "aria-busy": e || void 0,
101
- disabled: m,
107
+ "aria-disabled": e || void 0,
108
+ disabled: p,
102
109
  "data-loading": e || void 0,
103
- className: n,
104
- ...r,
110
+ className: s,
111
+ onClick: e ? r : n,
112
+ ...i,
105
113
  children: [
106
- e ? /* @__PURE__ */ s(x, { className: "animate-spin", "aria-hidden": "true" }) : u,
107
- t,
108
- !e && v
114
+ e ? /* @__PURE__ */ c(k, { className: "animate-spin", "aria-hidden": "true" }) : g,
115
+ a,
116
+ !e && l
109
117
  ]
110
118
  }
111
119
  );
112
120
  });
113
- y.displayName = "Button";
121
+ w.displayName = "Button";
122
+ function r(t) {
123
+ t.preventDefault(), t.stopPropagation();
124
+ }
125
+ function N(t) {
126
+ (t.key === "Enter" || t.key === " ") && r(t);
127
+ }
114
128
  export {
115
- y as Button
129
+ w as Button
116
130
  };
117
131
  //# sourceMappingURL=Button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sources":["../../../src/components/ui/Button.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Loader2 } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from '@/lib/cva';\n\n/* -----------------------------------------------------------------------------\n * Variants — the entire visual surface of the Button.\n *\n * All sizes share the same border radius (md = 6px) per the refined-minimal\n * rules. Focus state is the standardised 2px-ring + 2px-offset on every\n * variant, including `link`.\n * --------------------------------------------------------------------------- */\nconst button = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'rounded-md text-sm font-medium',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'outline-none',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'focus-visible:ring-offset-background',\n 'disabled:pointer-events-none disabled:opacity-50',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'bg-accent text-on-accent',\n 'hover:bg-accent-hover',\n 'active:bg-accent-active',\n ],\n secondary: [\n 'bg-background-muted text-foreground border border-border',\n 'hover:bg-surface-hover',\n 'active:bg-surface-active',\n ],\n outline: [\n 'border border-border bg-transparent text-foreground',\n 'hover:bg-background-muted',\n 'active:bg-background-subtle',\n ],\n ghost: [\n 'bg-transparent text-foreground',\n 'hover:bg-background-muted',\n 'active:bg-background-subtle',\n ],\n destructive: [\n 'bg-danger text-on-danger',\n 'hover:bg-danger-hover',\n 'active:bg-danger-active',\n ],\n link: [\n 'bg-transparent text-accent underline-offset-4 px-0',\n 'hover:underline',\n 'active:text-accent-hover',\n ],\n },\n size: {\n sm: 'h-8 px-3 text-xs [&_svg]:size-4',\n md: 'h-9 px-3.5 text-sm [&_svg]:size-4',\n lg: 'h-10 px-4 text-sm [&_svg]:size-5',\n icon: 'h-9 w-9 [&_svg]:size-4',\n },\n },\n compoundVariants: [\n // The `link` variant ignores horizontal padding from the size variant.\n { variant: 'link', size: 'sm', class: 'h-auto px-0' },\n { variant: 'link', size: 'md', class: 'h-auto px-0' },\n { variant: 'link', size: 'lg', class: 'h-auto px-0' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n },\n);\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof button> {\n /**\n * Render as a different element via Radix Slot. Useful when wrapping a\n * link: `<Button asChild><a href=\"…\">…</a></Button>`.\n * @default false\n */\n asChild?: boolean;\n /**\n * Show a spinner in place of the leading icon and disable the button.\n * Use for async actions where the user must wait.\n * @default false\n */\n loading?: boolean;\n /** Icon rendered before the label. Replaced by a spinner when loading. */\n leadingIcon?: ReactNode;\n /** Icon rendered after the label. Hidden while loading. */\n trailingIcon?: ReactNode;\n}\n\n/**\n * Primary interactive element. Variants:\n *\n * - `primary` — accent fill, the single most prominent action on a screen.\n * - `secondary` — neutral fill, sits next to a primary or stands alone for\n * secondary actions.\n * - `outline` — border only, transparent fill. Use when next to a primary.\n * - `ghost` — no border, hover background. Use in dense toolbars and tables.\n * - `destructive` — danger fill, reserved for irreversible actions.\n * - `link` — text styled as a link.\n *\n * @example Two-button row\n * <div className=\"flex gap-2 justify-end\">\n * <Button variant=\"outline\">Cancel</Button>\n * <Button>Save changes</Button>\n * </div>\n *\n * @example Loading state\n * <Button loading leadingIcon={<Mail />}>Sending…</Button>\n *\n * @do Use one primary button per major surface. Verb-first labels.\n * @dont Stack three primary buttons in a row — only the most important\n * action gets the primary variant.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n children,\n type = 'button',\n ...props\n },\n ref,\n) {\n const isDisabled = disabled || loading;\n const classes = cn(button({ variant, size }), className);\n\n if (asChild) {\n // Slot requires exactly one element child — pass the consumer's element\n // through untouched. The consumer is responsible for any leading/trailing\n // icons inside that element.\n return (\n <Slot\n ref={ref}\n aria-busy={loading || undefined}\n data-loading={loading || undefined}\n className={classes}\n {...props}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n type={type}\n aria-busy={loading || undefined}\n disabled={isDisabled}\n data-loading={loading || undefined}\n className={classes}\n {...props}\n >\n {loading ? (\n <Loader2 className=\"animate-spin\" aria-hidden=\"true\" />\n ) : (\n leadingIcon\n )}\n {children}\n {!loading && trailingIcon}\n </button>\n );\n});\n\nButton.displayName = 'Button';\n"],"names":["button","cva","Button","forwardRef","className","variant","size","asChild","loading","leadingIcon","trailingIcon","disabled","children","type","props","ref","isDisabled","classes","cn","jsx","Slot","jsxs","Loader2"],"mappings":";;;;;;;AAeA,MAAMA,IAASC;AAAA,EACb;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,kBAAkB;AAAA;AAAA,MAEhB,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,IAAc;AAAA,IAEtD,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GA+CaC,IAASC,EAA2C,SAC/D;AAAA,EACE,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,SAAAC,IAAU;AAAA,EACV,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAaL,KAAYH,GACzBS,IAAUC,EAAGlB,EAAO,EAAE,SAAAK,GAAS,MAAAC,EAAA,CAAM,GAAGF,CAAS;AAEvD,SAAIG,IAKA,gBAAAY;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,aAAWP,KAAW;AAAA,MACtB,gBAAcA,KAAW;AAAA,MACzB,WAAWS;AAAA,MACV,GAAGH;AAAA,MAEH,UAAAF;AAAA,IAAA;AAAA,EAAA,IAML,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAN;AAAA,MACA,MAAAF;AAAA,MACA,aAAWL,KAAW;AAAA,MACtB,UAAUQ;AAAA,MACV,gBAAcR,KAAW;AAAA,MACzB,WAAWS;AAAA,MACV,GAAGH;AAAA,MAEH,UAAA;AAAA,QAAAN,sBACEc,GAAA,EAAQ,WAAU,gBAAe,eAAY,QAAO,IAErDb;AAAA,QAEDG;AAAA,QACA,CAACJ,KAAWE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGnB,CAAC;AAEDR,EAAO,cAAc;"}
1
+ {"version":3,"file":"Button.js","sources":["../../../src/components/ui/Button.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ButtonHTMLAttributes,\n type MouseEvent,\n type ReactNode,\n type SyntheticEvent,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Loader2 } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from '@/lib/cva';\n\n/* -----------------------------------------------------------------------------\n * Variants — the entire visual surface of the Button.\n *\n * All sizes share the same border radius (md = 6px) per the refined-minimal\n * rules. Focus state is the standardised 2px-ring + 2px-offset on every\n * variant, including `link`.\n * --------------------------------------------------------------------------- */\nconst button = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'rounded-md text-sm font-medium',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'outline-none',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'focus-visible:ring-offset-background',\n 'disabled:pointer-events-none disabled:opacity-50',\n // Loading keeps focus (no `disabled`) but blocks interaction.\n 'aria-busy:pointer-events-none',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0',\n ],\n {\n variants: {\n variant: {\n primary: ['bg-accent text-on-accent', 'hover:bg-accent-hover', 'active:bg-accent-active'],\n secondary: [\n 'bg-background-muted text-foreground border border-border-input',\n 'hover:bg-surface-hover',\n 'active:bg-surface-active',\n ],\n outline: [\n 'border border-border-input bg-transparent text-foreground',\n 'hover:bg-background-muted',\n 'active:bg-background-subtle',\n ],\n ghost: [\n 'bg-transparent text-foreground',\n 'hover:bg-background-muted',\n 'active:bg-background-subtle',\n ],\n destructive: [\n 'bg-danger text-on-danger',\n 'hover:bg-danger-hover',\n 'active:bg-danger-active',\n ],\n link: [\n 'bg-transparent text-accent underline-offset-4 px-0',\n 'hover:underline',\n 'active:text-accent-hover',\n ],\n },\n size: {\n sm: 'h-8 px-3 text-xs [&_svg]:size-4',\n md: 'h-9 px-3.5 text-sm [&_svg]:size-4',\n lg: 'h-10 px-4 text-sm [&_svg]:size-5',\n // 44px — touch-first screens and marketing CTAs.\n xl: 'h-11 px-5 text-base [&_svg]:size-5',\n icon: 'h-9 w-9 [&_svg]:size-4',\n },\n },\n compoundVariants: [\n // The `link` variant ignores horizontal padding from the size variant.\n { variant: 'link', size: 'sm', class: 'h-auto px-0' },\n { variant: 'link', size: 'md', class: 'h-auto px-0' },\n { variant: 'link', size: 'lg', class: 'h-auto px-0' },\n { variant: 'link', size: 'xl', class: 'h-auto px-0' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n },\n);\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof button> {\n /**\n * Render as a different element via Radix Slot. Useful when wrapping a\n * link: `<Button asChild><a href=\"…\">…</a></Button>`.\n * @default false\n */\n asChild?: boolean;\n /**\n * Show a spinner in place of the leading icon and block interaction while\n * keeping keyboard focus (`aria-disabled` + `aria-busy`, not `disabled`, so\n * focus is not lost mid-submit). With `asChild` no spinner is rendered —\n * the child is only marked busy and made inert.\n * @default false\n */\n loading?: boolean;\n /** Icon rendered before the label. Replaced by a spinner when loading. */\n leadingIcon?: ReactNode;\n /** Icon rendered after the label. Hidden while loading. */\n trailingIcon?: ReactNode;\n}\n\n/**\n * Primary interactive element. Variants:\n *\n * - `primary` — accent fill, the single most prominent action on a screen.\n * - `secondary` — neutral fill, sits next to a primary or stands alone for\n * secondary actions.\n * - `outline` — border only, transparent fill. Use when next to a primary.\n * - `ghost` — no border, hover background. Use in dense toolbars and tables.\n * - `destructive` — danger fill, reserved for irreversible actions.\n * - `link` — text styled as a link.\n *\n * @example Two-button row\n * <div className=\"flex gap-2 justify-end\">\n * <Button variant=\"outline\">Cancel</Button>\n * <Button>Save changes</Button>\n * </div>\n *\n * @example Loading state\n * <Button loading leadingIcon={<Mail />}>Sending…</Button>\n *\n * @do Use one primary button per major surface. Verb-first labels.\n * @dont Stack three primary buttons in a row — only the most important\n * action gets the primary variant.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n children,\n type = 'button',\n onClick,\n ...props\n },\n ref,\n) {\n const classes = cn(button({ variant, size }), className);\n\n if (asChild) {\n // Slot requires exactly one element child — pass the consumer's element\n // through untouched. The consumer is responsible for any leading/trailing\n // icons inside that element. While loading, a capture-phase guard stops\n // the child's own handlers (and link navigation) before they run.\n return (\n <Slot\n ref={ref}\n aria-busy={loading || undefined}\n aria-disabled={loading || undefined}\n data-loading={loading || undefined}\n className={classes}\n onClick={onClick}\n onClickCapture={loading ? blockEvent : undefined}\n onKeyDownCapture={loading ? blockActivationKey : undefined}\n {...props}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n type={type}\n aria-busy={loading || undefined}\n aria-disabled={loading || undefined}\n disabled={disabled}\n data-loading={loading || undefined}\n className={classes}\n onClick={loading ? blockEvent : onClick}\n {...props}\n >\n {loading ? <Loader2 className=\"animate-spin\" aria-hidden=\"true\" /> : leadingIcon}\n {children}\n {!loading && trailingIcon}\n </button>\n );\n});\n\nButton.displayName = 'Button';\n\nfunction blockEvent(e: SyntheticEvent | MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n}\n\nfunction blockActivationKey(e: React.KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') blockEvent(e);\n}\n"],"names":["button","cva","Button","forwardRef","className","variant","size","asChild","loading","leadingIcon","trailingIcon","disabled","children","type","onClick","props","ref","classes","cn","jsx","Slot","blockEvent","blockActivationKey","jsxs","Loader2","e"],"mappings":";;;;;;;AAqBA,MAAMA,IAASC;AAAA,EACb;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS,CAAC,4BAA4B,yBAAyB,yBAAyB;AAAA,QACxF,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA;AAAA,QAEJ,IAAI;AAAA,QACJ,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,kBAAkB;AAAA;AAAA,MAEhB,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,IAAc;AAAA,IAEtD,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GAgDaC,IAASC,EAA2C,SAC/D;AAAA,EACE,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,SAAAC,IAAU;AAAA,EACV,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,SAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAUC,EAAGlB,EAAO,EAAE,SAAAK,GAAS,MAAAC,EAAA,CAAM,GAAGF,CAAS;AAEvD,SAAIG,IAMA,gBAAAY;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAJ;AAAA,MACA,aAAWR,KAAW;AAAA,MACtB,iBAAeA,KAAW;AAAA,MAC1B,gBAAcA,KAAW;AAAA,MACzB,WAAWS;AAAA,MACX,SAAAH;AAAA,MACA,gBAAgBN,IAAUa,IAAa;AAAA,MACvC,kBAAkBb,IAAUc,IAAqB;AAAA,MAChD,GAAGP;AAAA,MAEH,UAAAH;AAAA,IAAA;AAAA,EAAA,IAML,gBAAAW;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAP;AAAA,MACA,MAAAH;AAAA,MACA,aAAWL,KAAW;AAAA,MACtB,iBAAeA,KAAW;AAAA,MAC1B,UAAAG;AAAA,MACA,gBAAcH,KAAW;AAAA,MACzB,WAAWS;AAAA,MACX,SAAST,IAAUa,IAAaP;AAAA,MAC/B,GAAGC;AAAA,MAEH,UAAA;AAAA,QAAAP,sBAAWgB,GAAA,EAAQ,WAAU,gBAAe,eAAY,QAAO,IAAKf;AAAA,QACpEG;AAAA,QACA,CAACJ,KAAWE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGnB,CAAC;AAEDR,EAAO,cAAc;AAErB,SAASmB,EAAWI,GAAgC;AAClD,EAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA;AACJ;AAEA,SAASH,EAAmBG,GAAwB;AAClD,GAAIA,EAAE,QAAQ,WAAWA,EAAE,QAAQ,UAAgBA,CAAC;AACtD;"}
@@ -9,7 +9,7 @@ export type CalendarProps = DayPickerProps & {
9
9
  * Not a forwardRef: RDP v9's `DayPicker` is a plain function component and
10
10
  * exposes no root ref, so a forwarded ref would silently be dropped.
11
11
  */
12
- export declare function Calendar({ className, classNames, captionLayout, startMonth, endMonth, ...props }: CalendarProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function Calendar({ className, classNames, captionLayout, startMonth, endMonth, labels, weekStartsOn, ...props }: CalendarProps): import("react/jsx-runtime").JSX.Element;
13
13
  export declare namespace Calendar {
14
14
  var displayName: string;
15
15
  }