@inspirare/design-system 0.0.22 → 0.0.24

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 (297) hide show
  1. package/README.md +82 -61
  2. package/dist/book-logo-filled.svg +55 -0
  3. package/dist/components/ui/accessibility-improvements.js +26 -23
  4. package/dist/components/ui/accordion.js +34 -24
  5. package/dist/components/ui/alert-dialog.js +91 -57
  6. package/dist/components/ui/alert.js +38 -26
  7. package/dist/components/ui/aspect-ratio.js +11 -3
  8. package/dist/components/ui/avatar.js +30 -8
  9. package/dist/components/ui/badge.js +20 -14
  10. package/dist/components/ui/breadcrumb.js +69 -56
  11. package/dist/components/ui/button-group.js +17 -13
  12. package/dist/components/ui/button.js +19 -15
  13. package/dist/components/ui/calendar.js +63 -59
  14. package/dist/components/ui/card.js +11 -9
  15. package/dist/components/ui/carousel.js +70 -75
  16. package/dist/components/ui/chart.js +75 -72
  17. package/dist/components/ui/checkbox.js +4 -5
  18. package/dist/components/ui/collapsible.js +12 -14
  19. package/dist/components/ui/color-picker.js +60 -80
  20. package/dist/components/ui/combobox.js +153 -33
  21. package/dist/components/ui/command.js +50 -48
  22. package/dist/components/ui/context-menu.js +129 -68
  23. package/dist/components/ui/dialog.js +65 -60
  24. package/dist/components/ui/drawer.js +81 -40
  25. package/dist/components/ui/dropdown-menu.js +100 -87
  26. package/dist/components/ui/empty.js +7 -6
  27. package/dist/components/ui/field.js +44 -47
  28. package/dist/components/ui/form.js +22 -23
  29. package/dist/components/ui/hover-card.js +14 -11
  30. package/dist/components/ui/input-group.js +16 -13
  31. package/dist/components/ui/input-otp.js +37 -32
  32. package/dist/components/ui/input.js +9 -7
  33. package/dist/components/ui/item.js +42 -36
  34. package/dist/components/ui/kbd.js +2 -1
  35. package/dist/components/ui/label.js +6 -7
  36. package/dist/components/ui/menubar.js +124 -93
  37. package/dist/components/ui/navigation-menu.js +79 -54
  38. package/dist/components/ui/pagination.js +78 -58
  39. package/dist/components/ui/popover.js +35 -16
  40. package/dist/components/ui/progress.js +37 -13
  41. package/dist/components/ui/radio-group.js +14 -14
  42. package/dist/components/ui/resizable.js +24 -15
  43. package/dist/components/ui/scroll-area.js +29 -11
  44. package/dist/components/ui/select.js +98 -56
  45. package/dist/components/ui/separator.js +5 -7
  46. package/dist/components/ui/sheet.js +47 -42
  47. package/dist/components/ui/sidebar.js +279 -248
  48. package/dist/components/ui/skeleton.js +4 -40
  49. package/dist/components/ui/slider.js +27 -29
  50. package/dist/components/ui/sonner.js +27 -10
  51. package/dist/components/ui/spinner.js +2 -0
  52. package/dist/components/ui/switch.js +3 -4
  53. package/dist/components/ui/table.js +6 -6
  54. package/dist/components/ui/tabs.js +45 -22
  55. package/dist/components/ui/textarea.js +3 -2
  56. package/dist/components/ui/theme-toggle.js +38 -41
  57. package/dist/components/ui/toggle-group.js +30 -21
  58. package/dist/components/ui/toggle.js +8 -9
  59. package/dist/components/ui/tooltip.js +28 -23
  60. package/dist/index.css +1 -1
  61. package/dist/index.d.ts +446 -468
  62. package/dist/index.js +58 -58
  63. package/package.json +42 -41
  64. package/src/App.tsx +28 -34
  65. package/src/components/branding/assets/book-logo-filled.svg +55 -0
  66. package/src/components/branding/logo/logo.tsx +56 -0
  67. package/src/components/ui/accessibility-improvements.stories.tsx +18 -0
  68. package/src/components/ui/accessibility-improvements.test.tsx +13 -0
  69. package/src/components/ui/accessibility-improvements.tsx +16 -6
  70. package/src/components/ui/accordion.stories.tsx +19 -0
  71. package/src/components/ui/accordion.test.tsx +14 -0
  72. package/src/components/ui/accordion.tsx +28 -20
  73. package/src/components/ui/alert-dialog.stories.tsx +19 -0
  74. package/src/components/ui/alert-dialog.test.tsx +14 -0
  75. package/src/components/ui/alert-dialog.tsx +159 -123
  76. package/src/components/ui/alert.stories.tsx +19 -0
  77. package/src/components/ui/alert.test.tsx +14 -0
  78. package/src/components/ui/alert.tsx +60 -41
  79. package/src/components/ui/aspect-ratio.stories.tsx +19 -0
  80. package/src/components/ui/aspect-ratio.test.tsx +14 -0
  81. package/src/components/ui/aspect-ratio.tsx +19 -2
  82. package/src/components/ui/attachment.stories.tsx +19 -0
  83. package/src/components/ui/attachment.test.tsx +14 -0
  84. package/src/components/ui/attachment.tsx +209 -0
  85. package/src/components/ui/avatar.stories.tsx +19 -0
  86. package/src/components/ui/avatar.test.tsx +14 -0
  87. package/src/components/ui/avatar.tsx +73 -17
  88. package/src/components/ui/badge.stories.tsx +19 -0
  89. package/src/components/ui/badge.test.tsx +14 -0
  90. package/src/components/ui/badge.tsx +33 -25
  91. package/src/components/ui/breadcrumb.stories.tsx +19 -0
  92. package/src/components/ui/breadcrumb.test.tsx +14 -0
  93. package/src/components/ui/breadcrumb.tsx +98 -86
  94. package/src/components/ui/bubble.stories.tsx +19 -0
  95. package/src/components/ui/bubble.test.tsx +14 -0
  96. package/src/components/ui/bubble.tsx +130 -0
  97. package/src/components/ui/button-group.stories.tsx +19 -0
  98. package/src/components/ui/button-group.test.tsx +14 -0
  99. package/src/components/ui/button-group.tsx +26 -20
  100. package/src/components/ui/button.stories.tsx +19 -0
  101. package/src/components/ui/button.test.tsx +14 -0
  102. package/src/components/ui/button.tsx +30 -31
  103. package/src/components/ui/calendar.stories.tsx +19 -0
  104. package/src/components/ui/calendar.test.tsx +14 -0
  105. package/src/components/ui/calendar.tsx +28 -26
  106. package/src/components/ui/card.stories.tsx +19 -0
  107. package/src/components/ui/card.test.tsx +14 -0
  108. package/src/components/ui/card.tsx +30 -17
  109. package/src/components/ui/carousel.stories.tsx +19 -0
  110. package/src/components/ui/carousel.test.tsx +14 -0
  111. package/src/components/ui/carousel.tsx +115 -135
  112. package/src/components/ui/chart.stories.tsx +18 -0
  113. package/src/components/ui/chart.test.tsx +13 -0
  114. package/src/components/ui/chart.tsx +220 -216
  115. package/src/components/ui/checkbox.stories.tsx +19 -0
  116. package/src/components/ui/checkbox.test.tsx +14 -0
  117. package/src/components/ui/checkbox.tsx +7 -10
  118. package/src/components/ui/collapsible.stories.tsx +19 -0
  119. package/src/components/ui/collapsible.test.tsx +14 -0
  120. package/src/components/ui/collapsible.tsx +11 -26
  121. package/src/components/ui/color-picker.stories.tsx +19 -0
  122. package/src/components/ui/color-picker.test.tsx +14 -0
  123. package/src/components/ui/color-picker.tsx +36 -26
  124. package/src/components/ui/combobox.stories.tsx +19 -0
  125. package/src/components/ui/combobox.test.tsx +14 -0
  126. package/src/components/ui/combobox.tsx +281 -96
  127. package/src/components/ui/command.stories.tsx +19 -0
  128. package/src/components/ui/command.test.tsx +14 -0
  129. package/src/components/ui/command.tsx +59 -47
  130. package/src/components/ui/context-menu.stories.tsx +19 -0
  131. package/src/components/ui/context-menu.test.tsx +14 -0
  132. package/src/components/ui/context-menu.tsx +231 -160
  133. package/src/components/ui/dialog.stories.tsx +19 -0
  134. package/src/components/ui/dialog.test.tsx +14 -0
  135. package/src/components/ui/dialog.tsx +81 -72
  136. package/src/components/ui/direction.stories.tsx +19 -0
  137. package/src/components/ui/direction.test.tsx +14 -0
  138. package/src/components/ui/direction.tsx +6 -0
  139. package/src/components/ui/drawer.stories.tsx +19 -0
  140. package/src/components/ui/drawer.test.tsx +14 -0
  141. package/src/components/ui/drawer.tsx +143 -64
  142. package/src/components/ui/dropdown-menu.stories.tsx +19 -0
  143. package/src/components/ui/dropdown-menu.test.tsx +14 -0
  144. package/src/components/ui/dropdown-menu.tsx +199 -153
  145. package/src/components/ui/empty.stories.tsx +18 -0
  146. package/src/components/ui/empty.test.tsx +13 -0
  147. package/src/components/ui/empty.tsx +11 -9
  148. package/src/components/ui/field.stories.tsx +18 -0
  149. package/src/components/ui/field.test.tsx +13 -0
  150. package/src/components/ui/field.tsx +26 -32
  151. package/src/components/ui/form.stories.tsx +22 -0
  152. package/src/components/ui/form.test.tsx +15 -0
  153. package/src/components/ui/form.tsx +1 -2
  154. package/src/components/ui/hover-card.stories.tsx +19 -0
  155. package/src/components/ui/hover-card.test.tsx +14 -0
  156. package/src/components/ui/hover-card.tsx +34 -32
  157. package/src/components/ui/input-group.stories.tsx +18 -0
  158. package/src/components/ui/input-group.test.tsx +13 -0
  159. package/src/components/ui/input-group.tsx +21 -28
  160. package/src/components/ui/input-otp.stories.tsx +19 -0
  161. package/src/components/ui/input-otp.test.tsx +14 -0
  162. package/src/components/ui/input-otp.tsx +58 -42
  163. package/src/components/ui/input.stories.tsx +19 -0
  164. package/src/components/ui/input.test.tsx +14 -0
  165. package/src/components/ui/input.tsx +9 -8
  166. package/src/components/ui/item.stories.tsx +18 -0
  167. package/src/components/ui/item.test.tsx +13 -0
  168. package/src/components/ui/item.tsx +38 -28
  169. package/src/components/ui/kbd.stories.tsx +18 -0
  170. package/src/components/ui/kbd.test.tsx +13 -0
  171. package/src/components/ui/kbd.tsx +3 -3
  172. package/src/components/ui/label.stories.tsx +18 -0
  173. package/src/components/ui/label.test.tsx +13 -0
  174. package/src/components/ui/label.tsx +7 -11
  175. package/src/components/ui/marker.stories.tsx +19 -0
  176. package/src/components/ui/marker.test.tsx +14 -0
  177. package/src/components/ui/marker.tsx +73 -0
  178. package/src/components/ui/menubar.stories.tsx +19 -0
  179. package/src/components/ui/menubar.test.tsx +14 -0
  180. package/src/components/ui/menubar.tsx +226 -202
  181. package/src/components/ui/message-scroller.stories.tsx +19 -0
  182. package/src/components/ui/message-scroller.test.tsx +14 -0
  183. package/src/components/ui/message-scroller.tsx +131 -0
  184. package/src/components/ui/message.stories.tsx +19 -0
  185. package/src/components/ui/message.test.tsx +14 -0
  186. package/src/components/ui/message.tsx +94 -0
  187. package/src/components/ui/native-select.stories.tsx +18 -0
  188. package/src/components/ui/native-select.test.tsx +13 -0
  189. package/src/components/ui/native-select.tsx +63 -0
  190. package/src/components/ui/navigation-menu.stories.tsx +19 -0
  191. package/src/components/ui/navigation-menu.test.tsx +14 -0
  192. package/src/components/ui/navigation-menu.tsx +145 -103
  193. package/src/components/ui/pagination.stories.tsx +19 -0
  194. package/src/components/ui/pagination.test.tsx +14 -0
  195. package/src/components/ui/pagination.tsx +114 -83
  196. package/src/components/ui/popover.stories.tsx +19 -0
  197. package/src/components/ui/popover.test.tsx +14 -0
  198. package/src/components/ui/popover.tsx +68 -33
  199. package/src/components/ui/progress.stories.tsx +19 -0
  200. package/src/components/ui/progress.test.tsx +14 -0
  201. package/src/components/ui/progress.tsx +67 -15
  202. package/src/components/ui/questionnaire.stories.tsx +19 -0
  203. package/src/components/ui/questionnaire.test.tsx +14 -0
  204. package/src/components/ui/questionnaire.tsx +324 -0
  205. package/src/components/ui/radio-group.stories.tsx +19 -0
  206. package/src/components/ui/radio-group.test.tsx +14 -0
  207. package/src/components/ui/radio-group.tsx +15 -20
  208. package/src/components/ui/resizable.stories.tsx +19 -0
  209. package/src/components/ui/resizable.test.tsx +14 -0
  210. package/src/components/ui/resizable.tsx +37 -30
  211. package/src/components/ui/scroll-area.stories.tsx +19 -0
  212. package/src/components/ui/scroll-area.test.tsx +14 -0
  213. package/src/components/ui/scroll-area.tsx +41 -19
  214. package/src/components/ui/select.stories.tsx +19 -0
  215. package/src/components/ui/select.test.tsx +14 -0
  216. package/src/components/ui/select.tsx +145 -78
  217. package/src/components/ui/separator.stories.tsx +19 -0
  218. package/src/components/ui/separator.test.tsx +14 -0
  219. package/src/components/ui/separator.tsx +8 -11
  220. package/src/components/ui/sheet.stories.tsx +19 -0
  221. package/src/components/ui/sheet.test.tsx +14 -0
  222. package/src/components/ui/sheet.tsx +56 -71
  223. package/src/components/ui/sidebar.stories.tsx +18 -0
  224. package/src/components/ui/sidebar.test.tsx +13 -0
  225. package/src/components/ui/sidebar.tsx +469 -513
  226. package/src/components/ui/skeleton.stories.tsx +19 -0
  227. package/src/components/ui/skeleton.test.tsx +14 -0
  228. package/src/components/ui/skeleton.tsx +8 -114
  229. package/src/components/ui/slider.stories.tsx +19 -0
  230. package/src/components/ui/slider.test.tsx +14 -0
  231. package/src/components/ui/slider.tsx +31 -40
  232. package/src/components/ui/sonner.stories.tsx +19 -0
  233. package/src/components/ui/sonner.test.tsx +14 -0
  234. package/src/components/ui/sonner.tsx +39 -7
  235. package/src/components/ui/spinner.stories.tsx +18 -0
  236. package/src/components/ui/spinner.test.tsx +13 -0
  237. package/src/components/ui/spinner.tsx +3 -7
  238. package/src/components/ui/switch.stories.tsx +19 -0
  239. package/src/components/ui/switch.test.tsx +14 -0
  240. package/src/components/ui/switch.tsx +4 -7
  241. package/src/components/ui/table.stories.tsx +19 -0
  242. package/src/components/ui/table.test.tsx +14 -0
  243. package/src/components/ui/table.tsx +17 -17
  244. package/src/components/ui/tabs.stories.tsx +19 -0
  245. package/src/components/ui/tabs.test.tsx +14 -0
  246. package/src/components/ui/tabs.tsx +71 -31
  247. package/src/components/ui/textarea.stories.tsx +19 -0
  248. package/src/components/ui/textarea.test.tsx +14 -0
  249. package/src/components/ui/textarea.tsx +7 -5
  250. package/src/components/ui/theme-toggle.stories.tsx +18 -0
  251. package/src/components/ui/theme-toggle.test.tsx +13 -0
  252. package/src/components/ui/theme-toggle.tsx +35 -37
  253. package/src/components/ui/toggle-group.stories.tsx +19 -0
  254. package/src/components/ui/toggle-group.test.tsx +14 -0
  255. package/src/components/ui/toggle-group.tsx +41 -25
  256. package/src/components/ui/toggle.stories.tsx +19 -0
  257. package/src/components/ui/toggle.test.tsx +14 -0
  258. package/src/components/ui/toggle.tsx +17 -19
  259. package/src/components/ui/tooltip.stories.tsx +19 -0
  260. package/src/components/ui/tooltip.test.tsx +14 -0
  261. package/src/components/ui/tooltip.tsx +53 -44
  262. package/src/demo/AIDemo.tsx +50 -0
  263. package/src/demo/ButtonsDemo.tsx +41 -18
  264. package/src/demo/CalendarDemo.tsx +1 -1
  265. package/src/demo/FeedbackDemo.tsx +4 -6
  266. package/src/demo/FormsDemo.tsx +34 -11
  267. package/src/demo/NavigationDemo.tsx +38 -13
  268. package/src/demo/OverlaysDemo.tsx +22 -36
  269. package/src/demo/update-demos.js +82 -0
  270. package/src/index.css +66 -46
  271. package/src/lib/utils.ts +3 -3
  272. package/src/stories/Button.stories.ts +54 -0
  273. package/src/stories/Button.tsx +36 -0
  274. package/src/stories/Configure.mdx +388 -0
  275. package/src/stories/Header.stories.ts +34 -0
  276. package/src/stories/Header.tsx +55 -0
  277. package/src/stories/Page.stories.ts +33 -0
  278. package/src/stories/Page.tsx +73 -0
  279. package/src/stories/assets/accessibility.png +0 -0
  280. package/src/stories/assets/accessibility.svg +1 -0
  281. package/src/stories/assets/addon-library.png +0 -0
  282. package/src/stories/assets/assets.png +0 -0
  283. package/src/stories/assets/avif-test-image.avif +0 -0
  284. package/src/stories/assets/context.png +0 -0
  285. package/src/stories/assets/discord.svg +1 -0
  286. package/src/stories/assets/docs.png +0 -0
  287. package/src/stories/assets/figma-plugin.png +0 -0
  288. package/src/stories/assets/github.svg +1 -0
  289. package/src/stories/assets/share.png +0 -0
  290. package/src/stories/assets/styling.png +0 -0
  291. package/src/stories/assets/testing.png +0 -0
  292. package/src/stories/assets/theming.png +0 -0
  293. package/src/stories/assets/tutorials.svg +1 -0
  294. package/src/stories/assets/youtube.svg +1 -0
  295. package/src/stories/button.css +30 -0
  296. package/src/stories/header.css +32 -0
  297. package/src/stories/page.css +68 -0
