@adamosuiteservices/ui 1.2.4 → 1.3.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 (178) hide show
  1. package/README.md +4 -0
  2. package/dist/accordion-rounded.cjs +1 -1
  3. package/dist/accordion-rounded.js +1 -1
  4. package/dist/accordion.cjs +1 -1
  5. package/dist/accordion.js +1 -1
  6. package/dist/avatar.cjs +1 -1
  7. package/dist/avatar.js +1 -1
  8. package/dist/badge.cjs +1 -1
  9. package/dist/badge.js +1 -1
  10. package/dist/breadcrumb.cjs +1 -0
  11. package/dist/breadcrumb.js +105 -0
  12. package/dist/{button-C1n6snOY.js → button-2GdKenQI.js} +1 -1
  13. package/dist/{button-BV-_FVKZ.cjs → button-DEQVHMrX.cjs} +1 -1
  14. package/dist/button-group.cjs +1 -1
  15. package/dist/button-group.js +2 -2
  16. package/dist/button.cjs +1 -1
  17. package/dist/button.js +1 -1
  18. package/dist/calendar.cjs +1 -1
  19. package/dist/calendar.js +1 -1
  20. package/dist/{checkbox-BrmXPKTn.js → checkbox-Dr487kAg.js} +3 -3
  21. package/dist/{checkbox-Lq-HvSgc.cjs → checkbox-YWAnswaW.cjs} +1 -1
  22. package/dist/checkbox.cjs +1 -1
  23. package/dist/checkbox.js +1 -1
  24. package/dist/collapsible.cjs +1 -1
  25. package/dist/collapsible.js +1 -1
  26. package/dist/combobox.cjs +1 -1
  27. package/dist/combobox.js +6 -6
  28. package/dist/components/ui/breadcrumb/breadcrumb.d.ts +11 -0
  29. package/dist/components/ui/breadcrumb/breadcrumb.stories.d.ts +26 -0
  30. package/dist/components/ui/breadcrumb/index.d.ts +1 -0
  31. package/dist/components/ui/dialog/dialog.d.ts +2 -1
  32. package/dist/context-menu.cjs +1 -1
  33. package/dist/context-menu.js +2 -2
  34. package/dist/custom-layered-styles.css +1 -1
  35. package/dist/dialog.cjs +1 -1
  36. package/dist/dialog.js +33 -19
  37. package/dist/dropdown-menu.cjs +1 -1
  38. package/dist/dropdown-menu.js +3 -3
  39. package/dist/ellipsis-CryjZKZn.js +15 -0
  40. package/dist/ellipsis-Ct9VTDOG.cjs +6 -0
  41. package/dist/field.cjs +1 -1
  42. package/dist/field.js +2 -2
  43. package/dist/hover-card.cjs +1 -1
  44. package/dist/hover-card.js +6 -6
  45. package/dist/{index-CAOY367Y.js → index-B0M7VOwp.js} +2 -2
  46. package/dist/{index-B-ZRqW0J.js → index-BBoIAjAs.js} +3 -3
  47. package/dist/{index-gO_QEiaK.cjs → index-BDs8lUfq.cjs} +1 -1
  48. package/dist/index-BFyr34mw.cjs +5 -0
  49. package/dist/index-BMWt1NBG.js +79 -0
  50. package/dist/{index-yR-v1A4G.js → index-BX9hz-JD.js} +1 -1
  51. package/dist/{index-BGiGvaq8.cjs → index-BcGMAmWE.cjs} +1 -1
  52. package/dist/{index-IKJMQref.cjs → index-Bd0gQB0k.cjs} +1 -1
  53. package/dist/{index-VIUqZjyP.cjs → index-BeWgla7c.cjs} +1 -1
  54. package/dist/{index-EUea2gfp.js → index-BpWB3aFK.js} +1 -1
  55. package/dist/index-BvLQnI56.js +59 -0
  56. package/dist/{index-CwUFT-GQ.js → index-C0YiLSjW.js} +4 -4
  57. package/dist/{index-o0sNTcKe.js → index-CBjZooac.js} +2 -2
  58. package/dist/{index-DnS_sBBe.cjs → index-COuvjZLM.cjs} +1 -1
  59. package/dist/index-CTjlbbt9.cjs +1 -0
  60. package/dist/index-CUWMxxKG.js +97 -0
  61. package/dist/{index-C329e3yQ.js → index-CZZ3llmi.js} +2 -2
  62. package/dist/index-CjyiloO7.cjs +1 -0
  63. package/dist/{index-D3wSWKST.cjs → index-Cmx9M9cZ.cjs} +1 -1
  64. package/dist/index-CocSS1YK.cjs +1 -0
  65. package/dist/index-CzRiuk60.cjs +1 -0
  66. package/dist/index-DFPDUUq7.js +658 -0
  67. package/dist/{index-D3S7dBDI.cjs → index-DIwmXz1u.cjs} +1 -1
  68. package/dist/index-DLcqcWxM.js +29 -0
  69. package/dist/index-DMLQL2aG.js +286 -0
  70. package/dist/{index-DXQ-7kNJ.cjs → index-DMs8RL3E.cjs} +1 -1
  71. package/dist/{index-Ce3QBKyj.cjs → index-Dbj9vHNq.cjs} +1 -1
  72. package/dist/{index-BRLtxFFr.cjs → index-DmGzwG2z.cjs} +1 -1
  73. package/dist/{index-P1sVIHE3.js → index-PYkEXTqJ.js} +1 -1
  74. package/dist/{index-DulPG3F9.js → index-Se4vRnIO.js} +3 -3
  75. package/dist/index-_XxjJPRD.cjs +1 -0
  76. package/dist/{index-B-cHTKrs.js → index-yWvyIlmA.js} +4 -4
  77. package/dist/input-group.cjs +1 -1
  78. package/dist/input-group.js +1 -1
  79. package/dist/{label-Cne2J57f.cjs → label-BjXORCBM.cjs} +1 -1
  80. package/dist/{label-Ky8qBEC3.js → label-CmwGvhy1.js} +1 -1
  81. package/dist/label.cjs +1 -1
  82. package/dist/label.js +1 -1
  83. package/dist/pagination.cjs +1 -6
  84. package/dist/pagination.js +58 -69
  85. package/dist/popover-3rIoNCXs.js +306 -0
  86. package/dist/popover-FCKBtFo-.cjs +1 -0
  87. package/dist/popover.cjs +1 -1
  88. package/dist/popover.js +1 -1
  89. package/dist/progress.cjs +1 -1
  90. package/dist/progress.js +1 -1
  91. package/dist/radio-group.cjs +1 -1
  92. package/dist/radio-group.js +5 -5
  93. package/dist/select.cjs +2 -2
  94. package/dist/select.js +585 -542
  95. package/dist/{separator-CGnu_jIu.cjs → separator-BaZqZZ9R.cjs} +1 -1
  96. package/dist/{separator-BH73A90k.js → separator-DR7lQjv9.js} +1 -1
  97. package/dist/separator.cjs +1 -1
  98. package/dist/separator.js +1 -1
  99. package/dist/{sheet-CcxnJ6LH.cjs → sheet-CU-sFSaJ.cjs} +1 -1
  100. package/dist/{sheet-_DVpQIVF.js → sheet-UZWAbdXr.js} +1 -1
  101. package/dist/sheet.cjs +1 -1
  102. package/dist/sheet.js +1 -1
  103. package/dist/sidebar.cjs +1 -1
  104. package/dist/sidebar.js +4 -4
  105. package/dist/slider.cjs +1 -1
  106. package/dist/slider.js +3 -3
  107. package/dist/styles.css +1 -1
  108. package/dist/switch.cjs +1 -1
  109. package/dist/switch.js +2 -2
  110. package/dist/tabs-underline.cjs +1 -1
  111. package/dist/tabs-underline.js +1 -1
  112. package/dist/tabs.cjs +1 -1
  113. package/dist/tabs.js +1 -1
  114. package/dist/toaster.cjs +1 -1
  115. package/dist/toaster.js +1 -1
  116. package/dist/toggle.cjs +1 -1
  117. package/dist/toggle.js +1 -1
  118. package/dist/tooltip.cjs +1 -1
  119. package/dist/tooltip.js +114 -108
  120. package/dist/typography.cjs +1 -1
  121. package/dist/typography.js +16 -16
  122. package/docs/AI-GUIDE.md +321 -0
  123. package/docs/components/layout/sidebar.md +330 -0
  124. package/docs/components/layout/toaster.md +436 -0
  125. package/docs/components/ui/accordion-rounded.md +583 -0
  126. package/docs/components/ui/accordion.md +267 -0
  127. package/docs/components/ui/alert.md +671 -0
  128. package/docs/components/ui/avatar.md +588 -0
  129. package/docs/components/ui/badge.md +1024 -0
  130. package/docs/components/ui/breadcrumb.md +614 -0
  131. package/docs/components/ui/button-group.md +1002 -0
  132. package/docs/components/ui/button.md +1078 -0
  133. package/docs/components/ui/calendar.md +1159 -0
  134. package/docs/components/ui/card.md +1265 -0
  135. package/docs/components/ui/checkbox.md +292 -0
  136. package/docs/components/ui/collapsible.md +320 -0
  137. package/docs/components/ui/combobox.md +328 -0
  138. package/docs/components/ui/command.md +454 -0
  139. package/docs/components/ui/context-menu.md +540 -0
  140. package/docs/components/ui/dialog.md +628 -0
  141. package/docs/components/ui/dropdown-menu.md +731 -0
  142. package/docs/components/ui/field.md +706 -0
  143. package/docs/components/ui/hover-card.md +446 -0
  144. package/docs/components/ui/input-group.md +509 -0
  145. package/docs/components/ui/input.md +362 -0
  146. package/docs/components/ui/kbd.md +434 -0
  147. package/docs/components/ui/label.md +359 -0
  148. package/docs/components/ui/pagination.md +650 -0
  149. package/docs/components/ui/popover.md +536 -0
  150. package/docs/components/ui/progress.md +182 -0
  151. package/docs/components/ui/radio-group.md +311 -0
  152. package/docs/components/ui/select.md +352 -0
  153. package/docs/components/ui/separator.md +214 -0
  154. package/docs/components/ui/sheet.md +142 -0
  155. package/docs/components/ui/skeleton.md +140 -0
  156. package/docs/components/ui/slider.md +341 -0
  157. package/docs/components/ui/spinner.md +170 -0
  158. package/docs/components/ui/switch.md +402 -0
  159. package/docs/components/ui/table.md +183 -0
  160. package/docs/components/ui/tabs-underline.md +106 -0
  161. package/docs/components/ui/tabs.md +122 -0
  162. package/docs/components/ui/textarea.md +243 -0
  163. package/docs/components/ui/toggle.md +243 -0
  164. package/docs/components/ui/tooltip.md +320 -0
  165. package/docs/components/ui/typography.md +191 -0
  166. package/package.json +11 -5
  167. package/dist/index-6oTEokEx.js +0 -82
  168. package/dist/index-B-NyefE0.js +0 -243
  169. package/dist/index-BKbK2GzY.cjs +0 -1
  170. package/dist/index-BMitW9UR.cjs +0 -1
  171. package/dist/index-BpvjJ_T6.cjs +0 -5
  172. package/dist/index-C5wjudc-.js +0 -36
  173. package/dist/index-CezwiPd_.js +0 -615
  174. package/dist/index-D02K8KOB.js +0 -54
  175. package/dist/index-D7hQvndv.cjs +0 -1
  176. package/dist/index-DQvx1rG_.cjs +0 -1
  177. package/dist/popover-BjdTqaB8.cjs +0 -1
  178. package/dist/popover-EnVfE0YA.js +0 -263
