@adamosuiteservices/ui 1.8.13 → 1.9.14

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 (144) hide show
  1. package/dist/components/ui/icon/icon.d.ts +11 -0
  2. package/dist/components/ui/icon/icon.stories.d.ts +55 -0
  3. package/dist/components/ui/icon/index.d.ts +1 -0
  4. package/dist/components/ui/input-group/input-group.d.ts +1 -1
  5. package/dist/custom-layered-styles.css +1 -1
  6. package/dist/icon.cjs +6 -0
  7. package/dist/icon.js +36 -0
  8. package/dist/icons.css +1 -0
  9. package/dist/styles.css +1 -1
  10. package/docs/AI-GUIDE.md +321 -321
  11. package/docs/components/layout/sidebar.md +404 -404
  12. package/docs/components/layout/toaster.md +436 -436
  13. package/docs/components/ui/accordion-rounded.md +583 -583
  14. package/docs/components/ui/accordion.md +267 -267
  15. package/docs/components/ui/alert.md +671 -671
  16. package/docs/components/ui/avatar.md +588 -588
  17. package/docs/components/ui/badge.md +1024 -1024
  18. package/docs/components/ui/button-group.md +1002 -1002
  19. package/docs/components/ui/button.md +1078 -1078
  20. package/docs/components/ui/calendar.md +1159 -1159
  21. package/docs/components/ui/card.md +1265 -1265
  22. package/docs/components/ui/checkbox.md +292 -292
  23. package/docs/components/ui/collapsible.md +320 -320
  24. package/docs/components/ui/command.md +454 -454
  25. package/docs/components/ui/context-menu.md +540 -540
  26. package/docs/components/ui/dialog.md +628 -628
  27. package/docs/components/ui/dropdown-menu.md +731 -731
  28. package/docs/components/ui/field.md +706 -706
  29. package/docs/components/ui/hover-card.md +446 -446
  30. package/docs/components/ui/icon.md +502 -0
  31. package/docs/components/ui/input-group.md +509 -509
  32. package/docs/components/ui/input.md +362 -362
  33. package/docs/components/ui/kbd.md +434 -434
  34. package/docs/components/ui/label.md +359 -359
  35. package/docs/components/ui/pagination.md +650 -650
  36. package/docs/components/ui/popover.md +536 -536
  37. package/docs/components/ui/progress.md +182 -182
  38. package/docs/components/ui/radio-group.md +311 -311
  39. package/docs/components/ui/select.md +352 -352
  40. package/docs/components/ui/separator.md +214 -214
  41. package/docs/components/ui/sheet.md +142 -142
  42. package/docs/components/ui/skeleton.md +140 -140
  43. package/docs/components/ui/slider.md +341 -341
  44. package/docs/components/ui/spinner.md +170 -170
  45. package/docs/components/ui/switch.md +402 -402
  46. package/docs/components/ui/table.md +183 -183
  47. package/docs/components/ui/tabs-underline.md +106 -106
  48. package/docs/components/ui/tabs.md +122 -122
  49. package/docs/components/ui/textarea.md +243 -243
  50. package/docs/components/ui/toggle.md +243 -243
  51. package/docs/components/ui/tooltip.md +320 -320
  52. package/docs/components/ui/typography.md +191 -191
  53. package/package.json +6 -5
  54. package/dist/components/icons/account-balance-icon.d.ts +0 -3
  55. package/dist/components/icons/account-icon.d.ts +0 -3
  56. package/dist/components/icons/add-circle-icon.d.ts +0 -3
  57. package/dist/components/icons/alarm-icon.d.ts +0 -3
  58. package/dist/components/icons/archive-icon.d.ts +0 -3
  59. package/dist/components/icons/arrow-back-icon.d.ts +0 -3
  60. package/dist/components/icons/arrow-circle-up-icon.d.ts +0 -3
  61. package/dist/components/icons/arrow-forward-icon.d.ts +0 -3
  62. package/dist/components/icons/arrow-outward-icon.d.ts +0 -3
  63. package/dist/components/icons/article-icon.d.ts +0 -3
  64. package/dist/components/icons/attach-file-icon.d.ts +0 -3
  65. package/dist/components/icons/autorenew-icon.d.ts +0 -3
  66. package/dist/components/icons/bookmark-icon.d.ts +0 -3
  67. package/dist/components/icons/calculate-icon.d.ts +0 -3
  68. package/dist/components/icons/calendar-today-icon.d.ts +0 -3
  69. package/dist/components/icons/call-split-icon.d.ts +0 -3
  70. package/dist/components/icons/cancel-filled-icon.d.ts +0 -3
  71. package/dist/components/icons/cancel-icon.d.ts +0 -3
  72. package/dist/components/icons/check-circle-icon.d.ts +0 -3
  73. package/dist/components/icons/check-icon.d.ts +0 -3
  74. package/dist/components/icons/chevron-back-icon.d.ts +0 -3
  75. package/dist/components/icons/chevron-down-icon.d.ts +0 -3
  76. package/dist/components/icons/chevron-forward-icon.d.ts +0 -3
  77. package/dist/components/icons/chevron-up-icon.d.ts +0 -3
  78. package/dist/components/icons/clarify-icon.d.ts +0 -3
  79. package/dist/components/icons/clock-icon.d.ts +0 -3
  80. package/dist/components/icons/close-icon.d.ts +0 -3
  81. package/dist/components/icons/confirmation-number-icon.d.ts +0 -3
  82. package/dist/components/icons/contacts-icon.d.ts +0 -3
  83. package/dist/components/icons/contract-delete-icon.d.ts +0 -3
  84. package/dist/components/icons/copy-icon.d.ts +0 -3
  85. package/dist/components/icons/do-not-touch-icon.d.ts +0 -3
  86. package/dist/components/icons/download-icon.d.ts +0 -3
  87. package/dist/components/icons/dragger-icon.d.ts +0 -3
  88. package/dist/components/icons/edit-icon.d.ts +0 -3
  89. package/dist/components/icons/edit-square-icon.d.ts +0 -3
  90. package/dist/components/icons/exclamation-icon.d.ts +0 -3
  91. package/dist/components/icons/expand-circle-right-icon.d.ts +0 -3
  92. package/dist/components/icons/feature-search-icon.d.ts +0 -3
  93. package/dist/components/icons/filter-icon.d.ts +0 -3
  94. package/dist/components/icons/folder-icon.d.ts +0 -3
  95. package/dist/components/icons/folder-open-icon.d.ts +0 -3
  96. package/dist/components/icons/format-list-bulleted-icon.d.ts +0 -3
  97. package/dist/components/icons/hamburger-menu-icon.d.ts +0 -3
  98. package/dist/components/icons/help-icon.d.ts +0 -3
  99. package/dist/components/icons/hide-pass-icon.d.ts +0 -3
  100. package/dist/components/icons/home-icon.d.ts +0 -3
  101. package/dist/components/icons/id-card-icon.d.ts +0 -3
  102. package/dist/components/icons/index.d.ts +0 -88
  103. package/dist/components/icons/info-icon.d.ts +0 -3
  104. package/dist/components/icons/kid-star-icon.d.ts +0 -3
  105. package/dist/components/icons/language-icon.d.ts +0 -3
  106. package/dist/components/icons/last-page-icon.d.ts +0 -3
  107. package/dist/components/icons/layers-icon.d.ts +0 -3
  108. package/dist/components/icons/location-icon.d.ts +0 -3
  109. package/dist/components/icons/mail-icon.d.ts +0 -3
  110. package/dist/components/icons/manage-search-icon.d.ts +0 -3
  111. package/dist/components/icons/menu-icon.d.ts +0 -3
  112. package/dist/components/icons/message-icon.d.ts +0 -3
  113. package/dist/components/icons/metrics-icon.d.ts +0 -3
  114. package/dist/components/icons/mic-icon.d.ts +0 -3
  115. package/dist/components/icons/minus-icon.d.ts +0 -3
  116. package/dist/components/icons/mode-comment-icon.d.ts +0 -3
  117. package/dist/components/icons/money-icon.d.ts +0 -3
  118. package/dist/components/icons/monitoring-icon.d.ts +0 -3
  119. package/dist/components/icons/more-icon.d.ts +0 -3
  120. package/dist/components/icons/notifications-icon.d.ts +0 -3
  121. package/dist/components/icons/open-in-new-icon.d.ts +0 -3
  122. package/dist/components/icons/palette-icon.d.ts +0 -3
  123. package/dist/components/icons/password-icon.d.ts +0 -3
  124. package/dist/components/icons/pending-icon.d.ts +0 -3
  125. package/dist/components/icons/person-add-icon.d.ts +0 -3
  126. package/dist/components/icons/person-search-icon.d.ts +0 -3
  127. package/dist/components/icons/photo-icon.d.ts +0 -3
  128. package/dist/components/icons/plus-icon.d.ts +0 -3
  129. package/dist/components/icons/policy-icon.d.ts +0 -3
  130. package/dist/components/icons/publish-icon.d.ts +0 -3
  131. package/dist/components/icons/ready-icon.d.ts +0 -3
  132. package/dist/components/icons/receipt-icon.d.ts +0 -3
  133. package/dist/components/icons/receive-icon.d.ts +0 -3
  134. package/dist/components/icons/refresh-icon.d.ts +0 -3
  135. package/dist/components/icons/search-icon.d.ts +0 -3
  136. package/dist/components/icons/see-icon.d.ts +0 -3
  137. package/dist/components/icons/send-icon.d.ts +0 -3
  138. package/dist/components/icons/settings-icon.d.ts +0 -3
  139. package/dist/components/icons/shield-icon.d.ts +0 -3
  140. package/dist/components/icons/swap-horiz-icon.d.ts +0 -3
  141. package/dist/components/icons/tag-icon.d.ts +0 -3
  142. package/dist/components/icons/trash-icon.d.ts +0 -3
  143. package/dist/icons.cjs +0 -1
  144. package/dist/icons.js +0 -1507