@@ -1,8 +1,8 @@
1
- "use client";
1
+ "use client"
2
2
 
3
- import * as React from "react";
3
+ import * as React from "react"
4
4
 
5
- import { cn } from "@/lib/utils";
5
+ import { cn } from "@/lib/utils"
6
6
 
7
7
  function Table({ className, ...props }: React.ComponentProps<"table">) {
8
8
  return (
@@ -16,7 +16,7 @@ function Table({ className, ...props }: React.ComponentProps<"table">) {
16
16
  {...props}
17
17
  />
18
18
  </div>
19
- );
19
+ )
20
20
  }
21
21
 
22
22
  function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
@@ -26,7 +26,7 @@ function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
26
26
  className={cn("[&_tr]:border-b", className)}
27
27
  {...props}
28
28
  />
29
- );
29
+ )
30
30
  }
31
31
 
32
32
  function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
@@ -36,7 +36,7 @@ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
36
36
  className={cn("[&_tr:last-child]:border-0", className)}
37
37
  {...props}
38
38
  />
39
- );
39
+ )
40
40
  }
41
41
 
42
42
  function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
@@ -44,12 +44,12 @@ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
44
44
  <tfoot
45
45
  data-slot="table-footer"
46
46
  className={cn(
47
- "bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
47
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
48
48
  className
49
49
  )}
