@codefast/ui 0.3.16-canary.3 → 0.4.0-canary.5

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 (281) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +27 -16
  3. package/dist/components/accordion.d.mts +7 -22
  4. package/dist/components/accordion.mjs +26 -29
  5. package/dist/components/alert-dialog.d.mts +27 -26
  6. package/dist/components/alert-dialog.mjs +53 -45
  7. package/dist/components/alert.d.mts +12 -2
  8. package/dist/components/alert.mjs +15 -6
  9. package/dist/components/aspect-ratio.d.mts +2 -2
  10. package/dist/components/aspect-ratio.mjs +2 -3
  11. package/dist/components/avatar.d.mts +41 -5
  12. package/dist/components/avatar.mjs +40 -10
  13. package/dist/components/badge.mjs +4 -4
  14. package/dist/components/breadcrumb.d.mts +1 -0
  15. package/dist/components/breadcrumb.mjs +11 -10
  16. package/dist/components/button-group.d.mts +1 -1
  17. package/dist/components/button-group.mjs +6 -7
  18. package/dist/components/button.d.mts +0 -1
  19. package/dist/components/button.mjs +7 -7
  20. package/dist/components/calendar.d.mts +6 -2
  21. package/dist/components/calendar.mjs +39 -43
  22. package/dist/components/card.d.mts +4 -2
  23. package/dist/components/card.mjs +9 -9
  24. package/dist/components/carousel.d.mts +16 -4
  25. package/dist/components/carousel.mjs +25 -12
  26. package/dist/components/chart.d.mts +8 -3
  27. package/dist/components/chart.mjs +21 -15
  28. package/dist/components/checkbox-cards.mjs +6 -6
  29. package/dist/components/checkbox-group.mjs +6 -7
  30. package/dist/components/checkbox.d.mts +2 -2
  31. package/dist/components/checkbox.mjs +8 -9
  32. package/dist/components/collapsible.d.mts +4 -4
  33. package/dist/components/collapsible.mjs +4 -5
  34. package/dist/components/command.d.mts +11 -1
  35. package/dist/components/command.mjs +35 -32
  36. package/dist/components/context-menu.d.mts +22 -15
  37. package/dist/components/context-menu.mjs +44 -39
  38. package/dist/components/dialog.d.mts +19 -23
  39. package/dist/components/dialog.mjs +48 -47
  40. package/dist/components/direction.d.mts +24 -0
  41. package/dist/components/direction.mjs +18 -0
  42. package/dist/components/drawer.d.mts +2 -20
  43. package/dist/components/drawer.mjs +17 -25
  44. package/dist/components/dropdown-menu.d.mts +22 -15
  45. package/dist/components/dropdown-menu.mjs +41 -37
  46. package/dist/components/empty.mjs +5 -5
  47. package/dist/components/field.d.mts +1 -1
  48. package/dist/components/field.mjs +11 -12
  49. package/dist/components/form.d.mts +6 -7
  50. package/dist/components/form.mjs +6 -7
  51. package/dist/components/hover-card.d.mts +5 -5
  52. package/dist/components/hover-card.mjs +14 -12
  53. package/dist/components/input-group.d.mts +1 -1
  54. package/dist/components/input-group.mjs +12 -7
  55. package/dist/components/input-number.d.mts +3 -1
  56. package/dist/components/input-number.mjs +49 -27
  57. package/dist/components/input-otp.mjs +9 -7
  58. package/dist/components/input-password.mjs +1 -4
  59. package/dist/components/input-search.mjs +3 -5
  60. package/dist/components/input.mjs +1 -2
  61. package/dist/components/item.mjs +9 -9
  62. package/dist/components/kbd.mjs +1 -1
  63. package/dist/components/label.d.mts +2 -2
  64. package/dist/components/label.mjs +3 -4
  65. package/dist/components/menubar.d.mts +22 -16
  66. package/dist/components/menubar.mjs +54 -47
  67. package/dist/components/native-select.d.mts +5 -1
  68. package/dist/components/native-select.mjs +9 -6
  69. package/dist/components/navigation-menu.d.mts +30 -8
  70. package/dist/components/navigation-menu.mjs +33 -23
  71. package/dist/components/pagination.d.mts +6 -0
  72. package/dist/components/pagination.mjs +26 -11
  73. package/dist/components/popover.d.mts +40 -7
  74. package/dist/components/popover.mjs +46 -14
  75. package/dist/components/progress-circle.d.mts +1 -1
  76. package/dist/components/progress-circle.mjs +1 -2
  77. package/dist/components/progress.d.mts +2 -2
  78. package/dist/components/progress.mjs +5 -6
  79. package/dist/components/radio-cards.d.mts +3 -3
  80. package/dist/components/radio-cards.mjs +11 -11
  81. package/dist/components/radio-group.d.mts +3 -3
  82. package/dist/components/radio-group.mjs +9 -9
  83. package/dist/components/radio.mjs +2 -3
  84. package/dist/components/resizable.mjs +3 -8
  85. package/dist/components/scroll-area.d.mts +5 -5
  86. package/dist/components/scroll-area.mjs +13 -10
  87. package/dist/components/select.d.mts +14 -14
  88. package/dist/components/select.mjs +47 -47
  89. package/dist/components/separator.d.mts +2 -2
  90. package/dist/components/separator.mjs +3 -4
  91. package/dist/components/sheet.d.mts +13 -14
  92. package/dist/components/sheet.mjs +41 -39
  93. package/dist/components/sidebar.d.mts +2 -3
  94. package/dist/components/sidebar.mjs +46 -46
  95. package/dist/components/skeleton.mjs +1 -1
  96. package/dist/components/slider.d.mts +2 -2
  97. package/dist/components/slider.mjs +9 -11
  98. package/dist/components/sonner.mjs +11 -3
  99. package/dist/components/spinner.mjs +6 -7
  100. package/dist/components/switch.d.mts +5 -2
  101. package/dist/components/switch.mjs +7 -7
  102. package/dist/components/table.mjs +10 -10
  103. package/dist/components/tabs.d.mts +8 -5
  104. package/dist/components/tabs.mjs +18 -12
  105. package/dist/components/textarea.mjs +1 -1
  106. package/dist/components/toggle-group.d.mts +9 -6
  107. package/dist/components/toggle-group.mjs +19 -20
  108. package/dist/components/toggle.d.mts +2 -3
  109. package/dist/components/toggle.mjs +4 -6
  110. package/dist/components/tooltip.d.mts +7 -6
  111. package/dist/components/tooltip.mjs +19 -17
  112. package/dist/hooks/use-animated-value.mjs +0 -1
  113. package/dist/hooks/use-copy-to-clipboard.mjs +0 -1
  114. package/dist/hooks/use-is-mobile.mjs +0 -1
  115. package/dist/hooks/use-media-query.mjs +0 -1
  116. package/dist/hooks/use-mutation-observer.mjs +0 -1
  117. package/dist/hooks/use-pagination.mjs +0 -1
  118. package/dist/index.d.mts +15 -13
  119. package/dist/index.mjs +18 -16
  120. package/dist/primitives/checkbox-group.d.mts +9 -10
  121. package/dist/primitives/checkbox-group.mjs +14 -19
  122. package/dist/primitives/input-number.d.mts +3 -3
  123. package/dist/primitives/input-number.mjs +3 -5
  124. package/dist/primitives/input.d.mts +4 -4
  125. package/dist/primitives/input.mjs +2 -3
  126. package/dist/primitives/progress-circle.d.mts +3 -3
  127. package/dist/primitives/progress-circle.mjs +2 -3
  128. package/dist/variants/alert.d.mts +1 -1
  129. package/dist/variants/alert.mjs +3 -13
  130. package/dist/variants/badge.d.mts +6 -4
  131. package/dist/variants/badge.mjs +7 -34
  132. package/dist/variants/button-group.d.mts +2 -2
  133. package/dist/variants/button-group.mjs +3 -14
  134. package/dist/variants/button.d.mts +12 -10
  135. package/dist/variants/button.mjs +15 -57
  136. package/dist/variants/empty.d.mts +1 -1
  137. package/dist/variants/empty.mjs +2 -7
  138. package/dist/variants/field.d.mts +3 -3
  139. package/dist/variants/field.mjs +4 -22
  140. package/dist/variants/input-group.d.mts +9 -9
  141. package/dist/variants/input-group.mjs +11 -70
  142. package/dist/variants/input-number.d.mts +45 -0
  143. package/dist/variants/input-number.mjs +40 -0
  144. package/dist/variants/item.d.mts +5 -4
  145. package/dist/variants/item.mjs +9 -31
  146. package/dist/variants/navigation-menu.d.mts +1 -1
  147. package/dist/variants/navigation-menu.mjs +1 -5
  148. package/dist/variants/progress-circle.d.mts +1 -1
  149. package/dist/variants/progress-circle.mjs +1 -5
  150. package/dist/variants/scroll-area.d.mts +2 -2
  151. package/dist/variants/scroll-area.mjs +3 -8
  152. package/dist/variants/separator.mjs +6 -6
  153. package/dist/variants/sheet.d.mts +4 -4
  154. package/dist/variants/sheet.mjs +5 -38
  155. package/dist/variants/sidebar.d.mts +4 -4
  156. package/dist/variants/sidebar.mjs +6 -23
  157. package/dist/variants/tabs.d.mts +18 -0
  158. package/dist/variants/tabs.mjs +15 -0
  159. package/dist/variants/toggle.d.mts +4 -4
  160. package/dist/variants/toggle.mjs +9 -27
  161. package/package.json +27 -44
  162. package/src/components/accordion.tsx +26 -68
  163. package/src/components/alert-dialog.tsx +70 -86
  164. package/src/components/alert.tsx +27 -19
  165. package/src/components/aspect-ratio.tsx +1 -4
  166. package/src/components/avatar.tsx +99 -12
  167. package/src/components/badge.tsx +5 -8
  168. package/src/components/breadcrumb.tsx +18 -24
  169. package/src/components/button-group.tsx +10 -20
  170. package/src/components/button.tsx +8 -19
  171. package/src/components/calendar.tsx +77 -132
  172. package/src/components/card.tsx +16 -22
  173. package/src/components/carousel.tsx +40 -58
  174. package/src/components/chart.tsx +41 -92
  175. package/src/components/checkbox-cards.tsx +11 -30
  176. package/src/components/checkbox-group.tsx +6 -28
  177. package/src/components/checkbox.tsx +6 -26
  178. package/src/components/collapsible.tsx +1 -4
  179. package/src/components/command.tsx +52 -65
  180. package/src/components/context-menu.tsx +46 -125
  181. package/src/components/dialog.tsx +49 -101
  182. package/src/components/direction.tsx +32 -0
  183. package/src/components/drawer.tsx +17 -79
  184. package/src/components/dropdown-menu.tsx +39 -118
  185. package/src/components/empty.tsx +6 -20
  186. package/src/components/field.tsx +19 -52
  187. package/src/components/form.tsx +19 -61
  188. package/src/components/hover-card.tsx +4 -27
  189. package/src/components/input-group.tsx +13 -52
  190. package/src/components/input-number.tsx +55 -75
  191. package/src/components/input-otp.tsx +19 -38
  192. package/src/components/input-password.tsx +5 -29
  193. package/src/components/input-search.tsx +6 -23
  194. package/src/components/input.tsx +1 -17
  195. package/src/components/item.tsx +17 -31
  196. package/src/components/kbd.tsx +2 -14
  197. package/src/components/label.tsx +2 -10
  198. package/src/components/menubar.tsx +34 -125
  199. package/src/components/native-select.tsx +21 -30
  200. package/src/components/navigation-menu.tsx +34 -94
  201. package/src/components/pagination.tsx +28 -34
  202. package/src/components/popover.tsx +66 -35
  203. package/src/components/progress-circle.tsx +7 -25
  204. package/src/components/progress.tsx +3 -16
  205. package/src/components/radio-cards.tsx +8 -27
  206. package/src/components/radio-group.tsx +7 -27
  207. package/src/components/radio.tsx +3 -24
  208. package/src/components/resizable.tsx +5 -26
  209. package/src/components/scroll-area.tsx +12 -32
  210. package/src/components/select.tsx +37 -60
  211. package/src/components/separator.tsx +4 -18
  212. package/src/components/sheet.tsx +37 -74
  213. package/src/components/sidebar.tsx +47 -177
  214. package/src/components/skeleton.tsx +1 -3
  215. package/src/components/slider.tsx +7 -36
  216. package/src/components/sonner.tsx +16 -6
  217. package/src/components/spinner.tsx +6 -15
  218. package/src/components/switch.tsx +8 -30
  219. package/src/components/table.tsx +18 -35
  220. package/src/components/tabs.tsx +16 -34
  221. package/src/components/textarea.tsx +1 -15
  222. package/src/components/toggle-group.tsx +34 -38
  223. package/src/components/toggle.tsx +4 -13
  224. package/src/components/tooltip.tsx +11 -37
  225. package/src/css/foundation/base.css +74 -0
  226. package/src/css/foundation/motion.css +69 -0
  227. package/src/css/foundation/source.css +10 -0
  228. package/src/css/foundation/tokens.css +107 -0
  229. package/src/css/foundation/variants.css +121 -0
  230. package/src/css/preset.css +13 -214
  231. package/src/css/style.css +9 -1
  232. package/src/css/{amber.css → themes/amber.css} +29 -0
  233. package/src/css/{blue.css → themes/blue.css} +29 -0
  234. package/src/css/{cyan.css → themes/cyan.css} +29 -0
  235. package/src/css/{emerald.css → themes/emerald.css} +29 -0
  236. package/src/css/{fuchsia.css → themes/fuchsia.css} +29 -0
  237. package/src/css/{gray.css → themes/gray.css} +29 -0
  238. package/src/css/{green.css → themes/green.css} +29 -0
  239. package/src/css/{indigo.css → themes/indigo.css} +29 -0
  240. package/src/css/{lime.css → themes/lime.css} +29 -0
  241. package/src/css/{neutral.css → themes/neutral.css} +29 -0
  242. package/src/css/{orange.css → themes/orange.css} +29 -0
  243. package/src/css/{pink.css → themes/pink.css} +29 -0
  244. package/src/css/{purple.css → themes/purple.css} +29 -0
  245. package/src/css/{red.css → themes/red.css} +29 -0
  246. package/src/css/{rose.css → themes/rose.css} +29 -0
  247. package/src/css/{sky.css → themes/sky.css} +29 -0
  248. package/src/css/{slate.css → themes/slate.css} +29 -0
  249. package/src/css/{stone.css → themes/stone.css} +29 -0
  250. package/src/css/{teal.css → themes/teal.css} +29 -0
  251. package/src/css/{violet.css → themes/violet.css} +29 -0
  252. package/src/css/{yellow.css → themes/yellow.css} +29 -0
  253. package/src/css/{zinc.css → themes/zinc.css} +29 -0
  254. package/src/hooks/use-animated-value.ts +1 -7
  255. package/src/hooks/use-copy-to-clipboard.ts +1 -6
  256. package/src/hooks/use-is-mobile.ts +0 -2
  257. package/src/hooks/use-media-query.ts +0 -2
  258. package/src/hooks/use-mutation-observer.ts +0 -3
  259. package/src/hooks/use-pagination.ts +0 -2
  260. package/src/index.ts +39 -80
  261. package/src/primitives/checkbox-group.tsx +25 -39
  262. package/src/primitives/input-number.tsx +17 -63
  263. package/src/primitives/input.tsx +8 -24
  264. package/src/primitives/progress-circle.tsx +13 -43
  265. package/src/variants/alert.ts +3 -14
  266. package/src/variants/badge.ts +8 -35
  267. package/src/variants/button-group.ts +5 -18
  268. package/src/variants/button.ts +21 -58
  269. package/src/variants/empty.ts +2 -11
  270. package/src/variants/field.ts +6 -19
  271. package/src/variants/input-group.ts +12 -64
  272. package/src/variants/input-number.ts +65 -0
  273. package/src/variants/item.ts +10 -32
  274. package/src/variants/navigation-menu.ts +1 -8
  275. package/src/variants/progress-circle.ts +1 -2
  276. package/src/variants/scroll-area.ts +3 -9
  277. package/src/variants/separator.ts +6 -7
  278. package/src/variants/sheet.ts +6 -39
  279. package/src/variants/sidebar.ts +7 -27
  280. package/src/variants/tabs.ts +34 -0
  281. package/src/variants/toggle.ts +9 -28
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,23 +9,7 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const inputGroupVariants = tv({
13
- base: [
14
- "group/input-group relative flex h-9 w-full min-w-0 items-center",
15
- "rounded-lg border border-input shadow-xs outline-none",
16
- "transition-[color,box-shadow]",
17
- "motion-reduce:transition-none",
18
- "dark:bg-input/30",
19
- "has-[>textarea]:h-auto",
20
- "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col",
21
- "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col",
22
- "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50",
23
- "has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-destructive/20",
24
- "dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
25
- "has-[>[data-align=block-end]]:[&>[data-slot=input-group-control]]:pt-3",
26
- "has-[>[data-align=block-start]]:[&>[data-slot=input-group-control]]:pb-3",
27
- "has-[>[data-align=inline-end]]:[&>[data-slot=input-group-control]]:pr-2",
28
- "has-[>[data-align=inline-start]]:[&>[data-slot=input-group-control]]:pl-2",
29
- ],
12
+ base: "group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pe-1.5 has-[>[data-align=inline-start]]:[&>input]:ps-1.5",
30
13
  });