@@ -1,402 +1,402 @@
1
- # Switch
2
-
3
- Toggle binario on/off. Basado en Radix UI con animación de thumb.
4
-
5
- ## Descripción
6
-
7
- El componente `Switch` es un control de toggle que representa un estado booleano (on/off).
8
-
9
- ## Importación
10
-
11
- ```typescript
12
- import { Switch } from "@adamosuiteservices/ui/switch";
13
- ```
14
-
15
- ## Anatomía
16
-
17
- ```tsx
18
- <Switch />
19
- ```
20
-
21
- **Componentes**: 1 (Switch) con thumb interno
22
-
23
- ## Props
24
-
25
- | Prop | Tipo | Descripción |
26
- | ----------------- | ---------------------------- | ----------------------------- |
27
- | `defaultChecked` | `boolean` | Estado inicial (uncontrolled) |
28
- | `checked` | `boolean` | Estado controlado |
29
- | `onCheckedChange` | `(checked: boolean) => void` | Callback al cambiar |
30
- | `disabled` | `boolean` | Deshabilita el switch |
31
- | `required` | `boolean` | Campo requerido |
32
- | `name` | `string` | Nombre (formularios) |
33
- | `value` | `string` | Valor (formularios) |
34
- | `id` | `string` | ID para asociar con Label |
35
- | `className` | `string` | Clases CSS adicionales |
36
-
37
- **Nota**: Acepta todas las props de Radix UI Switch.Root
38
-
39
- ## Patrones de Uso
40
-
41
- ### Básico
42
-
43
- ```tsx
44
- import { Switch } from "@adamosuiteservices/ui/switch";
45
-
46
- <Switch />;
47
- ```
48
-
49
- ### Con Label
50
-
51
- ```tsx
52
- import { Label } from "@adamosuiteservices/ui/label";
53
-
54
- <div className="flex items-center space-x-2">
55
- <Switch id="airplane-mode" />
56
- <Label htmlFor="airplane-mode">Airplane Mode</Label>
57
- </div>;
58
- ```
59
-
60
- ### Controlado
61
-
62
- ```tsx
63
- import { useState } from "react";
64
-
65
- function App() {
66
- const [isChecked, setIsChecked] = useState(false);
67
-
68
- return (
69
- <div className="flex items-center space-x-2">
70
- <Switch
71
- id="controlled-switch"
72
- checked={isChecked}
73
- onCheckedChange={setIsChecked}
74
- />
75
- <Label htmlFor="controlled-switch">
76
- Notifications {isChecked ? "enabled" : "disabled"}
77
- </Label>
78
- </div>
79
- );
80
- }
81
- ```
82
-
83
- ### Con Iconos y Badges
84
-
85
- ```tsx
86
- import { BellIcon, MoonIcon, WifiIcon } from "lucide-react";
87
- import { Badge } from "@adamosuiteservices/ui/badge";
88
-
89
- function Settings() {
90
- const [settings, setSettings] = useState({
91
- notifications: true,
92
- darkMode: false,
93
- wifi: true,
94
- });
95
-
96
- return (
97
- <div className="space-y-4">
98
- <div className="flex items-center space-x-3">
99
- <BellIcon className="size-4 text-muted-foreground" />
100
- <Switch
101
- checked={settings.notifications}
102
- onCheckedChange={(checked) =>
103
- setSettings((prev) => ({ ...prev, notifications: checked }))
104
- }
105
- />
106
- <Label>Notifications</Label>
107
- <Badge variant={settings.notifications ? "default" : "secondary"}>
108
- {settings.notifications ? "On" : "Off"}
109
- </Badge>
110
- </div>
111
-
112
- <div className="flex items-center space-x-3">
113
- <MoonIcon className="size-4 text-muted-foreground" />
114
- <Switch
115
- checked={settings.darkMode}
116
- onCheckedChange={(checked) =>
117
- setSettings((prev) => ({ ...prev, darkMode: checked }))
118
- }
119
- />
120
- <Label>Dark Mode</Label>
121
- <Badge variant={settings.darkMode ? "default" : "secondary"}>
122
- {settings.darkMode ? "On" : "Off"}
123
- </Badge>
124
- </div>
125
- </div>
126
- );
127
- }
128
- ```
129
-
130
- ### Device Controls
131
-
132
- ```tsx
133
- import {
134
- Card,
135
- CardContent,
136
- CardDescription,
137
- CardHeader,
138
- CardTitle,
139
- } from "@adamosuiteservices/ui/card";
140
- import { AirplayIcon, WifiIcon, BluetoothIcon } from "lucide-react";
141
-
142
- function ControlCenter() {
143
- const [deviceSettings, setDeviceSettings] = useState({
144
- airplaneMode: false,
145
- wifi: true,
146
- bluetooth: false,
147
- });
148
-
149
- const updateSetting = (key: keyof typeof deviceSettings) => {
150
- setDeviceSettings((prev) => ({ ...prev, [key]: !prev[key] }));
151
- };
152
-
153
- return (
154
- <Card className="w-full max-w-sm">
155
- <CardHeader>
156
- <CardTitle>Control Center</CardTitle>
157
- <CardDescription>Quick access to device settings</CardDescription>
158
- </CardHeader>
159
- <CardContent className="space-y-4">
160
- <div className="grid grid-cols-2 gap-4">
161
- <div className="flex flex-col items-center space-y-2 p-3 border rounded-lg">
162
- <AirplayIcon className="size-6 text-muted-foreground" />
163
- <span className="text-sm font-medium">Airplane</span>
164
- <Switch
165
- checked={deviceSettings.airplaneMode}
166
- onCheckedChange={() => updateSetting("airplaneMode")}
167
- className="scale-75"
168
- />
169
- </div>
170
-
171
- <div className="flex flex-col items-center space-y-2 p-3 border rounded-lg">
172
- <WifiIcon className="size-6 text-muted-foreground" />
173
- <span className="text-sm font-medium">Wi-Fi</span>
174
- <Switch
175
- checked={deviceSettings.wifi}
176
- onCheckedChange={() => updateSetting("wifi")}
177
- className="scale-75"
178
- />
179
- </div>
180
-
181
- <div className="flex flex-col items-center space-y-2 p-3 border rounded-lg">
182
- <BluetoothIcon className="size-6 text-muted-foreground" />
183
- <span className="text-sm font-medium">Bluetooth</span>
184
- <Switch
185
- checked={deviceSettings.bluetooth}
186
- onCheckedChange={() => updateSetting("bluetooth")}
187
- className="scale-75"
188
- />
189
- </div>
190
- </div>
191
- </CardContent>
192
- </Card>
193
- );
194
- }
195
- ```
196
-
197
- ### Privacy Settings
198
-
199
- ```tsx
200
- import { ShieldIcon } from "lucide-react";
201
- import { Button } from "@adamosuiteservices/ui/button";
202
-
203
- function PrivacySettings() {
204
- const [privacySettings, setPrivacySettings] = useState({
205
- locationServices: true,
206
- analyticsData: false,
207
- crashReports: true,
208
- personalizedAds: false,
209
- });
210
-
211
- return (
212
- <Card className="w-full max-w-lg">
213
- <CardHeader>
214
- <CardTitle className="flex items-center space-x-2">
215
- <ShieldIcon className="size-5" />
216
- <span>Privacy & Security</span>
217
- </CardTitle>
218
- <CardDescription>
219
- Control how your data is collected and used
220
- </CardDescription>
221
- </CardHeader>
222
- <CardContent className="space-y-6">
223
- <div className="space-y-4">
224
- <div className="flex items-start justify-between space-x-4">
225
- <div className="flex-1">
226
- <Label className="text-sm font-medium">Location Services</Label>
227
- <p className="text-xs text-muted-foreground mt-1">
228
- Allow apps to access your location for personalized experiences
229
- </p>
230
- </div>
231
- <Switch
232
- checked={privacySettings.locationServices}
233
- onCheckedChange={(checked) =>
234
- setPrivacySettings((prev) => ({
235
- ...prev,
236
- locationServices: checked,
237
- }))
238
- }
239
- />
240
- </div>
241
-
242
- <div className="flex items-start justify-between space-x-4">
243
- <div className="flex-1">
244
- <Label className="text-sm font-medium">
245
- Analytics & Diagnostics
246
- </Label>
247
- <p className="text-xs text-muted-foreground mt-1">
248
- Share analytics data to help improve our products
249
- </p>
250
- </div>
251
- <Switch
252
- checked={privacySettings.analyticsData}
253
- onCheckedChange={(checked) =>
254
- setPrivacySettings((prev) => ({
255
- ...prev,
256
- analyticsData: checked,
257
- }))
258
- }
259
- />
260
- </div>
261
- </div>
262
-
263
- <div className="flex justify-end space-x-2 pt-4 border-t">
264
- <Button variant="outline" size="sm">
265
- Reset to Defaults
266
- </Button>
267
- <Button size="sm">Save Changes</Button>
268
- </div>
269
- </CardContent>
270
- </Card>
271
- );
272
- }
273
- ```
274
-
275
- ### Feature Toggles
276
-
277
- ```tsx
278
- function FeatureToggles() {
279
- const [features, setFeatures] = useState({
280
- newDashboard: false,
281
- betaFeatures: false,
282
- experimentalUI: false,
283
- });
284
-
285
- const updateFeature = (key: keyof typeof features) => {
286
- setFeatures((prev) => ({ ...prev, [key]: !prev[key] }));
287
- };
288
-
289
- return (
290
- <Card className="w-full max-w-lg">
291
- <CardHeader>
292
- <CardTitle>Feature Toggles</CardTitle>
293
- <CardDescription>
294
- Enable or disable experimental features
295
- </CardDescription>
296
- </CardHeader>
297
- <CardContent className="space-y-4">
298
- <div className="flex items-start justify-between space-x-4 p-3 border rounded-lg">
299
- <div className="flex-1 space-y-1">
300
- <div className="flex items-center space-x-2">
301
- <Label className="text-sm font-medium">New Dashboard</Label>
302
- <Badge variant="default" className="text-xs">
303
- New
304
- </Badge>
305
- </div>
306
- <p className="text-xs text-muted-foreground">
307
- Try our redesigned dashboard interface
308
- </p>
309
- </div>
310
- <Switch
311
- checked={features.newDashboard}
312
- onCheckedChange={() => updateFeature("newDashboard")}
313
- />
314
- </div>
315
-
316
- <div className="flex items-start justify-between space-x-4 p-3 border rounded-lg">
317
- <div className="flex-1 space-y-1">
318
- <div className="flex items-center space-x-2">
319
- <Label className="text-sm font-medium">Beta Features</Label>
320
- <Badge variant="secondary" className="text-xs">
321
- Beta
322
- </Badge>
323
- </div>
324
- <p className="text-xs text-muted-foreground">
325
- Access features currently in beta testing
326
- </p>
327
- </div>
328
- <Switch
329
- checked={features.betaFeatures}
330
- onCheckedChange={() => updateFeature("betaFeatures")}
331
- />
332
- </div>
333
- </CardContent>
334
- </Card>
335
- );
336
- }
337
- ```
338
-
339
- ### Deshabilitado
340
-
341
- ```tsx
342
- <div className="space-y-4">
343
- <div className="flex items-center space-x-2">
344
- <Switch disabled />
345
- <Label className="text-muted-foreground">Disabled (off)</Label>
346
- </div>
347
- <div className="flex items-center space-x-2">
348
- <Switch disabled checked />
349
- <Label className="text-muted-foreground">Disabled (on)</Label>
350
- </div>
351
- </div>
352
- ```
353
-
354
- ## Casos de Uso
355
-
356
- **Settings**: On/off toggles para configuración
357
- **Feature flags**: Activar/desactivar features
358
- **Notifications**: Habilitar/deshabilitar notificaciones
359
- **Privacy**: Controles de privacidad y permisos
360
- **Device controls**: Wi-Fi, Bluetooth, Airplane mode
361
- **Filters**: Mostrar/ocultar contenido
362
-
363
- ## Estilos Base
364
-
365
- - **Size**: `h-5 w-8`
366
- - **Checked bg**: `bg-primary`
367
- - **Unchecked bg**: `bg-input` (dark: `bg-input/80`)
368
- - **Thumb**: `size-4` con `bg-background`
369
- - **Thumb checked**: `translate-x-[calc(100%-2px)]`
370
- - **Thumb unchecked**: `translate-x-0`
371
- - **Focus**: `ring-ring/50` con `ring-[3px]`
372
- - **Transition**: `transition-all` en thumb y background
373
-
374
- ## Accesibilidad
375
-
376
- - ✅ **Role**: `role="switch"` con `aria-checked`
377
- - ✅ **Keyboard**: Space/Enter para toggle
378
- - ✅ **Focus**: Focus ring visible
379
- - ✅ **Label**: Asociar con `htmlFor` e `id`
380
- - ✅ **State**: Screen readers anuncian checked/unchecked
381
-
382
- ## Notas de Implementación
383
-
384
- - **Radix UI**: Basado en `@radix-ui/react-switch`
385
- - **Peer class**: Usa `peer` para estilos relacionados con Label
386
- - **Data states**: `data-state="checked|unchecked"` para estilos
387
- - **Controlled**: Usa `checked` + `onCheckedChange`
388
- - **Uncontrolled**: Usa `defaultChecked`
389
- - **Dark mode**: Thumb color cambia automáticamente
390
-
391
- ## Troubleshooting
392
-
393
- **No cambia estado**: En modo controlado usa `checked` + `onCheckedChange`, no `defaultChecked`
394
- **Label no clickeable**: Asegura `htmlFor` en Label coincida con `id` del Switch
395
- **Thumb no anima**: Verifica que estilos de `transition-transform` no estén sobrescritos
396
- **Color incorrecto**: Switch usa `bg-primary` checked, `bg-input` unchecked
397
- **Disabled no funciona**: Prop `disabled` deshabilita interacción
398
-
399
- ## Referencias
400
-
401
- - **Radix UI Switch**: <https://www.radix-ui.com/primitives/docs/components/switch>
402
- - **shadcn/ui Switch**: <https://ui.shadcn.com/docs/components/switch>
1
+ # Switch
2
+
3
+ Toggle binario on/off. Basado en Radix UI con animación de thumb.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Switch` es un control de toggle que representa un estado booleano (on/off).
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import { Switch } from "@adamosuiteservices/ui/switch";
13
+ ```
14
+
15
+ ## Anatomía
16
+
17
+ ```tsx
18
+ <Switch />
19
+ ```
20
+
21
+ **Componentes**: 1 (Switch) con thumb interno
22
+
23
+ ## Props
24
+
25
+ | Prop | Tipo | Descripción |
26
+ | ----------------- | ---------------------------- | ----------------------------- |
27
+ | `defaultChecked` | `boolean` | Estado inicial (uncontrolled) |
28
+ | `checked` | `boolean` | Estado controlado |
29
+ | `onCheckedChange` | `(checked: boolean) => void` | Callback al cambiar |
30
+ | `disabled` | `boolean` | Deshabilita el switch |
31
+ | `required` | `boolean` | Campo requerido |
32
+ | `name` | `string` | Nombre (formularios) |
33
+ | `value` | `string` | Valor (formularios) |
34
+ | `id` | `string` | ID para asociar con Label |
35
+ | `className` | `string` | Clases CSS adicionales |
36
+
37
+ **Nota**: Acepta todas las props de Radix UI Switch.Root
38
+
39
+ ## Patrones de Uso
40
+
41
+ ### Básico
42
+
43
+ ```tsx
44
+ import { Switch } from "@adamosuiteservices/ui/switch";
45
+
46
+ <Switch />;
47
+ ```
48
+
49
+ ### Con Label
50
+
51
+ ```tsx
52
+ import { Label } from "@adamosuiteservices/ui/label";
53
+
54
+ <div className="flex items-center space-x-2">
55
+ <Switch id="airplane-mode" />
56
+ <Label htmlFor="airplane-mode">Airplane Mode</Label>
57
+ </div>;
58
+ ```
59
+
60
+ ### Controlado
61
+
62
+ ```tsx
63
+ import { useState } from "react";
64
+
65
+ function App() {
66
+ const [isChecked, setIsChecked] = useState(false);
67
+
68
+ return (
69
+ <div className="flex items-center space-x-2">
70
+ <Switch
71
+ id="controlled-switch"
72
+ checked={isChecked}
73
+ onCheckedChange={setIsChecked}
74
+ />
75
+ <Label htmlFor="controlled-switch">
76
+ Notifications {isChecked ? "enabled" : "disabled"}
77
+ </Label>
78
+ </div>
79
+ );
80
+ }
81
+ ```
82
+
83
+ ### Con Iconos y Badges
84
+
85
+ ```tsx
86
+ import { BellIcon, MoonIcon, WifiIcon } from "lucide-react";
87
+ import { Badge } from "@adamosuiteservices/ui/badge";
88
+
89
+ function Settings() {
90
+ const [settings, setSettings] = useState({
91
+ notifications: true,
92
+ darkMode: false,
93
+ wifi: true,
94
+ });
95
+
96
+ return (
97
+ <div className="space-y-4">
98
+ <div className="flex items-center space-x-3">
99
+ <BellIcon className="size-4 text-muted-foreground" />
100
+ <Switch
101
+ checked={settings.notifications}
102
+ onCheckedChange={(checked) =>
103
+ setSettings((prev) => ({ ...prev, notifications: checked }))
104
+ }
105
+ />
106
+ <Label>Notifications</Label>
107
+ <Badge variant={settings.notifications ? "default" : "secondary"}>
108
+ {settings.notifications ? "On" : "Off"}
109
+ </Badge>
110
+ </div>
111
+
112
+ <div className="flex items-center space-x-3">
113
+ <MoonIcon className="size-4 text-muted-foreground" />
114
+ <Switch
115
+ checked={settings.darkMode}
116
+ onCheckedChange={(checked) =>
117
+ setSettings((prev) => ({ ...prev, darkMode: checked }))
118
+ }
119
+ />
120
+ <Label>Dark Mode</Label>
121
+ <Badge variant={settings.darkMode ? "default" : "secondary"}>
122
+ {settings.darkMode ? "On" : "Off"}
123
+ </Badge>
124
+ </div>
125
+ </div>
126
+ );
127
+ }
128
+ ```
129
+
130
+ ### Device Controls
131
+
132
+ ```tsx
133
+ import {
134
+ Card,
135
+ CardContent,
136
+ CardDescription,
137
+ CardHeader,
138
+ CardTitle,
139
+ } from "@adamosuiteservices/ui/card";
140
+ import { AirplayIcon, WifiIcon, BluetoothIcon } from "lucide-react";
141
+
142
+ function ControlCenter() {
143
+ const [deviceSettings, setDeviceSettings] = useState({
144
+ airplaneMode: false,
145
+ wifi: true,
146
+ bluetooth: false,
147
+ });
148
+
149
+ const updateSetting = (key: keyof typeof deviceSettings) => {
150
+ setDeviceSettings((prev) => ({ ...prev, [key]: !prev[key] }));
151
+ };
152
+
153
+ return (
154
+ <Card className="w-full max-w-sm">
155
+ <CardHeader>
156
+ <CardTitle>Control Center</CardTitle>
157
+ <CardDescription>Quick access to device settings</CardDescription>
158
+ </CardHeader>
159
+ <CardContent className="space-y-4">
160
+ <div className="grid grid-cols-2 gap-4">
161
+ <div className="flex flex-col items-center space-y-2 p-3 border rounded-lg">
162
+ <AirplayIcon className="size-6 text-muted-foreground" />
163
+ <span className="text-sm font-medium">Airplane</span>
164
+ <Switch
165
+ checked={deviceSettings.airplaneMode}
166
+ onCheckedChange={() => updateSetting("airplaneMode")}
167
+ className="scale-75"
168
+ />
169
+ </div>
170
+
171
+ <div className="flex flex-col items-center space-y-2 p-3 border rounded-lg">
172
+ <WifiIcon className="size-6 text-muted-foreground" />
173
+ <span className="text-sm font-medium">Wi-Fi</span>
174
+ <Switch
175
+ checked={deviceSettings.wifi}
176
+ onCheckedChange={() => updateSetting("wifi")}
177
+ className="scale-75"
178
+ />
179
+ </div>
180
+
181
+ <div className="flex flex-col items-center space-y-2 p-3 border rounded-lg">
182
+ <BluetoothIcon className="size-6 text-muted-foreground" />
183
+ <span className="text-sm font-medium">Bluetooth</span>
184
+ <Switch
185
+ checked={deviceSettings.bluetooth}
186
+ onCheckedChange={() => updateSetting("bluetooth")}
187
+ className="scale-75"
188
+ />
189
+ </div>
190
+ </div>
191
+ </CardContent>
192
+ </Card>
193
+ );
194
+ }
195
+ ```
196
+
197
+ ### Privacy Settings
198
+
199
+ ```tsx
200
+ import { ShieldIcon } from "lucide-react";
201
+ import { Button } from "@adamosuiteservices/ui/button";
202
+
203
+ function PrivacySettings() {
204
+ const [privacySettings, setPrivacySettings] = useState({
205
+ locationServices: true,
206
+ analyticsData: false,
207
+ crashReports: true,
208
+ personalizedAds: false,
209
+ });
210
+
211
+ return (
212
+ <Card className="w-full max-w-lg">
213
+ <CardHeader>
214
+ <CardTitle className="flex items-center space-x-2">
215
+ <ShieldIcon className="size-5" />
216
+ <span>Privacy & Security</span>
217
+ </CardTitle>
218
+ <CardDescription>
219
+ Control how your data is collected and used
220
+ </CardDescription>
221
+ </CardHeader>
222
+ <CardContent className="space-y-6">
223
+ <div className="space-y-4">
224
+ <div className="flex items-start justify-between space-x-4">
225
+ <div className="flex-1">
226
+ <Label className="text-sm font-medium">Location Services</Label>
227
+ <p className="text-xs text-muted-foreground mt-1">
228
+ Allow apps to access your location for personalized experiences
229
+ </p>
230
+ </div>
231
+ <Switch
232
+ checked={privacySettings.locationServices}
233
+ onCheckedChange={(checked) =>
234
+ setPrivacySettings((prev) => ({
235
+ ...prev,
236
+ locationServices: checked,
237
+ }))
238
+ }
239
+ />
240
+ </div>
241
+
242
+ <div className="flex items-start justify-between space-x-4">
243
+ <div className="flex-1">
244
+ <Label className="text-sm font-medium">
245
+ Analytics & Diagnostics
246
+ </Label>
247
+ <p className="text-xs text-muted-foreground mt-1">
248
+ Share analytics data to help improve our products
249
+ </p>
250
+ </div>
251
+ <Switch
252
+ checked={privacySettings.analyticsData}
253
+ onCheckedChange={(checked) =>
254
+ setPrivacySettings((prev) => ({
255
+ ...prev,
256
+ analyticsData: checked,
257
+ }))
258
+ }
259
+ />
260
+ </div>
261
+ </div>
262
+
263
+ <div className="flex justify-end space-x-2 pt-4 border-t">
264
+ <Button variant="outline" size="sm">
265
+ Reset to Defaults
266
+ </Button>
267
+ <Button size="sm">Save Changes</Button>
268
+ </div>
269
+ </CardContent>
270
+ </Card>
271
+ );
272
+ }
273
+ ```
274
+
275
+ ### Feature Toggles
276
+
277
+ ```tsx
278
+ function FeatureToggles() {
279
+ const [features, setFeatures] = useState({
280
+ newDashboard: false,
281
+ betaFeatures: false,
282
+ experimentalUI: false,
283
+ });
284
+
285
+ const updateFeature = (key: keyof typeof features) => {
286
+ setFeatures((prev) => ({ ...prev, [key]: !prev[key] }));
287
+ };
288
+
289
+ return (
290
+ <Card className="w-full max-w-lg">
291
+ <CardHeader>
292
+ <CardTitle>Feature Toggles</CardTitle>
293
+ <CardDescription>
294
+ Enable or disable experimental features
295
+ </CardDescription>
296
+ </CardHeader>
297
+ <CardContent className="space-y-4">
298
+ <div className="flex items-start justify-between space-x-4 p-3 border rounded-lg">
299
+ <div className="flex-1 space-y-1">
300
+ <div className="flex items-center space-x-2">
301
+ <Label className="text-sm font-medium">New Dashboard</Label>
302
+ <Badge variant="default" className="text-xs">
303
+ New
304
+ </Badge>
305
+ </div>
306
+ <p className="text-xs text-muted-foreground">
307
+ Try our redesigned dashboard interface
308
+ </p>
309
+ </div>
310
+ <Switch
311
+ checked={features.newDashboard}
312
+ onCheckedChange={() => updateFeature("newDashboard")}
313
+ />
314
+ </div>
315
+
316
+ <div className="flex items-start justify-between space-x-4 p-3 border rounded-lg">
317
+ <div className="flex-1 space-y-1">
318
+ <div className="flex items-center space-x-2">
319
+ <Label className="text-sm font-medium">Beta Features</Label>
320
+ <Badge variant="secondary" className="text-xs">
321
+ Beta
322
+ </Badge>
323
+ </div>
324
+ <p className="text-xs text-muted-foreground">
325
+ Access features currently in beta testing
326
+ </p>
327
+ </div>
328
+ <Switch
329
+ checked={features.betaFeatures}
330
+ onCheckedChange={() => updateFeature("betaFeatures")}
331
+ />
332
+ </div>
333
+ </CardContent>
334
+ </Card>
335
+ );
336
+ }
337
+ ```
338
+
339
+ ### Deshabilitado
340
+
341
+ ```tsx
342
+ <div className="space-y-4">
343
+ <div className="flex items-center space-x-2">
344
+ <Switch disabled />
345
+ <Label className="text-muted-foreground">Disabled (off)</Label>
346
+ </div>
347
+ <div className="flex items-center space-x-2">
348
+ <Switch disabled checked />
349
+ <Label className="text-muted-foreground">Disabled (on)</Label>
350
+ </div>
351
+ </div>
352
+ ```
353
+
354
+ ## Casos de Uso
355
+
356
+ **Settings**: On/off toggles para configuración
357
+ **Feature flags**: Activar/desactivar features
358
+ **Notifications**: Habilitar/deshabilitar notificaciones
359
+ **Privacy**: Controles de privacidad y permisos
360
+ **Device controls**: Wi-Fi, Bluetooth, Airplane mode
361
+ **Filters**: Mostrar/ocultar contenido
362
+
363
+ ## Estilos Base
364
+
365
+ - **Size**: `h-5 w-8`
366
+ - **Checked bg**: `bg-primary`
367
+ - **Unchecked bg**: `bg-input` (dark: `bg-input/80`)
368
+ - **Thumb**: `size-4` con `bg-background`
369
+ - **Thumb checked**: `translate-x-[calc(100%-2px)]`
370
+ - **Thumb unchecked**: `translate-x-0`
371
+ - **Focus**: `ring-ring/50` con `ring-[3px]`
372
+ - **Transition**: `transition-all` en thumb y background
373
+
374
+ ## Accesibilidad
375
+
376
+ - ✅ **Role**: `role="switch"` con `aria-checked`
377
+ - ✅ **Keyboard**: Space/Enter para toggle
378
+ - ✅ **Focus**: Focus ring visible
379
+ - ✅ **Label**: Asociar con `htmlFor` e `id`
380
+ - ✅ **State**: Screen readers anuncian checked/unchecked
381
+
382
+ ## Notas de Implementación
383
+
384
+ - **Radix UI**: Basado en `@radix-ui/react-switch`
385
+ - **Peer class**: Usa `peer` para estilos relacionados con Label
386
+ - **Data states**: `data-state="checked|unchecked"` para estilos
387
+ - **Controlled**: Usa `checked` + `onCheckedChange`
388
+ - **Uncontrolled**: Usa `defaultChecked`
389
+ - **Dark mode**: Thumb color cambia automáticamente
390
+
391
+ ## Troubleshooting
392
+
393
+ **No cambia estado**: En modo controlado usa `checked` + `onCheckedChange`, no `defaultChecked`
394
+ **Label no clickeable**: Asegura `htmlFor` en Label coincida con `id` del Switch
395
+ **Thumb no anima**: Verifica que estilos de `transition-transform` no estén sobrescritos
396
+ **Color incorrecto**: Switch usa `bg-primary` checked, `bg-input` unchecked
397
+ **Disabled no funciona**: Prop `disabled` deshabilita interacción
398
+
399
+ ## Referencias
400
+
401
+ - **Radix UI Switch**: <https://www.radix-ui.com/primitives/docs/components/switch>
402
+ - **shadcn/ui Switch**: <https://ui.shadcn.com/docs/components/switch>