50
50
  {...props}
51
51
  />
52
- );
52
+ )
53
53
  }
54
54
 
55
55
  function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
@@ -57,12 +57,12 @@ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
57
57
  <tr
58
58
  data-slot="table-row"
59
59
  className={cn(
60
- "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
60
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
61
61
  className
62
62
  )}
63
63
  {...props}
64
64
  />
65
- );
65
+ )
66
66
  }
67
67
 
68
68
  function TableHead({ className, ...props }: React.ComponentProps<"th">) {
@@ -70,12 +70,12 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
70
70
  <th
71
71
  data-slot="table-head"
72
72
  className={cn(
73
- "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
73
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
74
74
  className
75
75
  )}
76
76
  {...props}
77
77
  />
78
- );
78
+ )
79
79
  }
80
80
 
81
81
  function TableCell({ className, ...props }: React.ComponentProps<"td">) {
@@ -83,12 +83,12 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
83
83
  <td
84
84
  data-slot="table-cell"
85
85
  className={cn(
86
- "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
86
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
87
87
  className
88
88
  )}
89
89
  {...props}
90
90
  />
91
- );
91
+ )
92
92
  }
93
93
 
94
94
  function TableCaption({
@@ -98,10 +98,10 @@ function TableCaption({
98
98
  return (
99
99
  <caption
100
100
  data-slot="table-caption"
101
- className={cn("text-muted-foreground mt-4 text-sm", className)}
101
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
102
102
  {...props}
103
103
  />
104
- );
104
+ )
105
105
  }
106
106
 
107
107
  export {
@@ -113,4 +113,4 @@ export {
113
113
  TableRow,
114
114
  TableCell,
115
115
  TableCaption,
116
- };
116
+ }
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from "./tabs";
3
+
4
+ const meta = {
5
+ title: 'Design System/Tabs',
6
+ parameters: { layout: 'centered' },
7
+ tags: ['autodocs'],
8
+ } satisfies Meta;
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <div className="p-4 w-full h-full flex items-center justify-center">
16
+ <Tabs defaultValue="account" className="w-[400px]"><TabsList><TabsTrigger value="account">Account</TabsTrigger><TabsTrigger value="password">Password</TabsTrigger></TabsList><TabsContent value="account">Make changes to your account here.</TabsContent><TabsContent value="password">Change your password here.</TabsContent></Tabs>
17
+ </div>
18
+ )
19
+ };
@@ -0,0 +1,14 @@
1
+ import { render } from '@testing-library/react';
2
+ import { axe } from 'jest-axe';
3
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from "./tabs";
4
+
5
+ describe('Tabs Accessibility', () => {
6
+ it('should have no accessibility violations in basic render', async () => {
7
+ const Wrapper = () => (
8
+ <Tabs defaultValue="account" className="w-[400px]"><TabsList><TabsTrigger value="account">Account</TabsTrigger><TabsTrigger value="password">Password</TabsTrigger></TabsList><TabsContent value="account">Make changes to your account here.</TabsContent><TabsContent value="password">Change your password here.</TabsContent></Tabs>
9
+ );
10
+ const { container } = render(<Wrapper />);
11
+ const results = await axe(container);
12
+ expect(results).toHaveNoViolations();
13
+ });
14
+ });
@@ -1,66 +1,106 @@
1
- "use client";
1
+ "use client"
2
+ import * as React from "react"
2
3
 