31
14
 
32
15
  /* -----------------------------------------------------------------------------
@@ -37,41 +20,17 @@ const inputGroupVariants = tv({
37
20
  * @since 0.3.16-canary.0
38
21
  */
39
22
  const inputGroupAddonVariants = tv({
40
- base: [
41
- "flex h-auto items-center justify-center gap-2 py-1.5",
42
- "text-sm font-medium text-muted-foreground",
43
- "cursor-text select-none",
44
- "group-data-disabled/input-group:opacity-50",
45
- "[&>kbd]:rounded-[calc(var(--radius)-5px)]",
46
- "[&>svg:not([class*='size-'])]:size-4",
47
- ],
23
+ base: "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-disabled/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-3px)] [&>svg:not([class*='size-'])]:size-4",
48
24
  defaultVariants: {
49
25
  align: "inline-start",
50
26
  },
51
27
  variants: {
52
28
  align: {
53
- "block-end": [
54
- "order-last w-full justify-start px-3 pb-3",
55
- "group-has-[>input]/input-group:pb-2.5",
56
- "[.border-t]:pt-3",
57
- ],
58
- "block-start": [
59
- "order-first w-full justify-start px-3 pt-3",
60
- "group-has-[>input]/input-group:pt-2.5",
61
- "[.border-b]:pb-3",
62
- ],
63
- "inline-end": [
64
- "order-last",
65
- "pr-3",
66
- "has-[>button]:mr-[-0.45rem]",
67
- "has-[>kbd]:mr-[-0.35rem]",
68
- ],
69
- "inline-start": [
70
- "order-first",
71
- "pl-3",
72
- "has-[>button]:ml-[-0.45rem]",
73
- "has-[>kbd]:ml-[-0.35rem]",
74
- ],
29
+ "block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2",
30
+ "block-start":
31
+ "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
32
+ "inline-end": "order-last pe-2 has-[>button]:-me-1 has-[>kbd]:me-[-0.15rem]",
33
+ "inline-start": "order-first ps-2 has-[>button]:-ms-1 has-[>kbd]:ms-[-0.15rem]",
75
34
  },
76
35
  },
77
36
  });