@@ -0,0 +1,140 @@
1
+ # Skeleton
2
+
3
+ Placeholder animado para contenido en carga. Simula la estructura del contenido final con bloques pulsantes.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Skeleton` muestra placeholders de carga para contenido que está siendo cargado.
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import { Skeleton } from "@adamosuiteservices/ui/skeleton";
13
+ ```
14
+
15
+ ## Anatomía
16
+
17
+ ```tsx
18
+ <Skeleton className="w-full h-12" />
19
+ ```
20
+
21
+ **Componentes**: 1 (Skeleton)
22
+
23
+ ## Props
24
+
25
+ | Prop | Tipo | Descripción |
26
+ | ----------- | -------- | ------------------------------ |
27
+ | `className` | `string` | Clases CSS para tamaño y forma |
28
+
29
+ **Nota**: Acepta todas las props de `<div>`
30
+
31
+ ## Patrones de Uso
32
+
33
+ ### Básico
34
+
35
+ ```tsx
36
+ <Skeleton className="h-4 w-[250px]" />
37
+ ```
38
+
39
+ ### Avatar + Text
40
+
41
+ ```tsx
42
+ <div className="flex items-center space-x-4">
43
+ <Skeleton className="h-12 w-12 rounded-full" />
44
+ <div className="space-y-2">
45
+ <Skeleton className="h-4 w-[250px]" />
46
+ <Skeleton className="h-4 w-[200px]" />
47
+ </div>
48
+ </div>
49
+ ```
50
+
51
+ ### Card
52
+
53
+ ```tsx
54
+ <div className="flex flex-col space-y-3">
55
+ <Skeleton className="h-[125px] w-[250px] rounded-xl" />
56
+ <div className="space-y-2">
57
+ <Skeleton className="h-4 w-[250px]" />
58
+ <Skeleton className="h-4 w-[200px]" />
59
+ </div>
60
+ </div>
61
+ ```
62
+
63
+ ### Text Lines
64
+
65
+ ```tsx
66
+ <div className="space-y-2">
67
+ <Skeleton className="h-4 w-full" />
68
+ <Skeleton className="h-4 w-[90%]" />
69
+ <Skeleton className="h-4 w-[80%]" />
70
+ </div>
71
+ ```
72
+
73
+ ### Form
74
+
75
+ ```tsx
76
+ <div className="space-y-4 max-w-md">
77
+ <div className="space-y-2">
78
+ <Skeleton className="h-4 w-16" />
79
+ <Skeleton className="h-10 w-full rounded-md" />
80
+ </div>
81
+ <div className="space-y-2">
82
+ <Skeleton className="h-4 w-20" />
83
+ <Skeleton className="h-10 w-full rounded-md" />
84
+ </div>
85
+ <Skeleton className="h-10 w-24 rounded-md" />
86
+ </div>
87
+ ```
88
+
89
+ ### List Items
90
+
91
+ ```tsx
92
+ <div className="space-y-4">
93
+ {Array.from({ length: 4 }).map((_, i) => (
94
+ <div key={i} className="flex items-center space-x-4">
95
+ <Skeleton className="h-10 w-10 rounded-full" />
96
+ <div className="space-y-2 flex-1">
97
+ <Skeleton className="h-4 w-[200px]" />
98
+ <Skeleton className="h-3 w-[150px]" />
99
+ </div>
100
+ <Skeleton className="h-8 w-16 rounded-md" />
101
+ </div>
102
+ ))}
103
+ </div>
104
+ ```
105
+
106
+ ## Casos de Uso
107
+
108
+ **Loading states**: Placeholder mientras carga contenido
109
+ **Lazy loading**: Imágenes/contenido que carga progresivamente
110
+ **Optimistic UI**: Simular contenido antes de respuesta
111
+ **Infinite scroll**: Items mientras cargan más
112
+
113
+ ## Estilos Base
114
+
115
+ - **Background**: `bg-accent`
116
+ - **Animation**: `animate-pulse`
117
+ - **Border radius**: `rounded-md` default
118
+
119
+ ## Accesibilidad
120
+
121
+ - ✅ **ARIA**: Usa `aria-busy="true"` en contenedor padre
122
+ - ✅ **Screen readers**: Anuncia estado de carga en contenedor
123
+ - ⚠️ **Replace**: Reemplaza skeleton con contenido real al cargar
124
+
125
+ ## Notas de Implementación
126
+
127
+ - **HTML nativo**: Simple `<div>` con estilos
128
+ - **Pulse animation**: Tailwind `animate-pulse`
129
+ - **Customizable**: Totalmente personalizable con className
130
+ - **No state**: Stateless, solo visual
131
+
132
+ ## Troubleshooting
133
+
134
+ **No pulsa**: Verifica que `animate-pulse` esté aplicado
135
+ **Tamaño inconsistente**: Usa height/width específicos con className
136
+ **Forma incorrecta**: Ajusta `rounded-*` para avatars, cards, etc.
137
+
138
+ ## Referencias
139
+
140
+ - **shadcn/ui Skeleton**: <https://ui.shadcn.com/docs/components/skeleton>
@@ -0,0 +1,341 @@
1
+ # Slider
2
+
3
+ Control de rango con thumbs deslizables. Soporta valores simples y rangos. Basado en Radix UI.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Slider` permite seleccionar un valor arrastrando un control deslizante.
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import { Slider } from "@adamosuiteservices/ui/slider";
13
+ ```
14
+
15
+ ## Anatomía
16
+
17
+ ```tsx
18
+ <Slider defaultValue={[50]} max={100} step={1} />
19
+ ```
20
+
21
+ **Componentes**: 1 (Slider) con 3 partes internas (Root, Track, Range, Thumb)
22
+
23
+ ## Props
24
+
25
+ | Prop | Tipo | Descripción |
26
+ | --------------- | ---------------------------- | ----------------------------------- |
27
+ | `defaultValue` | `number[]` | Valor inicial (uncontrolled) |
28
+ | `value` | `number[]` | Valor controlado (array de números) |
29
+ | `onValueChange` | `(value: number[]) => void` | Callback al cambiar valor |
30
+ | `min` | `number` | Valor mínimo (default: 0) |
31
+ | `max` | `number` | Valor máximo (default: 100) |
32
+ | `step` | `number` | Incremento (default: 1) |
33
+ | `disabled` | `boolean` | Deshabilita el slider |
34
+ | `orientation` | `"horizontal" \| "vertical"` | Orientación (default: horizontal) |
35
+ | `theme` | `Theme` | Tema personalizado |
36
+ | `className` | `string` | Clases CSS adicionales |
37
+
38
+ **Nota**: `value` y `defaultValue` siempre son arrays. Single value = `[50]`, range = `[20, 80]`
39
+
40
+ ## Patrones de Uso
41
+
42
+ ### Básico
43
+
44
+ ```tsx
45
+ import { Slider } from "@adamosuiteservices/ui/slider";
46
+
47
+ <Slider defaultValue={[33]} max={100} step={1} className="w-[60%]" />;
48
+ ```
49
+
50
+ ### Con Label
51
+
52
+ ```tsx
53
+ import { Label } from "@adamosuiteservices/ui/label";
54
+ import { useState } from "react";
55
+
56
+ function App() {
57
+ const [value, setValue] = useState([50]);
58
+
59
+ return (
60
+ <div className="grid w-full max-w-sm items-center gap-2">
61
+ <Label htmlFor="volume">Volume: {value[0]}%</Label>
62
+ <Slider
63
+ id="volume"
64
+ max={100}
65
+ step={1}
66
+ value={value}
67
+ onValueChange={setValue}
68
+ className="w-full"
69
+ />
70
+ </div>
71
+ );
72
+ }
73
+ ```
74
+
75
+ ### Range (Dos Valores)
76
+
77
+ ```tsx
78
+ function App() {
79
+ const [value, setValue] = useState([20, 80]);
80
+
81
+ return (
82
+ <div className="grid w-full max-w-sm items-center gap-2">
83
+ <Label>
84
+ Price Range: ${value[0]} - ${value[1]}
85
+ </Label>
86
+ <Slider
87
+ max={100}
88
+ step={1}
89
+ value={value}
90
+ onValueChange={setValue}
91
+ className="w-full"
92
+ />
93
+ </div>
94
+ );
95
+ }
96
+ ```
97
+
98
+ ### Con Steps
99
+
100
+ ```tsx
101
+ function App() {
102
+ const [value, setValue] = useState([25]);
103
+ const stepSize = 25;
104
+
105
+ return (
106
+ <div className="grid w-full max-w-sm items-center gap-2">
107
+ <Label>Progress: {value[0]}%</Label>
108
+ <Slider
109
+ max={100}
110
+ step={stepSize}
111
+ value={value}
112
+ onValueChange={setValue}
113
+ className="w-full"
114
+ />
115
+ <div className="flex justify-between text-xs text-muted-foreground">
116
+ <span>0%</span>
117
+ <span>25%</span>
118
+ <span>50%</span>
119
+ <span>75%</span>
120
+ <span>100%</span>
121
+ </div>
122
+ </div>
123
+ );
124
+ }
125
+ ```
126
+
127
+ ### Vertical
128
+
129
+ ```tsx
130
+ function App() {
131
+ const [value, setValue] = useState([60]);
132
+
133
+ return (
134
+ <div className="flex h-64 items-center space-x-6">
135
+ <div className="flex flex-col items-center space-y-2">
136
+ <Label>Volume</Label>
137
+ <Slider
138
+ orientation="vertical"
139
+ max={100}
140
+ step={1}
141
+ value={value}
142
+ onValueChange={setValue}
143
+ className="h-48"
144
+ />
145
+ <span className="text-sm text-muted-foreground">{value[0]}%</span>
146
+ </div>
147
+ </div>
148
+ );
149
+ }
150
+ ```
151
+
152
+ ### Con Botones
153
+
154
+ ```tsx
155
+ import { Button } from "@adamosuiteservices/ui/button";
156
+
157
+ function App() {
158
+ const [value, setValue] = useState([50]);
159
+
160
+ const decrease = () => setValue([Math.max(0, value[0] - 10)]);
161
+ const increase = () => setValue([Math.min(100, value[0] + 10)]);
162
+
163
+ return (
164
+ <div className="grid w-full max-w-sm items-center gap-4">
165
+ <Label>Volume: {value[0]}%</Label>
166
+ <div className="flex items-center space-x-2">
167
+ <Button
168
+ variant="outline"
169
+ size="sm"
170
+ onClick={decrease}
171
+ disabled={value[0] === 0}
172
+ >
173
+ -
174
+ </Button>
175
+ <Slider
176
+ value={value}
177
+ onValueChange={setValue}
178
+ max={100}
179
+ step={1}
180
+ className="flex-1"
181
+ />
182
+ <Button
183
+ variant="outline"
184
+ size="sm"
185
+ onClick={increase}
186
+ disabled={value[0] === 100}
187
+ >
188
+ +
189
+ </Button>
190
+ </div>
191
+ </div>
192
+ );
193
+ }
194
+ ```
195
+
196
+ ### Price Filter
197
+
198
+ ```tsx
199
+ import {
200
+ Card,
201
+ CardContent,
202
+ CardHeader,
203
+ CardTitle,
204
+ } from "@adamosuiteservices/ui/card";
205
+ import { Button } from "@adamosuiteservices/ui/button";
206
+
207
+ function PriceFilter() {
208
+ const [priceRange, setPriceRange] = useState([25, 75]);
209
+
210
+ return (
211
+ <Card className="w-full max-w-sm">
212
+ <CardHeader>
213
+ <CardTitle>Filter by Price</CardTitle>
214
+ </CardHeader>
215
+ <CardContent className="space-y-4">
216
+ <div className="space-y-2">
217
+ <Label>Price Range</Label>
218
+ <Slider
219
+ value={priceRange}
220
+ onValueChange={setPriceRange}
221
+ max={100}
222
+ step={1}
223
+ className="w-full"
224
+ />
225
+ </div>
226
+ <div className="flex justify-between text-sm">
227
+ <span>${priceRange[0]}</span>
228
+ <span>${priceRange[1]}</span>
229
+ </div>
230
+ <Button className="w-full">Apply Filter</Button>
231
+ </CardContent>
232
+ </Card>
233
+ );
234
+ }
235
+ ```
236
+
237
+ ### RGB Color Picker
238
+
239
+ ```tsx
240
+ function ColorPicker() {
241
+ const [red, setRed] = useState([128]);
242
+ const [green, setGreen] = useState([200]);
243
+ const [blue, setBlue] = useState([75]);
244
+
245
+ const rgbColor = `rgb(${red[0]}, ${green[0]}, ${blue[0]})`;
246
+
247
+ return (
248
+ <Card className="w-full max-w-sm">
249
+ <CardHeader>
250
+ <CardTitle>RGB Color Picker</CardTitle>
251
+ </CardHeader>
252
+ <CardContent className="space-y-6">
253
+ <div
254
+ className="w-full h-20 rounded-lg border"
255
+ style={{ backgroundColor: rgbColor }}
256
+ />
257
+
258
+ <div className="space-y-4">
259
+ <div className="space-y-2">
260
+ <div className="flex justify-between">
261
+ <Label>Red</Label>
262
+ <span className="text-sm text-muted-foreground">{red[0]}</span>
263
+ </div>
264
+ <Slider value={red} onValueChange={setRed} max={255} step={1} />
265
+ </div>
266
+
267
+ <div className="space-y-2">
268
+ <div className="flex justify-between">
269
+ <Label>Green</Label>
270
+ <span className="text-sm text-muted-foreground">{green[0]}</span>
271
+ </div>
272
+ <Slider value={green} onValueChange={setGreen} max={255} step={1} />
273
+ </div>
274
+
275
+ <div className="space-y-2">
276
+ <div className="flex justify-between">
277
+ <Label>Blue</Label>
278
+ <span className="text-sm text-muted-foreground">{blue[0]}</span>
279
+ </div>
280
+ <Slider value={blue} onValueChange={setBlue} max={255} step={1} />
281
+ </div>
282
+ </div>
283
+ </CardContent>
284
+ </Card>
285
+ );
286
+ }
287
+ ```
288
+
289
+ ### Deshabilitado
290
+
291
+ ```tsx
292
+ <Slider defaultValue={[50]} max={100} step={1} disabled className="w-full" />
293
+ ```
294
+
295
+ ## Casos de Uso
296
+
297
+ **Volume control**: Audio, música, efectos de sonido
298
+ **Price filters**: Rango de precios en e-commerce
299
+ **Color pickers**: RGB, HSL sliders
300
+ **Brightness/Contrast**: Ajustes de imagen
301
+ **Temperature**: Termostatos, controles de clima
302
+ **Range selection**: Filtros de fecha, edad, tamaño
303
+
304
+ ## Estilos Base
305
+
306
+ - **Track height**: `h-1.5` (horizontal), `w-1.5` (vertical)
307
+ - **Track bg**: `bg-muted`
308
+ - **Range bg**: `bg-primary`
309
+ - **Thumb**: `size-4` con `border-primary`, `bg-white`, `shadow-sm`
310
+ - **Thumb hover/focus**: `ring-4` con `ring-ring/50`
311
+ - **Vertical**: `min-h-44` default, `flex-col`
312
+
313
+ ## Accesibilidad
314
+
315
+ - ✅ **Role**: `role="slider"` con `aria-valuenow`, `aria-valuemin`, `aria-valuemax`
316
+ - ✅ **Keyboard**: Arrow keys para ajustar valor, Home/End para min/max
317
+ - ✅ **Focus**: Focus ring visible en thumbs
318
+ - ✅ **Label**: Asociar con `id` para screen readers
319
+
320
+ ## Notas de Implementación
321
+
322
+ - **Radix UI**: Basado en `@radix-ui/react-slider`
323
+ - **Multiple thumbs**: Array length determina número de thumbs
324
+ - **Value format**: Siempre array, ej: `[50]` para single, `[20, 80]` para range
325
+ - **Auto-thumbs**: Genera thumbs automáticamente basado en `value.length`
326
+ - **Data attributes**: `data-orientation` para estilos horizontal/vertical
327
+ - **Theme support**: Prop `theme` para personalización
328
+
329
+ ## Troubleshooting
330
+
331
+ **Thumb no se mueve**: Verifica `max`, `min` y `step` son números válidos
332
+ **Value no actualiza**: En modo controlado usa `value` + `onValueChange`, no `defaultValue`
333
+ **Range invertido**: Asegura `value[0] < value[1]` en ranges
334
+ **Vertical no funciona**: Agrega `className="h-[Xpx]"` para altura explícita
335
+ **Step no funciona**: `step` debe ser divisor válido del rango (max - min)
336
+ **Multiple thumbs**: `value={[10, 50, 90]}` crea 3 thumbs
337
+
338
+ ## Referencias
339
+
340
+ - **Radix UI Slider**: <https://www.radix-ui.com/primitives/docs/components/slider>
341
+ - **shadcn/ui Slider**: <https://ui.shadcn.com/docs/components/slider>
@@ -0,0 +1,170 @@
1
+ # Spinner
2
+
3
+ Indicador de carga animado basado en Loader2 icon de Lucide. Icono giratorio para estados de loading.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Spinner` muestra un indicador de carga animado.
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import { Spinner } from "@adamosuiteservices/ui/spinner";
13
+ ```
14
+
15
+ ## Anatomía
16
+
17
+ ```tsx
18
+ <Spinner />
19
+ ```
20
+
21
+ **Componentes**: 1 (Spinner)
22
+
23
+ ## Props
24
+
25
+ | Prop | Tipo | Descripción |
26
+ | ----------- | -------- | ------------------------------ |
27
+ | `className` | `string` | Clases CSS para tamaño y color |
28
+
29
+ **Nota**: Acepta todas las props de `<svg>`
30
+
31
+ ## Patrones de Uso
32
+
33
+ ### Básico
34
+
35
+ ```tsx
36
+ <Spinner />
37
+ ```
38
+
39
+ ### Tamaños
40
+
41
+ ```tsx
42
+ <Spinner className="size-3" />
43
+ <Spinner className="size-4" /> {/* Default */}
44
+ <Spinner className="size-6" />
45
+ <Spinner className="size-8" />
46
+ ```
47
+
48
+ ### Colores
49
+
50
+ ```tsx
51
+ <Spinner className="text-primary" />
52
+ <Spinner className="text-destructive" />
53
+ <Spinner className="text-blue-500" />
54
+ ```
55
+
56
+ ### En Botones
57
+
58
+ ```tsx
59
+ import { Button } from "@adamosuiteservices/ui/button";
60
+
61
+ <Button disabled>
62
+ <Spinner />
63
+ Loading...
64
+ </Button>
65
+
66
+ <Button variant="outline" disabled>
67
+ <Spinner />
68
+ Please wait
69
+ </Button>
70
+ ```
71
+
72
+ ### Con Estado
73
+
74
+ ```tsx
75
+ import { useState } from "react";
76
+ import { Button } from "@adamosuiteservices/ui/button";
77
+
78
+ function App() {
79
+ const [isLoading, setIsLoading] = useState(false);
80
+
81
+ const handleClick = () => {
82
+ setIsLoading(true);
83
+ setTimeout(() => setIsLoading(false), 2000);
84
+ };
85
+
86
+ return (
87
+ <Button onClick={handleClick} disabled={isLoading}>
88
+ {isLoading ? (
89
+ <>
90
+ <Spinner />
91
+ Submitting...
92
+ </>
93
+ ) : (
94
+ "Submit Form"
95
+ )}
96
+ </Button>
97
+ );
98
+ }
99
+ ```
100
+
101
+ ### En Badges
102
+
103
+ ```tsx
104
+ import { Badge } from "@adamosuiteservices/ui/badge";
105
+
106
+ <Badge>
107
+ <Spinner />
108
+ Syncing
109
+ </Badge>;
110
+ ```
111
+
112
+ ### En Cards
113
+
114
+ ```tsx
115
+ import { Card, CardContent } from "@adamosuiteservices/ui/card";
116
+
117
+ <Card>
118
+ <CardContent className="flex items-center space-x-3 p-6">
119
+ <Spinner className="size-5" />
120
+ <span>Processing your payment...</span>
121
+ </CardContent>
122
+ </Card>;
123
+ ```
124
+
125
+ ### Inline
126
+
127
+ ```tsx
128
+ <p>
129
+ Loading data <Spinner className="inline size-4" />
130
+ </p>
131
+ ```
132
+
133
+ ## Casos de Uso
134
+
135
+ **Button loading**: Estados de carga en botones
136
+ **Badge status**: Indicador de sincronización/procesamiento
137
+ **Inline loading**: Texto con loading inline
138
+ **Cards**: Contenido de cards en proceso
139
+ **Global loading**: Indicadores globales de app
140
+
141
+ ## Estilos Base
142
+
143
+ - **Size**: `size-4` default
144
+ - **Animation**: `animate-spin`
145
+ - **Role**: `role="status"`
146
+ - **ARIA**: `aria-label="Loading"`
147
+
148
+ ## Accesibilidad
149
+
150
+ - ✅ **Role**: `role="status"`
151
+ - ✅ **ARIA**: `aria-label="Loading"` para screen readers
152
+ - ✅ **Screen readers**: Anuncia estado de carga
153
+
154
+ ## Notas de Implementación
155
+
156
+ - **Lucide React**: Usa `Loader2Icon` de lucide-react
157
+ - **Spin animation**: Tailwind `animate-spin`
158
+ - **SVG**: Componente SVG nativo
159
+ - **Customizable**: Tamaño y color via className
160
+
161
+ ## Troubleshooting
162
+
163
+ **No gira**: Verifica `animate-spin` aplicado
164
+ **Muy pequeño/grande**: Ajusta `size-*` en className
165
+ **Color incorrecto**: Usa `text-*` para cambiar color
166
+ **No se ve en button**: Asegúrate de espaciado con gap
167
+
168
+ ## Referencias
169
+
170
+ - **Lucide Icons**: <https://lucide.dev/icons/loader-2>