3
- import * as React from "react";
4
- import * as TabsPrimitive from "@radix-ui/react-tabs";
4
+ import { Tabs as TabsPrimitive } from "@base-ui/react/tabs"
5
+ import { cva, type VariantProps } from "class-variance-authority"
5
6
 
6
- import { cn } from "@/lib/utils";
7
+ import { cn } from "@/lib/utils"
7
8
 
8
9
  function Tabs({
9
10
  className,
11
+ orientation = "horizontal",
10
12
  ...props
11
- }: React.ComponentProps<typeof TabsPrimitive.Root>) {
13
+ }: TabsPrimitive.Root.Props) {
12
14
  return (
13
15
  <TabsPrimitive.Root
14
16
  data-slot="tabs"
15
- className={cn("flex flex-col gap-2", className)}
17
+ data-orientation={orientation}
18
+ className={cn(
19
+ "group/tabs flex gap-2 data-horizontal:flex-col",
20
+ className
21
+ )}
16
22
  {...props}
17
23
  />
18
- );
24
+ )
19
25
  }
20
26
 
27
+ const tabsListVariants = cva(
28
+ "group/tabs-list relative inline-flex items-center justify-center p-1 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
29
+ {
30
+ variants: {
31
+ variant: {
32
+ default: "bg-background/50 border border-border/40 rounded-lg backdrop-blur-md shadow-sm text-muted-foreground",
33
+ line: "gap-1 bg-transparent text-muted-foreground",
34
+ },
35
+ },
36
+ defaultVariants: {
37
+ variant: "default",
38
+ },
39
+ }
40
+ )
41
+
21
42
  function TabsList({
22
43
  className,
44
+ variant = "default",
23
45
  ...props
24
- }: React.ComponentProps<typeof TabsPrimitive.List>) {
46
+ }: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {
25
47
  return (
26
48
  <TabsPrimitive.List
27
49
  data-slot="tabs-list"
28
- className={cn(
29
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
30
- className
31
- )}
50
+ data-variant={variant}
51
+ className={cn(tabsListVariants({ variant }), className)}
32
52
  {...props}
33
- />
34
- );
53
+ >
54
+ {/* Indicador que desliza horizontalmente via CSS variables do Base UI.
55
+ É um único elemento posicionado absolutamente — sem mount/unmount,
56
+ sem layoutId, puramente CSS transition. */}
57
+ <TabsPrimitive.Indicator
58
+ className="absolute rounded-md bg-primary shadow-md transition-all duration-300 ease-[cubic-bezier(0.65,0,0.35,1)]"
59
+ style={{
60
+ left: "var(--active-tab-left)",
61
+ top: "var(--active-tab-top)",
62
+ width: "var(--active-tab-width)",
63
+ height: "var(--active-tab-height)",
64
+ }}
65
+ />
66
+ {props.children}
67
+ </TabsPrimitive.List>
68
+ )
35
69
  }