@@ -84,27 +43,16 @@ const inputGroupAddonVariants = tv({
84
43
  * @since 0.3.16-canary.0
85
44
  */
86
45
  const inputGroupButtonVariants = tv({
87
- base: [
88
- "flex items-center gap-2",
89
- "shadow-none",
90
- "text-sm",
91
- "[&>svg:not([class*='size-'])]:size-4",
92
- ],
46
+ base: "flex items-center gap-2 text-sm shadow-none",
93
47
  defaultVariants: {
94
48
  size: "xs",
95
49
  },
96
50
  variants: {
97
51
  size: {
98
- "icon-xs": ["size-6 p-0", "rounded-[calc(var(--radius)-5px)]", "has-[>svg]:p-0"],
99
- "icon-sm": ["size-8 p-0", "has-[>svg]:p-0"],
100
-
101
- xs: [
102
- "h-6 gap-1 px-2",
103
- "rounded-[calc(var(--radius)-5px)]",
104
- "has-[>svg]:px-2",
105
- "[&>svg]:size-3.5",
106
- ],
107
- sm: ["h-8 gap-1.5 px-2.5", "rounded-md", "has-[>svg]:px-2.5"],
52
+ "icon-xs": "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
53
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
54
+ sm: "",
55
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
108
56
  },
109
57
  },
110
58
  });
@@ -0,0 +1,65 @@
1
+ import type { VariantProps } from "#/lib/utils";
2
+ import { tv } from "#/lib/utils";
3
+
4
+ /* -----------------------------------------------------------------------------
5
+ * Variant: InputNumber
6
+ * -------------------------------------------------------------------------- */
7
+
8
+ /**
9
+ * @since 0.3.16-canary.0
10
+ */
11
+ const inputNumberVariants = tv({
12
+ defaultVariants: {
13
+ variant: "stepper",
14
+ },
15
+ slots: {
16
+ /**
17
+ * Split layout: trailing increment button (always on the inline end).
18
+ */
19
+ incrementButton:
20
+ "order-last h-full w-9 shrink-0 rounded-none rounded-e-[calc(var(--radius-md)-1px)] border-s border-s-input text-muted-foreground group-focus-within/input-number:border-s-ring group-has-aria-invalid/input-number:border-s-destructive focus-visible:bg-ring/50 focus-visible:ring-0 group-has-aria-invalid/input-number:focus-visible:bg-destructive/20 dark:group-has-aria-invalid/input-number:focus-visible:bg-destructive/40",
21
+ /**
22
+ * Split layout: leading decrement button (always on the inline start).
23
+ */
24
+ decrementButton:
25
+ "order-first h-full w-9 shrink-0 rounded-none rounded-s-[calc(var(--radius-md)-1px)] border-e border-e-input text-muted-foreground group-focus-within/input-number:border-e-ring group-has-aria-invalid/input-number:border-e-destructive focus-visible:bg-ring/50 focus-visible:ring-0 group-has-aria-invalid/input-number:focus-visible:bg-destructive/20 dark:group-has-aria-invalid/input-number:focus-visible:bg-destructive/40",
26
+ /**
27
+ * Editable numeric input.
28
+ */
29
+ field:
30
+ "h-full min-w-0 flex-1 bg-transparent px-2.5 py-1 outline-hidden selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed",
31
+ /**
32
+ * Outer container.
33
+ */
34
+ root: "group/input-number relative flex h-9 w-full min-w-0 items-center overflow-hidden rounded-md border border-input bg-transparent text-base transition-[color,box-shadow] not-has-disabled:shadow-xs focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 has-disabled:opacity-50 has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 motion-reduce:transition-none md:text-sm dark:bg-input/30 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40 [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
35
+ /**
36
+ * Stepper layout: stacked chevron column on the trailing edge.
37
+ */
38
+ stepper:
39
+ "order-last grid h-full w-8 shrink-0 divide-y divide-input border-s border-s-input transition-colors group-focus-within/input-number:divide-ring group-focus-within/input-number:border-s-ring group-has-aria-invalid/input-number:divide-destructive group-has-aria-invalid/input-number:border-s-destructive motion-reduce:transition-none *:[button]:focus-visible:bg-ring/50 *:[button]:focus-visible:ring-0 group-has-aria-invalid/input-number:*:[button]:focus-visible:bg-destructive/20 dark:group-has-aria-invalid/input-number:*:[button]:focus-visible:bg-destructive/40",
40
+ /**
41
+ * Stepper layout: individual chevron button (shared by increment/decrement).
42
+ */
43
+ stepperButton: "h-auto min-w-0 rounded-none px-0 text-muted-foreground",
44
+ },
45
+ variants: {
46
+ variant: {
47
+ split: {
48
+ field: "text-center tabular-nums",
49
+ },
50
+ stepper: {},
51
+ },
52
+ },
53
+ });
54
+
55
+ /**
56
+ * @since 0.3.16-canary.0
57
+ */
58
+ type InputNumberVariants = VariantProps<typeof inputNumberVariants>;
59
+
60
+ /* -----------------------------------------------------------------------------
61
+ * Exports
62
+ * -------------------------------------------------------------------------- */
63
+
64
+ export { inputNumberVariants };
65
+ export type { InputNumberVariants };
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,29 +9,20 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const itemVariants = tv({
13
- base: [
14
- "group/item flex flex-wrap items-center",
15
- "rounded-lg border border-transparent outline-hidden",
16
- "text-sm",
17
- "transition-colors duration-100",
18
- "motion-reduce:transition-none motion-reduce:duration-0",
19
- "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
20
- "[a]:transition-colors",
21
- "[a]:motion-reduce:transition-none",
22
- "[a]:hover:bg-accent/50",
23
- ],
12
+ base: "group/item flex w-full flex-wrap items-center rounded-md border text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-muted",
24
13
  defaultVariants: {
25
14
  size: "default",
26
15
  variant: "default",
27
16
  },
28
17
  variants: {
29
18
  size: {
30
- default: ["gap-4", "p-4"],
31
- sm: ["gap-2.5", "px-4 py-3"],
19
+ default: "gap-3.5 px-4 py-3.5",
20
+ sm: "gap-2.5 px-3 py-2.5",
21
+ xs: "gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0",
32
22
  },
33
23
  variant: {
34
- default: "bg-transparent",
35
- muted: "bg-muted/50",
24
+ default: "border-transparent",
25
+ muted: "border-transparent bg-muted/50",
36
26
  outline: "border-border",
37
27
  },
38
28
  },
@@ -46,28 +36,16 @@ const itemVariants = tv({
46
36
  * @since 0.3.16-canary.0
47
37
  */
48
38
  const itemMediaVariants = tv({
49
- base: [
50
- "flex shrink-0 items-center justify-center gap-2",
51
- "group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start",
52
- "[&_svg]:pointer-events-none",
53
- ],
39
+ base: "flex shrink-0 items-center justify-center gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start [&_svg]:pointer-events-none",
54
40
  defaultVariants: {
55
41
  variant: "default",
56
42
  },
57
43
  variants: {
58
44
  variant: {
59
45
  default: "bg-transparent",
60
- icon: [
61
- "size-8 shrink-0",
62
- "rounded-md border",
63
- "bg-muted",
64
- "[&_svg:not([class*='size-'])]:size-4",
65
- ],
66
- image: [
67
- "size-10 shrink-0 overflow-hidden",
68
- "rounded-md",
69
- "[&_img]:size-full [&_img]:object-cover",
70
- ],
46
+ icon: "[&_svg:not([class*='size-'])]:size-4",
47
+ image:
48
+ "size-10 overflow-hidden rounded-sm group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 [&_img]:size-full [&_img]:object-cover",
71
49
  },
72
50
  },
73
51
  });
@@ -1,9 +1,6 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
- import { buttonVariants } from "#/variants/button";
6
-
7
4
  /* -----------------------------------------------------------------------------
8
5
  * Style: NavigationMenuTrigger
9
6
  * -------------------------------------------------------------------------- */
@@ -12,11 +9,7 @@ import { buttonVariants } from "#/variants/button";
12
9
  * @since 0.3.16-canary.0
13
10
  */
14
11
  const navigationMenuTriggerVariants = tv({
15
- base: buttonVariants({
16
- className:
17
- "data-open:bg-secondary/50 data-open:text-secondary-foreground group/navigation-menu-trigger focus-visible:bg-secondary dark:hover:not-disabled:bg-secondary",
18
- variant: "ghost",
19
- }),
12
+ base: "group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted data-open:bg-muted/50 data-open:hover:bg-muted data-open:focus:bg-muted",
20
13
  });
21
14
 
22
15
  /**
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -13,7 +12,7 @@ const progressCircleVariants = tv({
13
12
  defaultVariants: { size: "md", thickness: "regular", variant: "default" },
14
13
  slots: {
15
14
  indicator: "origin-center",
16
- label: ["absolute flex items-center justify-center", "inset-0", "text-xs font-medium"],
15
+ label: "absolute inset-0 flex items-center justify-center text-xs font-medium",
17
16
  root: "relative inline-flex items-center justify-center",
18
17
  svg: "size-full",
19
18
  track: "origin-center",
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,12 +9,7 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const scrollAreaScrollbarVariants = tv({
13
- base: [
14
- "flex",
15
- "p-px",
16
- "touch-none transition-colors select-none",
17
- "motion-reduce:transition-none motion-reduce:duration-0",
18
- ],
12
+ base: "flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-s data-vertical:border-s-transparent",
19
13
  compoundVariants: [
20
14
  {
21
15
  className: "w-1.5",
@@ -54,8 +48,8 @@ const scrollAreaScrollbarVariants = tv({
54
48
  },
55
49
  variants: {
56
50
  orientation: {
57
- horizontal: ["w-full flex-col", "border-t border-t-transparent"],
58
- vertical: ["h-full flex-row", "border-l border-l-transparent"],
51
+ horizontal: "",
52
+ vertical: "",
59
53
  },
60
54
  size: {
61
55
  none: "",
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,20 +9,20 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const separatorVariants = tv({
13
- base: ["relative flex shrink-0 items-center", "bg-border"],
12
+ base: "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
14
13
  defaultVariants: {
15
14
  align: "center",
16
15
  orientation: "horizontal",
17
16
  },
18
17
  variants: {
19
18
  align: {
20
- center: "justify-center",
21
- end: "justify-end",
22
- start: "justify-start",
19
+ center: "relative flex items-center justify-center",
20
+ end: "relative flex items-center justify-end",
21
+ start: "relative flex items-center justify-start",
23
22
  },
24
23
  orientation: {
25
- horizontal: "h-px w-full",
26
- vertical: "h-full w-px flex-col",
24
+ horizontal: "",
25
+ vertical: "",
27
26
  },
28
27
  },
29
28
  });
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,49 +9,17 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const sheetContentVariants = tv({
13
- base: [
14
- "fixed z-50 flex flex-col overflow-auto",
15
- "bg-background shadow-lg",
16
- "ease-ui data-open:animate-in data-open:animation-duration-500",
17
- "data-closed:animate-out data-closed:animation-duration-500",
18
- "motion-reduce:animate-none motion-reduce:transition-none motion-reduce:duration-0",
19
- ],
12
+ base: "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition ease-ui data-open:animate-in data-open:animation-duration-panel-in data-open:fade-in-0 data-closed:animate-out data-closed:ease-exit data-closed:animation-duration-panel-out data-closed:fade-out-0",
20
13
  defaultVariants: {
21
14
  side: "right",
22
15
  },
23
16
  variants: {
24
17
  side: {
25
- bottom: [
26
- "max-h-[80dvh]",
27
- "inset-x-0 bottom-0",
28
- "rounded-t-2xl border-t",
29
- "pb-[env(safe-area-inset-bottom)]",
30
- "data-open:slide-in-from-bottom",
31
- "data-closed:slide-out-to-bottom",
32
- ],
33
- left: [
34
- "h-full w-3/4",
35
- "inset-y-0 left-0",
36
- "border-r",
37
- "sm:max-w-sm",
38
- "data-open:slide-in-from-left",
39
- "data-closed:slide-out-to-left",
40
- ],
41
- right: [
42
- "h-full w-3/4",
43
- "inset-y-0 right-0",
44
- "border-l",
45
- "sm:max-w-sm",
46
- "data-open:slide-in-from-right",
47
- "data-closed:slide-out-to-right",
48
- ],
49
- top: [
50
- "max-h-[80vh]",
51
- "inset-x-0 top-0",
52
- "border-b",
53
- "data-open:slide-in-from-top",
54
- "data-closed:slide-out-to-top",
55
- ],
18
+ bottom: "inset-x-0 bottom-0 h-auto border-t data-open:slide-in-from-bottom-10 data-closed:slide-out-to-bottom-10",
19
+ left: "inset-y-0 start-0 h-full w-3/4 border-e sm:max-w-sm data-open:slide-in-from-left-10 data-closed:slide-out-to-left-10",
20
+ right:
21
+ "inset-y-0 end-0 h-full w-3/4 border-s sm:max-w-sm data-open:slide-in-from-right-10 data-closed:slide-out-to-right-10",
22
+ top: "inset-x-0 top-0 h-auto border-b data-open:slide-in-from-top-10 data-closed:slide-out-to-top-10",
56
23
  },
57
24
  },
58
25
  });
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,40 +9,21 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const sidebarMenuButtonVariants = tv({
13
- base: [
14
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden p-2",
15
- "rounded-md ring-sidebar-ring outline-hidden",
16
- "text-left text-sm",
17
- "transition-[width,height,padding]",
18
- "motion-reduce:transition-none motion-reduce:duration-0",
19
- "group-has-data-[sidebar=menu-action]/menu-item:pr-8",
20
- "group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2!",
21
- "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
22
- "focus-visible:ring-3",
23
- "active:bg-sidebar-accent active:text-sidebar-accent-foreground",
24
- "disabled:pointer-events-none disabled:opacity-50",
25
- "aria-disabled:pointer-events-none aria-disabled:opacity-50",
26
- "data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground",
27
- "data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground",
28
- "[&>span:last-child]:truncate",
29
- "[&>svg]:size-4 [&>svg]:shrink-0",
30
- ],
12
+ base: "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-start text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pe-8 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:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
31
13
  defaultVariants: {
32
- size: "md",
14
+ size: "default",
33
15
  variant: "default",
34
16
  },
35
17
  variants: {
36
18
  size: {
37
- sm: ["h-7", "text-xs"],
38
- md: ["h-8", "text-sm"],
39
- lg: ["h-12 text-sm", "group-data-[collapsible=icon]:p-0!"],
19
+ default: "h-8 text-sm",
20
+ sm: "h-7 text-xs",
21
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
40
22
  },
41
23
  variant: {
42
24
  default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
43
- outline: [
44
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))]",
45
- "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
46
- ],
25
+ outline:
26
+ "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)]",
47
27
  },
48
28
  },
49
29
  });
@@ -0,0 +1,34 @@
1
+ import type { VariantProps } from "#/lib/utils";
2
+ import { tv } from "#/lib/utils";
3
+
4
+ /* -----------------------------------------------------------------------------
5
+ * Variant: TabsList
6
+ * -------------------------------------------------------------------------- */
7
+
8
+ /**
9
+ * @since 0.3.16-canary.0
10
+ */
11
+ const tabsListVariants = tv({
12
+ base: "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-0.75 text-muted-foreground group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
13
+ defaultVariants: {
14
+ variant: "default",
15
+ },
16
+ variants: {
17
+ variant: {
18
+ default: "bg-muted",
19
+ line: "gap-1 bg-transparent",
20
+ },
21
+ },
22
+ });
23
+
24
+ /**
25
+ * @since 0.3.16-canary.0
26
+ */
27
+ type TabsListVariants = VariantProps<typeof tabsListVariants>;
28
+
29
+ /* -----------------------------------------------------------------------------
30
+ * Exports
31
+ * -------------------------------------------------------------------------- */
32
+
33
+ export { tabsListVariants };
34
+ export type { TabsListVariants };
@@ -1,5 +1,4 @@
1
1
  import type { VariantProps } from "#/lib/utils";
2
-
3
2
  import { tv } from "#/lib/utils";
4
3
 
5
4
  /* -----------------------------------------------------------------------------
@@ -10,40 +9,22 @@ import { tv } from "#/lib/utils";
10
9
  * @since 0.3.16-canary.0
11
10
  */
12
11
  const toggleVariants = tv({
13
- base: [
14
- "inline-flex items-center justify-center gap-2",
15
- "rounded-lg outline-none",
16
- "text-sm font-medium whitespace-nowrap",
17
- "transition-[color,background-color,box-shadow] duration-150 ease-snappy",
18
- "motion-reduce:transition-none motion-reduce:duration-0",
19
- "active:not-disabled:translate-y-px",
20
- "hover:bg-muted hover:text-muted-foreground",
21
- "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
22
- "disabled:pointer-events-none disabled:opacity-50",
23
- "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
24
- "data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
25
- "dark:aria-invalid:ring-destructive/40",
26
- "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
27
- ],
12
+ base: "group/toggle inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
13
+ defaultVariants: {
14
+ size: "default",
15
+ variant: "default",
16
+ },
28
17
  variants: {
29
18
  size: {
30
- default: ["h-9 min-w-9", "px-2"],
31
- lg: ["h-10 min-w-10", "px-2.5"],
32
- sm: ["h-8 min-w-8", "px-1.5"],
19
+ default: "h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
20
+ sm: "h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5",
21
+ lg: "h-10 min-w-10 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
33
22
  },
34
23
  variant: {
35
24
  default: "bg-transparent",
36
- outline: [
37
- "border border-input",
38
- "bg-transparent shadow-xs",
39
- "hover:bg-accent hover:text-accent-foreground",
40
- ],
25
+ outline: "border border-input bg-transparent shadow-xs hover:bg-muted",
41
26
  },
42
27
  },
43
- defaultVariants: {
44
- size: "default",
45
- variant: "default",
46
- },
47
28
  });
48
29
 
49
30
  /**