@strategicos/ui 0.0.0-stage → 0.1.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 (119) hide show
  1. package/README.md +33 -2
  2. package/THIRD_PARTY_NOTICES.md +27 -0
  3. package/dist/components/alert-dialog.d.ts +15 -0
  4. package/dist/components/alert-dialog.d.ts.map +1 -0
  5. package/dist/components/alert-dialog.js +40 -0
  6. package/dist/components/alert-dialog.js.map +1 -0
  7. package/dist/components/alert.d.ts +11 -0
  8. package/dist/components/alert.d.ts.map +1 -0
  9. package/dist/components/alert.js +28 -0
  10. package/dist/components/alert.js.map +1 -0
  11. package/dist/components/avatar.d.ts +12 -0
  12. package/dist/components/avatar.d.ts.map +1 -0
  13. package/dist/components/avatar.js +24 -0
  14. package/dist/components/avatar.js.map +1 -0
  15. package/dist/components/badge.d.ts +10 -0
  16. package/dist/components/badge.d.ts.map +1 -0
  17. package/dist/components/badge.js +33 -0
  18. package/dist/components/badge.js.map +1 -0
  19. package/dist/components/button.d.ts +11 -0
  20. package/dist/components/button.d.ts.map +1 -0
  21. package/dist/components/button.js +36 -0
  22. package/dist/components/button.js.map +1 -0
  23. package/dist/components/card.d.ts +12 -0
  24. package/dist/components/card.d.ts.map +1 -0
  25. package/dist/components/card.js +25 -0
  26. package/dist/components/card.js.map +1 -0
  27. package/dist/components/dialog.d.ts +18 -0
  28. package/dist/components/dialog.d.ts.map +1 -0
  29. package/dist/components/dialog.js +38 -0
  30. package/dist/components/dialog.js.map +1 -0
  31. package/dist/components/dropdown-menu.d.ts +30 -0
  32. package/dist/components/dropdown-menu.d.ts.map +1 -0
  33. package/dist/components/dropdown-menu.js +52 -0
  34. package/dist/components/dropdown-menu.js.map +1 -0
  35. package/dist/components/input.d.ts +4 -0
  36. package/dist/components/input.d.ts.map +1 -0
  37. package/dist/components/input.js +7 -0
  38. package/dist/components/input.js.map +1 -0
  39. package/dist/components/label.d.ts +5 -0
  40. package/dist/components/label.d.ts.map +1 -0
  41. package/dist/components/label.js +9 -0
  42. package/dist/components/label.js.map +1 -0
  43. package/dist/components/pagination.d.ts +12 -0
  44. package/dist/components/pagination.d.ts.map +1 -0
  45. package/dist/components/pagination.js +12 -0
  46. package/dist/components/pagination.js.map +1 -0
  47. package/dist/components/select.d.ts +18 -0
  48. package/dist/components/select.d.ts.map +1 -0
  49. package/dist/components/select.js +37 -0
  50. package/dist/components/select.js.map +1 -0
  51. package/dist/components/separator.d.ts +5 -0
  52. package/dist/components/separator.d.ts.map +1 -0
  53. package/dist/components/separator.js +9 -0
  54. package/dist/components/separator.js.map +1 -0
  55. package/dist/components/sheet.d.ts +15 -0
  56. package/dist/components/sheet.d.ts.map +1 -0
  57. package/dist/components/sheet.js +38 -0
  58. package/dist/components/sheet.js.map +1 -0
  59. package/dist/components/sidebar.d.ts +70 -0
  60. package/dist/components/sidebar.d.ts.map +1 -0
  61. package/dist/components/sidebar.js +207 -0
  62. package/dist/components/sidebar.js.map +1 -0
  63. package/dist/components/skeleton.d.ts +3 -0
  64. package/dist/components/skeleton.d.ts.map +1 -0
  65. package/dist/components/skeleton.js +7 -0
  66. package/dist/components/skeleton.js.map +1 -0
  67. package/dist/components/sonner.d.ts +4 -0
  68. package/dist/components/sonner.d.ts.map +1 -0
  69. package/dist/components/sonner.js +26 -0
  70. package/dist/components/sonner.js.map +1 -0
  71. package/dist/components/table.d.ts +11 -0
  72. package/dist/components/table.d.ts.map +1 -0
  73. package/dist/components/table.js +29 -0
  74. package/dist/components/table.js.map +1 -0
  75. package/dist/components/tabs.d.ts +13 -0
  76. package/dist/components/tabs.d.ts.map +1 -0
  77. package/dist/components/tabs.js +69 -0
  78. package/dist/components/tabs.js.map +1 -0
  79. package/dist/components/textarea.d.ts +15 -0
  80. package/dist/components/textarea.d.ts.map +1 -0
  81. package/dist/components/textarea.js +18 -0
  82. package/dist/components/textarea.js.map +1 -0
  83. package/dist/components/tooltip.d.ts +8 -0
  84. package/dist/components/tooltip.d.ts.map +1 -0
  85. package/dist/components/tooltip.js +18 -0
  86. package/dist/components/tooltip.js.map +1 -0
  87. package/dist/hooks/use-mobile.d.ts +2 -0
  88. package/dist/hooks/use-mobile.d.ts.map +1 -0
  89. package/dist/hooks/use-mobile.js +14 -0
  90. package/dist/hooks/use-mobile.js.map +1 -0
  91. package/dist/lib/utils.d.ts +4 -0
  92. package/dist/lib/utils.d.ts.map +1 -0
  93. package/dist/lib/utils.js +7 -0
  94. package/dist/lib/utils.js.map +1 -0
  95. package/package.json +76 -4
  96. package/src/components/alert-dialog.tsx +152 -0
  97. package/src/components/alert.tsx +76 -0
  98. package/src/components/avatar.tsx +112 -0
  99. package/src/components/badge.tsx +57 -0
  100. package/src/components/button.tsx +67 -0
  101. package/src/components/card.tsx +103 -0
  102. package/src/components/dialog.tsx +168 -0
  103. package/src/components/dropdown-menu.tsx +269 -0
  104. package/src/components/input.tsx +19 -0
  105. package/src/components/label.tsx +24 -0
  106. package/src/components/pagination.tsx +62 -0
  107. package/src/components/select.tsx +208 -0
  108. package/src/components/separator.tsx +28 -0
  109. package/src/components/sheet.tsx +147 -0
  110. package/src/components/sidebar.tsx +702 -0
  111. package/src/components/skeleton.tsx +13 -0
  112. package/src/components/sonner.tsx +49 -0
  113. package/src/components/table.tsx +116 -0
  114. package/src/components/tabs.tsx +153 -0
  115. package/src/components/textarea.tsx +29 -0
  116. package/src/components/tooltip.tsx +57 -0
  117. package/src/hooks/use-mobile.ts +20 -0
  118. package/src/lib/utils.ts +7 -0
  119. package/styles.css +112 -0