36
70
 
37
- function TabsTrigger({
38
- className,
39
- ...props
40
- }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
71
+ const TabsTrigger = React.forwardRef<
72
+ React.ElementRef<"button">,
73
+ TabsPrimitive.Tab.Props
74
+ >(({ className, children, ...props }, ref) => {
41
75
  return (
42
- <TabsPrimitive.Trigger
76
+ <TabsPrimitive.Tab
77
+ ref={ref}
43
78
  data-slot="tabs-trigger"
44
79
  className={cn(
45
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
80
+ "relative inline-flex flex-1 md:flex-none items-center justify-center gap-1.5 rounded-md px-3 sm:px-6 py-2.5 text-xs sm:text-sm font-semibold font-[family-name:var(--font-sans)] whitespace-nowrap transition-colors duration-300 z-10 cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
81
+ "text-muted-foreground hover:text-foreground hover:bg-muted/50",
82
+ "data-active:text-primary-foreground data-active:hover:bg-transparent",
83
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring",
46
84
  className
47
85
  )}
48
86
  {...props}
49
- />
50
- );
51
- }
87
+ >
88
+ <span className="relative z-20 flex items-center justify-center gap-1.5">
89
+ {children}
90
+ </span>
91
+ </TabsPrimitive.Tab>
92
+ )
93
+ })
94
+ TabsTrigger.displayName = "TabsTrigger"
52
95
 
