@adamosuiteservices/ui 2.11.17 → 2.11.19

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 (66) hide show
  1. package/dist/accordion-rounded.cjs +1 -1
  2. package/dist/accordion-rounded.js +1 -1
  3. package/dist/badge.cjs +3 -3
  4. package/dist/badge.js +2 -2
  5. package/dist/breadcrumb.cjs +5 -5
  6. package/dist/breadcrumb.js +16 -16
  7. package/dist/components/ui/date-picker-selector/date-picker-selector.d.ts +2 -2
  8. package/dist/components/ui/sheet/sheet.d.ts +2 -1
  9. package/dist/date-picker-selector.cjs +1 -1
  10. package/dist/date-picker-selector.js +29 -30
  11. package/dist/dialog.cjs +1 -1
  12. package/dist/dialog.js +1 -1
  13. package/dist/select.cjs +2 -2
  14. package/dist/select.js +2 -2
  15. package/dist/{sheet-DVT_djHX.cjs → sheet-CvcCaGSl.cjs} +11 -11
  16. package/dist/{sheet-CPf9Guon.js → sheet-IRIc3TJ1.js} +33 -19
  17. package/dist/sheet.cjs +1 -1
  18. package/dist/sheet.js +7 -6
  19. package/dist/sidebar.cjs +1 -1
  20. package/dist/sidebar.js +1 -1
  21. package/dist/styles.css +1 -1
  22. package/dist/tabs-underline.cjs +3 -3
  23. package/dist/tabs-underline.js +13 -13
  24. package/dist/tabs.cjs +5 -4
  25. package/dist/tabs.js +3 -2
  26. package/dist/themes.css +1 -1
  27. package/docs/AI-GUIDE.md +321 -321
  28. package/docs/components/layout/sidebar.md +399 -399
  29. package/docs/components/layout/toaster.md +436 -436
  30. package/docs/components/ui/accordion-rounded.md +584 -584
  31. package/docs/components/ui/accordion.md +269 -269
  32. package/docs/components/ui/badge.md +2 -1
  33. package/docs/components/ui/button-group.md +984 -984
  34. package/docs/components/ui/button.md +1137 -1137
  35. package/docs/components/ui/calendar.md +1159 -1159
  36. package/docs/components/ui/card.md +1455 -1455
  37. package/docs/components/ui/checkbox.md +292 -292
  38. package/docs/components/ui/collapsible.md +323 -323
  39. package/docs/components/ui/command.md +454 -454
  40. package/docs/components/ui/context-menu.md +540 -540
  41. package/docs/components/ui/date-picker-selector.md +0 -2
  42. package/docs/components/ui/dialog.md +628 -628
  43. package/docs/components/ui/dropdown-menu.md +709 -709
  44. package/docs/components/ui/field.md +706 -706
  45. package/docs/components/ui/hover-card.md +446 -446
  46. package/docs/components/ui/input.md +362 -362
  47. package/docs/components/ui/kbd.md +434 -434
  48. package/docs/components/ui/label.md +359 -359
  49. package/docs/components/ui/pagination.md +650 -650
  50. package/docs/components/ui/popover.md +536 -536
  51. package/docs/components/ui/progress.md +182 -182
  52. package/docs/components/ui/radio-group.md +311 -311
  53. package/docs/components/ui/select.md +352 -352
  54. package/docs/components/ui/separator.md +214 -214
  55. package/docs/components/ui/sheet.md +174 -142
  56. package/docs/components/ui/skeleton.md +140 -140
  57. package/docs/components/ui/slider.md +341 -341
  58. package/docs/components/ui/spinner.md +170 -170
  59. package/docs/components/ui/switch.md +408 -408
  60. package/docs/components/ui/tabs-underline.md +106 -106
  61. package/docs/components/ui/tabs.md +122 -122
  62. package/docs/components/ui/textarea.md +243 -243
  63. package/docs/components/ui/toggle.md +237 -237
  64. package/docs/components/ui/tooltip.md +317 -317
  65. package/docs/components/ui/typography.md +280 -280
  66. package/package.json +1 -1
@@ -1,341 +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>
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>