@@ -0,0 +1,269 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "../lib/utils.js"
7
+ import { CheckIcon, ChevronRightIcon } from "lucide-react"
8
+
9
+ function DropdownMenu({
10
+ ...props
11
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
12
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
13
+ }
14
+
15
+ function DropdownMenuPortal({
16
+ ...props
17
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
18
+ return (
19
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
20
+ )
21
+ }
22
+
23
+ function DropdownMenuTrigger({
24
+ ...props
25
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
26
+ return (
27
+ <DropdownMenuPrimitive.Trigger
28
+ data-slot="dropdown-menu-trigger"
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function DropdownMenuContent({
35
+ className,
36
+ align = "start",
37
+ sideOffset = 4,
38
+ ...props
39
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
40
+ return (
41
+ <DropdownMenuPrimitive.Portal>
42
+ <DropdownMenuPrimitive.Content
43
+ data-slot="dropdown-menu-content"
44
+ sideOffset={sideOffset}
45
+ align={align}
46
+ className={cn("z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
47
+ {...props}
48
+ />
49
+ </DropdownMenuPrimitive.Portal>
50
+ )
51
+ }
52
+
53
+ function DropdownMenuGroup({
54
+ ...props
55
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
56
+ return (
57
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
58
+ )
59
+ }
60
+
61
+ function DropdownMenuItem({
62
+ className,
63
+ inset,
64
+ variant = "default",
65
+ ...props
66
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
67
+ inset?: boolean
68
+ variant?: "default" | "destructive"
69
+ }) {
70
+ return (
71
+ <DropdownMenuPrimitive.Item
72
+ data-slot="dropdown-menu-item"
73
+ data-inset={inset}
74
+ data-variant={variant}
75
+ className={cn(
76
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function DropdownMenuCheckboxItem({
85
+ className,
86
+ children,
87
+ checked,
88
+ inset,
89
+ ...props
90
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
91
+ inset?: boolean
92
+ }) {
93
+ return (
94
+ <DropdownMenuPrimitive.CheckboxItem
95
+ data-slot="dropdown-menu-checkbox-item"
96
+ data-inset={inset}
97
+ className={cn(
98
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
99
+ className
100
+ )}
101
+ checked={checked}
102
+ {...props}
103
+ >
104
+ <span
105
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
106
+ data-slot="dropdown-menu-checkbox-item-indicator"
107
+ >
108
+ <DropdownMenuPrimitive.ItemIndicator>
109
+ <CheckIcon
110
+ />
111
+ </DropdownMenuPrimitive.ItemIndicator>
112
+ </span>
113
+ {children}
114
+ </DropdownMenuPrimitive.CheckboxItem>
115
+ )
116
+ }
117
+
118
+ function DropdownMenuRadioGroup({
119
+ ...props
120
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
121
+ return (
122
+ <DropdownMenuPrimitive.RadioGroup
123
+ data-slot="dropdown-menu-radio-group"
124
+ {...props}
125
+ />
126
+ )
127
+ }
128
+
129
+ function DropdownMenuRadioItem({
130
+ className,
131
+ children,
132
+ inset,
133
+ ...props
134
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
135
+ inset?: boolean
136
+ }) {
137
+ return (
138
+ <DropdownMenuPrimitive.RadioItem
139
+ data-slot="dropdown-menu-radio-item"
140
+ data-inset={inset}
141
+ className={cn(
142
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
143
+ className
144
+ )}
145
+ {...props}
146
+ >
147
+ <span
148
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
149
+ data-slot="dropdown-menu-radio-item-indicator"
150
+ >
151
+ <DropdownMenuPrimitive.ItemIndicator>
152
+ <CheckIcon
153
+ />
154
+ </DropdownMenuPrimitive.ItemIndicator>
155
+ </span>
156
+ {children}
157
+ </DropdownMenuPrimitive.RadioItem>
158
+ )
159
+ }
160
+
161
+ function DropdownMenuLabel({
162
+ className,
163
+ inset,
164
+ ...props
165
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
166
+ inset?: boolean
167
+ }) {
168
+ return (
169
+ <DropdownMenuPrimitive.Label
170
+ data-slot="dropdown-menu-label"
171
+ data-inset={inset}
172
+ className={cn(
173
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
174
+ className
175
+ )}
176
+ {...props}
177
+ />
178
+ )
179
+ }
180
+
181
+ function DropdownMenuSeparator({
182
+ className,
183
+ ...props
184
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
185
+ return (
186
+ <DropdownMenuPrimitive.Separator
187
+ data-slot="dropdown-menu-separator"
188
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
189
+ {...props}
190
+ />
191
+ )
192
+ }
193
+
194
+ function DropdownMenuShortcut({
195
+ className,
196
+ ...props
197
+ }: React.ComponentProps<"span">) {
198
+ return (
199
+ <span
200
+ data-slot="dropdown-menu-shortcut"
201
+ className={cn(
202
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
203
+ className
204
+ )}
205
+ {...props}
206
+ />
207
+ )
208
+ }
209
+
210
+ function DropdownMenuSub({
211
+ ...props
212
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
213
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
214
+ }
215
+
216
+ function DropdownMenuSubTrigger({
217
+ className,
218
+ inset,
219
+ children,
220
+ ...props
221
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
222
+ inset?: boolean
223
+ }) {
224
+ return (
225
+ <DropdownMenuPrimitive.SubTrigger
226
+ data-slot="dropdown-menu-sub-trigger"
227
+ data-inset={inset}
228
+ className={cn(
229
+ "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
230
+ className
231
+ )}
232
+ {...props}
233
+ >
234
+ {children}
235
+ <ChevronRightIcon className="ml-auto" />
236
+ </DropdownMenuPrimitive.SubTrigger>
237
+ )
238
+ }
239
+
240
+ function DropdownMenuSubContent({
241
+ className,
242
+ ...props
243
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
244
+ return (
245
+ <DropdownMenuPrimitive.SubContent
246
+ data-slot="dropdown-menu-sub-content"
247
+ className={cn("z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
248
+ {...props}
249
+ />
250
+ )
251
+ }
252
+
253
+ export {
254
+ DropdownMenu,
255
+ DropdownMenuPortal,
256
+ DropdownMenuTrigger,
257
+ DropdownMenuContent,
258
+ DropdownMenuGroup,
259
+ DropdownMenuLabel,
260
+ DropdownMenuItem,
261
+ DropdownMenuCheckboxItem,
262
+ DropdownMenuRadioGroup,
263
+ DropdownMenuRadioItem,
264
+ DropdownMenuSeparator,
265
+ DropdownMenuShortcut,
266
+ DropdownMenuSub,
267
+ DropdownMenuSubTrigger,
268
+ DropdownMenuSubContent,
269
+ }
@@ -0,0 +1,19 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../lib/utils.js"
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ "h-9 w-full min-w-0 rounded-lg border border-input bg-transparent px-3 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 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",
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ )
17
+ }
18
+
19
+ export { Input }
@@ -0,0 +1,24 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Label as LabelPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "../lib/utils.js"
7
+
8
+ function Label({
9
+ className,
10
+ ...props
11
+ }: React.ComponentProps<typeof LabelPrimitive.Root>) {
12
+ return (
13
+ <LabelPrimitive.Root
14
+ data-slot="label"
15
+ className={cn(
16
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ export { Label }
@@ -0,0 +1,62 @@
1
+ import { ChevronLeft, ChevronRight } from "lucide-react"
2
+
3
+ import { cn } from "../lib/utils.js"
4
+ import { Button } from "./button.js"
5
+
6
+ interface PaginationProps {
7
+ page: number
8
+ totalPages: number
9
+ total: number
10
+ pageSize: number
11
+ loading?: boolean
12
+ onPageChange: (page: number) => void
13
+ className?: string
14
+ }
15
+
16
+ export function Pagination({
17
+ page,
18
+ totalPages,
19
+ total,
20
+ pageSize,
21
+ loading,
22
+ onPageChange,
23
+ className,
24
+ }: PaginationProps) {
25
+ if (totalPages <= 1) return null
26
+
27
+ const from = total === 0 ? 0 : (page - 1) * pageSize + 1
28
+ const to = Math.min(page * pageSize, total)
29
+
30
+ return (
31
+ <div className={cn("flex items-center justify-between gap-3 pt-3", className)}>
32
+ <p className="text-xs text-muted-foreground">
33
+ {from}–{to} de {total}
34
+ </p>
35
+ <div className="flex items-center gap-2">
36
+ <Button
37
+ size="icon"
38
+ variant="outline"
39
+ className="size-8"
40
+ disabled={page <= 1 || loading}
41
+ onClick={() => onPageChange(page - 1)}
42
+ aria-label="Página anterior"
43
+ >
44
+ <ChevronLeft className="size-4" />
45
+ </Button>
46
+ <span className="text-xs text-muted-foreground tabular-nums">
47
+ Página {page} de {totalPages}
48
+ </span>
49
+ <Button
50
+ size="icon"
51
+ variant="outline"
52
+ className="size-8"
53
+ disabled={page >= totalPages || loading}
54
+ onClick={() => onPageChange(page + 1)}
55
+ aria-label="Próxima página"
56
+ >
57
+ <ChevronRight className="size-4" />
58
+ </Button>
59
+ </div>
60
+ </div>
61
+ )
62
+ }
@@ -0,0 +1,208 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Select as SelectPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "../lib/utils.js"
7
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
8
+
9
+ function Select({
10
+ ...props
11
+ }: React.ComponentProps<typeof SelectPrimitive.Root>) {
12
+ return <SelectPrimitive.Root data-slot="select" {...props} />
13
+ }
14
+
15
+ function SelectGroup({
16
+ className,
17
+ ...props
18
+ }: React.ComponentProps<typeof SelectPrimitive.Group>) {
19
+ return (
20
+ <SelectPrimitive.Group
21
+ data-slot="select-group"
22
+ className={cn("scroll-my-1 p-1", className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function SelectValue({
29
+ ...props
30
+ }: React.ComponentProps<typeof SelectPrimitive.Value>) {
31
+ return <SelectPrimitive.Value data-slot="select-value" {...props} />
32
+ }
33
+
34
+ function SelectTrigger({
35
+ className,
36
+ size = "default",
37
+ children,
38
+ ...props
39
+ }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
40
+ size?: "sm" | "default"
41
+ }) {
42
+ return (
43
+ <SelectPrimitive.Trigger
44
+ data-slot="select-trigger"
45
+ data-size={size}
46
+ className={cn(
47
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2.5 pl-3 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-7.5 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
48
+ className
49
+ )}
50
+ {...props}
51
+ >
52
+ {children}
53
+ <SelectPrimitive.Icon asChild>
54
+ {/* Sem cor fixa: o chevron HERDA a cor do trigger e só recua na
55
+ opacidade. Com `text-muted-foreground` fixo aqui, todo trigger de
56
+ fundo customizado (ex.: o chip sólido de status) precisava brigar
57
+ com esta classe — e o cinza sumia sobre o preenchimento colorido. */}
58
+ <ChevronDownIcon className="pointer-events-none size-4 opacity-70" />
59
+ </SelectPrimitive.Icon>
60
+ </SelectPrimitive.Trigger>
61
+ )
62
+ }
63
+
64
+ function SelectContent({
65
+ className,
66
+ children,
67
+ position = "popper",
68
+ align = "start",
69
+ ...props
70
+ }: React.ComponentProps<typeof SelectPrimitive.Content>) {
71
+ return (
72
+ <SelectPrimitive.Portal>
73
+ <SelectPrimitive.Content
74
+ data-slot="select-content"
75
+ data-align-trigger={position === "item-aligned"}
76
+ className={cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )}
77
+ position={position}
78
+ align={align}
79
+ {...props}
80
+ >
81
+ <SelectScrollUpButton />
82
+ <SelectPrimitive.Viewport
83
+ data-position={position}
84
+ className={cn(
85
+ "data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
86
+ position === "popper" && ""
87
+ )}
88
+ >
89
+ {children}
90
+ </SelectPrimitive.Viewport>
91
+ <SelectScrollDownButton />
92
+ </SelectPrimitive.Content>
93
+ </SelectPrimitive.Portal>
94
+ )
95
+ }
96
+
97
+ function SelectLabel({
98
+ className,
99
+ ...props
100
+ }: React.ComponentProps<typeof SelectPrimitive.Label>) {
101
+ return (
102
+ <SelectPrimitive.Label
103
+ data-slot="select-label"
104
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
105
+ {...props}
106
+ />
107
+ )
108
+ }
109
+
110
+ function SelectItem({
111
+ className,
112
+ children,
113
+ description,
114
+ ...props
115
+ }: React.ComponentProps<typeof SelectPrimitive.Item> & {
116
+ // Texto secundário (ex.: e-mail) exibido só na lista, não no valor selecionado —
117
+ // fica fora do ItemText, que é o único conteúdo clonado para o trigger.
118
+ description?: React.ReactNode
119
+ }) {
120
+ return (
121
+ <SelectPrimitive.Item
122
+ data-slot="select-item"
123
+ className={cn(
124
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
125
+ className
126
+ )}
127
+ {...props}
128
+ >
129
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
130
+ <SelectPrimitive.ItemIndicator>
131
+ <CheckIcon className="pointer-events-none" />
132
+ </SelectPrimitive.ItemIndicator>
133
+ </span>
134
+ {description ? (
135
+ <div className="flex flex-col">
136
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
137
+ <span className="text-[11px] text-muted-foreground">{description}</span>
138
+ </div>
139
+ ) : (
140
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
141
+ )}
142
+ </SelectPrimitive.Item>
143
+ )
144
+ }
145
+
146
+ function SelectSeparator({
147
+ className,
148
+ ...props
149
+ }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
150
+ return (
151
+ <SelectPrimitive.Separator
152
+ data-slot="select-separator"
153
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
154
+ {...props}
155
+ />
156
+ )
157
+ }
158
+
159
+ function SelectScrollUpButton({
160
+ className,
161
+ ...props
162
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
163
+ return (
164
+ <SelectPrimitive.ScrollUpButton
165
+ data-slot="select-scroll-up-button"
166
+ className={cn(
167
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
168
+ className
169
+ )}
170
+ {...props}
171
+ >
172
+ <ChevronUpIcon
173
+ />
174
+ </SelectPrimitive.ScrollUpButton>
175
+ )
176
+ }
177
+
178
+ function SelectScrollDownButton({
179
+ className,
180
+ ...props
181
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
182
+ return (
183
+ <SelectPrimitive.ScrollDownButton
184
+ data-slot="select-scroll-down-button"
185
+ className={cn(
186
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
187
+ className
188
+ )}
189
+ {...props}
190
+ >
191
+ <ChevronDownIcon
192
+ />
193
+ </SelectPrimitive.ScrollDownButton>
194
+ )
195
+ }
196
+
197
+ export {
198
+ Select,
199
+ SelectContent,
200
+ SelectGroup,
201
+ SelectItem,
202
+ SelectLabel,
203
+ SelectScrollDownButton,
204
+ SelectScrollUpButton,
205
+ SelectSeparator,
206
+ SelectTrigger,
207
+ SelectValue,
208
+ }
@@ -0,0 +1,28 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Separator as SeparatorPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "../lib/utils.js"
7
+
8
+ function Separator({
9
+ className,
10
+ orientation = "horizontal",
11
+ decorative = true,
12
+ ...props
13
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
14
+ return (
15
+ <SeparatorPrimitive.Root
16
+ data-slot="separator"
17
+ decorative={decorative}
18
+ orientation={orientation}
19
+ className={cn(
20
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ export { Separator }