53
- function TabsContent({
54
- className,
55
- ...props
56
- }: React.ComponentProps<typeof TabsPrimitive.Content>) {
96
+ function TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {
57
97
  return (
58
- <TabsPrimitive.Content
98
+ <TabsPrimitive.Panel
59
99
  data-slot="tabs-content"
60
- className={cn("flex-1 outline-none", className)}
100
+ className={cn("flex-1 text-sm outline-none", className)}
61
101
  {...props}
62
102
  />
63
- );
103
+ )
64
104
  }
65
105
 
66
- export { Tabs, TabsList, TabsTrigger, TabsContent };
106
+ export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Textarea } from "./textarea";
3
+
4
+ const meta = {
5
+ title: 'Design System/Textarea',
6
+ parameters: { layout: 'centered' },
7
+ tags: ['autodocs'],
8
+ } satisfies Meta;
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <div className="p-4 w-full h-full flex items-center justify-center">
16
+ <Textarea placeholder="Type your message here." />
17
+ </div>
18
+ )
19
+ };
@@ -0,0 +1,14 @@
1
+ import { render } from '@testing-library/react';
2
+ import { axe } from 'jest-axe';
3
+ import { Textarea } from "./textarea";
4
+
5
+ describe('Textarea Accessibility', () => {
6
+ it('should have no accessibility violations in basic render', async () => {
7
+ const Wrapper = () => (
8
+ <Textarea placeholder="Type your message here." />
9
+ );
10
+ const { container } = render(<Wrapper />);
11
+ const results = await axe(container);
12
+ expect(results).toHaveNoViolations();
13
+ });
14
+ });
@@ -1,18 +1,20 @@
1
- import * as React from "react";
1
+ "use client"
2
2
 
3
- import { cn } from "@/lib/utils";
3
+ import * as React from "react"
4
+
5
+ import { cn } from "@/lib/utils"
4
6
 
5
7
  function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
8
  return (
7
9
  <textarea
8
10
  data-slot="textarea"
9
11
  className={cn(
10
- "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+ "flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
11
13
  className
12
14
  )}
13
15
  {...props}
14
16
  />
15
- );
17
+ )
16
18
  }
17
19
 
18
- export { Textarea };
20
+ export { Textarea }
@@ -0,0 +1,18 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ const meta = {
4
+ title: 'Design System/ThemeToggle',
5
+ parameters: { layout: 'centered' },
6
+ tags: ['autodocs'],
7
+ } satisfies Meta;
8
+
9
+ export default meta;
10
+ type Story = StoryObj<typeof meta>;
11
+
12
+ export const Default: Story = {
13
+ render: () => (
14
+ <div className="p-4 w-full h-full flex items-center justify-center">
15
+ <div className="p-4 border rounded bg-muted/50 text-muted-foreground text-sm">ThemeToggle — needs manual template</div>
16
+ </div>
17
+ )
18
+ };
@@ -0,0 +1,13 @@
1
+ import { render } from '@testing-library/react';
2
+ import { axe } from 'jest-axe';
3
+
4
+ describe('ThemeToggle Accessibility', () => {
5
+ it('should have no accessibility violations in basic render', async () => {
6
+ const Wrapper = () => (
7
+ <div className="p-4 border rounded bg-muted/50 text-muted-foreground text-sm">ThemeToggle — needs manual template</div>
8
+ );
9
+ const { container } = render(<Wrapper />);
10
+ const results = await axe(container);
11
+ expect(results).toHaveNoViolations();
12
+ });
13
+ });
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { Button } from "@/components/ui/button";
4
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
4
5
  import { cn } from "@/lib/utils";
5
6
  import { Moon, Sun } from "lucide-react";
6
7
  import { useTheme } from "next-themes";
@@ -42,56 +43,53 @@ export const ThemeToggle = memo(function ThemeToggle({
42
43
  }
43
44
  };
44
45
 
45
- const getThemeLabel = () => {
46
- if (!mounted) return "Tema escuro";
47
46
 
48
- switch (theme) {
49
- case "light":
50
- return "Tema claro";
51
- case "dark":
52
- default:
53
- return "Tema escuro";
54
- }
55
- };
56
47
 
57
48
  const getNextThemeLabel = () => {
58
- if (!mounted) return "Mudar para tema claro";
49
+ if (!mounted) return "Alternar tema";
59
50
 
60
51
  switch (theme) {
61
52
  case "light":
62
- return "Mudar para tema escuro";
53
+ return "Ativar tema escuro";
63
54
  case "dark":
64
55
  default:
65
- return "Mudar para tema claro";
56
+ return "Ativar tema claro";
66
57
  }
67
58
  };
68
59
 
69
60
  return (
70
61
  <div className="relative">
71
- <Button
72
- variant="ghost"
73
- size="sm"
74
- onClick={cycleTheme}
75
- className={cn(
76
- "h-9 p-0 text-primary transition-all duration-300 rounded-lg",
77
- "hover:bg-accent/50 active:scale-95",
78
- !showLabel ? "w-9" : "px-3 w-auto",
79
- className
80
- )}
81
- title={getNextThemeLabel()}
82
- aria-label={getThemeLabel()}
83
- >
84
- <div className={cn("flex items-center gap-1.5", !showLabel && "justify-center")}>
85
- <div className="transition-transform duration-300 hover:rotate-12">
86
- {getThemeIcon()}
87
- </div>
88
- {showLabel && (
89
- <span className="text-sm font-medium hidden lg:inline">
90
- Tema
91
- </span>
92
- )}
93
- </div>
94
- </Button>
62
+ <Tooltip>
63
+ <TooltipTrigger
64
+ render={
65
+ <Button
66
+ variant="ghost"
67
+ size="sm"
68
+ onClick={cycleTheme}
69
+ className={cn(
70
+ "h-11 p-0 text-primary transition-all duration-300 rounded-lg md:h-9",
71
+ "hover:bg-accent/50 active:scale-95",
72
+ !showLabel ? "w-11 md:w-9" : "px-3 w-auto",
73
+ className
74
+ )}
75
+ aria-label={getNextThemeLabel()}
76
+ aria-live="polite"
77
+ >
78
+ <div className={cn("flex items-center gap-1.5", !showLabel && "justify-center")}>
79
+ <div className="transition-transform duration-300 hover:rotate-12">
80
+ {getThemeIcon()}
81
+ </div>
82
+ {showLabel && (
83
+ <span className="text-sm font-medium hidden lg:inline">
84
+ Tema
85
+ </span>
86
+ )}
87
+ </div>
88
+ </Button>
89
+ }
90
+ />
91
+ <TooltipContent>{getNextThemeLabel()}</TooltipContent>
92
+ </Tooltip>
95
93
  </div>
96
94
  );
97
95
  });
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { ToggleGroup, ToggleGroupItem } from "./toggle-group";
3
+
4
+ const meta = {
5
+ title: 'Design System/ToggleGroup',
6
+ parameters: { layout: 'centered' },
7
+ tags: ['autodocs'],
8
+ } satisfies Meta;
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <div className="p-4 w-full h-full flex items-center justify-center">
16
+ <ToggleGroup><ToggleGroupItem value="bold" aria-label="Toggle bold">B</ToggleGroupItem><ToggleGroupItem value="italic" aria-label="Toggle italic">I</ToggleGroupItem></ToggleGroup>
17
+ </div>
18
+ )
19
+ };
@@ -0,0 +1,14 @@
1
+ import { render } from '@testing-library/react';
2
+ import { axe } from 'jest-axe';
3
+ import { ToggleGroup, ToggleGroupItem } from "./toggle-group";
4
+
5
+ describe('ToggleGroup Accessibility', () => {
6
+ it('should have no accessibility violations in basic render', async () => {
7
+ const Wrapper = () => (
8
+ <ToggleGroup><ToggleGroupItem value="bold" aria-label="Toggle bold">B</ToggleGroupItem><ToggleGroupItem value="italic" aria-label="Toggle italic">I</ToggleGroupItem></ToggleGroup>
9
+ );
10
+ const { container } = render(<Wrapper />);
11
+ const results = await axe(container);
12
+ expect(results).toHaveNoViolations();
13
+ });
14
+ });
@@ -1,73 +1,89 @@
1
- "use client";
1
+ "use client"
2
2
 
3
- import * as React from "react";
4
- import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
5
- import { type VariantProps } from "class-variance-authority";
3
+ import * as React from "react"
4
+ import { Toggle as TogglePrimitive } from "@base-ui/react/toggle"
5
+ import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group"
6
+ import { type VariantProps } from "class-variance-authority"
6
7
 
7
- import { cn } from "@/lib/utils";
8
- import { toggleVariants } from "@/components/ui/toggle";
8
+ import { cn } from "@/lib/utils"
9
+ import { toggleVariants } from "@/components/ui/toggle"
9
10
 
10
11
  const ToggleGroupContext = React.createContext<
11
- VariantProps<typeof toggleVariants>
12
+ VariantProps<typeof toggleVariants> & {
13
+ spacing?: number
14
+ orientation?: "horizontal" | "vertical"
15
+ }
12
16
  >({
13
17
  size: "default",
14
18
  variant: "default",
15
- });
19
+ spacing: 2,
20
+ orientation: "horizontal",
21
+ })
16
22
 
17
23
  function ToggleGroup({
18
24
  className,
19
25
  variant,
20
26
  size,
27
+ spacing = 2,
28
+ orientation = "horizontal",
21
29
  children,
22
30
  ...props
23
- }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
24
- VariantProps<typeof toggleVariants>) {
31
+ }: ToggleGroupPrimitive.Props &
32
+ VariantProps<typeof toggleVariants> & {
33
+ spacing?: number
34
+ orientation?: "horizontal" | "vertical"
35
+ }) {
25
36
  return (
26
- <ToggleGroupPrimitive.Root
37
+ <ToggleGroupPrimitive
27
38
  data-slot="toggle-group"
28
39
  data-variant={variant}
29
40
  data-size={size}
41
+ data-spacing={spacing}
42
+ data-orientation={orientation}
43
+ style={{ "--gap": spacing } as React.CSSProperties}
30
44
  className={cn(
31
- "group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
45
+ "group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch",
32
46
  className
33
47
  )}
34
48
  {...props}
35
49
  >
36
- <ToggleGroupContext.Provider value={{ variant, size }}>
50
+ <ToggleGroupContext.Provider
51
+ value={{ variant, size, spacing, orientation }}
52
+ >
37
53
  {children}
38
54
  </ToggleGroupContext.Provider>
39
- </ToggleGroupPrimitive.Root>
40
- );
55
+ </ToggleGroupPrimitive>
56
+ )
41
57
  }
42
58
 
43
59
  function ToggleGroupItem({
44
60
  className,
45
61
  children,
46
- variant,
47
- size,
62
+ variant = "default",
63
+ size = "default",
48
64
  ...props
49
- }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
50
- VariantProps<typeof toggleVariants>) {
51
- const context = React.useContext(ToggleGroupContext);
65
+ }: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {
66
+ const context = React.useContext(ToggleGroupContext)
52
67
 
53
68
  return (
54
- <ToggleGroupPrimitive.Item
69
+ <TogglePrimitive
55
70
  data-slot="toggle-group-item"
56
71
  data-variant={context.variant || variant}
57
72
  data-size={context.size || size}
73
+ data-spacing={context.spacing}
58
74
  className={cn(
75
+ "shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
59
76
  toggleVariants({
60
77
  variant: context.variant || variant,
61
78
  size: context.size || size,
62
79
  }),
63
- "min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
64
80
  className
65
81
  )}
66
82
  {...props}
67
83
  >
68
84
  {children}
69
- </ToggleGroupPrimitive.Item>
70
- );
85
+ </TogglePrimitive>
86
+ )
71
87
  }
72
88
 
73
- export { ToggleGroup, ToggleGroupItem };
89
+ export { ToggleGroup, ToggleGroupItem }
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Toggle } from "./toggle";
3
+
4
+ const meta = {
5
+ title: 'Design System/Toggle',
6
+ parameters: { layout: 'centered' },
7
+ tags: ['autodocs'],
8
+ } satisfies Meta;
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <div className="p-4 w-full h-full flex items-center justify-center">
16
+ <Toggle aria-label="Toggle italic">I</Toggle>
17
+ </div>
18
+ )
19
+ };