@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.
- package/README.md +4 -0
- package/dist/accordion-rounded.cjs +1 -1
- package/dist/accordion-rounded.js +1 -1
- package/dist/accordion.cjs +1 -1
- package/dist/accordion.js +1 -1
- package/dist/avatar.cjs +1 -1
- package/dist/avatar.js +1 -1
- package/dist/badge.cjs +1 -1
- package/dist/badge.js +1 -1
- package/dist/breadcrumb.cjs +1 -0
- package/dist/breadcrumb.js +105 -0
- package/dist/{button-C1n6snOY.js → button-2GdKenQI.js} +1 -1
- package/dist/{button-BV-_FVKZ.cjs → button-DEQVHMrX.cjs} +1 -1
- package/dist/button-group.cjs +1 -1
- package/dist/button-group.js +2 -2
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.js +1 -1
- package/dist/{checkbox-BrmXPKTn.js → checkbox-Dr487kAg.js} +3 -3
- package/dist/{checkbox-Lq-HvSgc.cjs → checkbox-YWAnswaW.cjs} +1 -1
- package/dist/checkbox.cjs +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/collapsible.cjs +1 -1
- package/dist/collapsible.js +1 -1
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.js +6 -6
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +11 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.d.ts +26 -0
- package/dist/components/ui/breadcrumb/index.d.ts +1 -0
- package/dist/components/ui/dialog/dialog.d.ts +2 -1
- package/dist/context-menu.cjs +1 -1
- package/dist/context-menu.js +2 -2
- package/dist/custom-layered-styles.css +1 -1
- package/dist/dialog.cjs +1 -1
- package/dist/dialog.js +33 -19
- package/dist/dropdown-menu.cjs +1 -1
- package/dist/dropdown-menu.js +3 -3
- package/dist/ellipsis-CryjZKZn.js +15 -0
- package/dist/ellipsis-Ct9VTDOG.cjs +6 -0
- package/dist/field.cjs +1 -1
- package/dist/field.js +2 -2
- package/dist/hover-card.cjs +1 -1
- package/dist/hover-card.js +6 -6
- package/dist/{index-CAOY367Y.js → index-B0M7VOwp.js} +2 -2
- package/dist/{index-B-ZRqW0J.js → index-BBoIAjAs.js} +3 -3
- package/dist/{index-gO_QEiaK.cjs → index-BDs8lUfq.cjs} +1 -1
- package/dist/index-BFyr34mw.cjs +5 -0
- package/dist/index-BMWt1NBG.js +79 -0
- package/dist/{index-yR-v1A4G.js → index-BX9hz-JD.js} +1 -1
- package/dist/{index-BGiGvaq8.cjs → index-BcGMAmWE.cjs} +1 -1
- package/dist/{index-IKJMQref.cjs → index-Bd0gQB0k.cjs} +1 -1
- package/dist/{index-VIUqZjyP.cjs → index-BeWgla7c.cjs} +1 -1
- package/dist/{index-EUea2gfp.js → index-BpWB3aFK.js} +1 -1
- package/dist/index-BvLQnI56.js +59 -0
- package/dist/{index-CwUFT-GQ.js → index-C0YiLSjW.js} +4 -4
- package/dist/{index-o0sNTcKe.js → index-CBjZooac.js} +2 -2
- package/dist/{index-DnS_sBBe.cjs → index-COuvjZLM.cjs} +1 -1
- package/dist/index-CTjlbbt9.cjs +1 -0
- package/dist/index-CUWMxxKG.js +97 -0
- package/dist/{index-C329e3yQ.js → index-CZZ3llmi.js} +2 -2
- package/dist/index-CjyiloO7.cjs +1 -0
- package/dist/{index-D3wSWKST.cjs → index-Cmx9M9cZ.cjs} +1 -1
- package/dist/index-CocSS1YK.cjs +1 -0
- package/dist/index-CzRiuk60.cjs +1 -0
- package/dist/index-DFPDUUq7.js +658 -0
- package/dist/{index-D3S7dBDI.cjs → index-DIwmXz1u.cjs} +1 -1
- package/dist/index-DLcqcWxM.js +29 -0
- package/dist/index-DMLQL2aG.js +286 -0
- package/dist/{index-DXQ-7kNJ.cjs → index-DMs8RL3E.cjs} +1 -1
- package/dist/{index-Ce3QBKyj.cjs → index-Dbj9vHNq.cjs} +1 -1
- package/dist/{index-BRLtxFFr.cjs → index-DmGzwG2z.cjs} +1 -1
- package/dist/{index-P1sVIHE3.js → index-PYkEXTqJ.js} +1 -1
- package/dist/{index-DulPG3F9.js → index-Se4vRnIO.js} +3 -3
- package/dist/index-_XxjJPRD.cjs +1 -0
- package/dist/{index-B-cHTKrs.js → index-yWvyIlmA.js} +4 -4
- package/dist/input-group.cjs +1 -1
- package/dist/input-group.js +1 -1
- package/dist/{label-Cne2J57f.cjs → label-BjXORCBM.cjs} +1 -1
- package/dist/{label-Ky8qBEC3.js → label-CmwGvhy1.js} +1 -1
- package/dist/label.cjs +1 -1
- package/dist/label.js +1 -1
- package/dist/pagination.cjs +1 -6
- package/dist/pagination.js +58 -69
- package/dist/popover-3rIoNCXs.js +306 -0
- package/dist/popover-FCKBtFo-.cjs +1 -0
- package/dist/popover.cjs +1 -1
- package/dist/popover.js +1 -1
- package/dist/progress.cjs +1 -1
- package/dist/progress.js +1 -1
- package/dist/radio-group.cjs +1 -1
- package/dist/radio-group.js +5 -5
- package/dist/select.cjs +2 -2
- package/dist/select.js +585 -542
- package/dist/{separator-CGnu_jIu.cjs → separator-BaZqZZ9R.cjs} +1 -1
- package/dist/{separator-BH73A90k.js → separator-DR7lQjv9.js} +1 -1
- package/dist/separator.cjs +1 -1
- package/dist/separator.js +1 -1
- package/dist/{sheet-CcxnJ6LH.cjs → sheet-CU-sFSaJ.cjs} +1 -1
- package/dist/{sheet-_DVpQIVF.js → sheet-UZWAbdXr.js} +1 -1
- package/dist/sheet.cjs +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sidebar.cjs +1 -1
- package/dist/sidebar.js +4 -4
- package/dist/slider.cjs +1 -1
- package/dist/slider.js +3 -3
- package/dist/styles.css +1 -1
- package/dist/switch.cjs +1 -1
- package/dist/switch.js +2 -2
- package/dist/tabs-underline.cjs +1 -1
- package/dist/tabs-underline.js +1 -1
- package/dist/tabs.cjs +1 -1
- package/dist/tabs.js +1 -1
- package/dist/toaster.cjs +1 -1
- package/dist/toaster.js +1 -1
- package/dist/toggle.cjs +1 -1
- package/dist/toggle.js +1 -1
- package/dist/tooltip.cjs +1 -1
- package/dist/tooltip.js +114 -108
- package/dist/typography.cjs +1 -1
- package/dist/typography.js +16 -16
- package/docs/AI-GUIDE.md +321 -0
- package/docs/components/layout/sidebar.md +330 -0
- package/docs/components/layout/toaster.md +436 -0
- package/docs/components/ui/accordion-rounded.md +583 -0
- package/docs/components/ui/accordion.md +267 -0
- package/docs/components/ui/alert.md +671 -0
- package/docs/components/ui/avatar.md +588 -0
- package/docs/components/ui/badge.md +1024 -0
- package/docs/components/ui/breadcrumb.md +614 -0
- package/docs/components/ui/button-group.md +1002 -0
- package/docs/components/ui/button.md +1078 -0
- package/docs/components/ui/calendar.md +1159 -0
- package/docs/components/ui/card.md +1265 -0
- package/docs/components/ui/checkbox.md +292 -0
- package/docs/components/ui/collapsible.md +320 -0
- package/docs/components/ui/combobox.md +328 -0
- package/docs/components/ui/command.md +454 -0
- package/docs/components/ui/context-menu.md +540 -0
- package/docs/components/ui/dialog.md +628 -0
- package/docs/components/ui/dropdown-menu.md +731 -0
- package/docs/components/ui/field.md +706 -0
- package/docs/components/ui/hover-card.md +446 -0
- package/docs/components/ui/input-group.md +509 -0
- package/docs/components/ui/input.md +362 -0
- package/docs/components/ui/kbd.md +434 -0
- package/docs/components/ui/label.md +359 -0
- package/docs/components/ui/pagination.md +650 -0
- package/docs/components/ui/popover.md +536 -0
- package/docs/components/ui/progress.md +182 -0
- package/docs/components/ui/radio-group.md +311 -0
- package/docs/components/ui/select.md +352 -0
- package/docs/components/ui/separator.md +214 -0
- package/docs/components/ui/sheet.md +142 -0
- package/docs/components/ui/skeleton.md +140 -0
- package/docs/components/ui/slider.md +341 -0
- package/docs/components/ui/spinner.md +170 -0
- package/docs/components/ui/switch.md +402 -0
- package/docs/components/ui/table.md +183 -0
- package/docs/components/ui/tabs-underline.md +106 -0
- package/docs/components/ui/tabs.md +122 -0
- package/docs/components/ui/textarea.md +243 -0
- package/docs/components/ui/toggle.md +243 -0
- package/docs/components/ui/tooltip.md +320 -0
- package/docs/components/ui/typography.md +191 -0
- package/package.json +11 -5
- package/dist/index-6oTEokEx.js +0 -82
- package/dist/index-B-NyefE0.js +0 -243
- package/dist/index-BKbK2GzY.cjs +0 -1
- package/dist/index-BMitW9UR.cjs +0 -1
- package/dist/index-BpvjJ_T6.cjs +0 -5
- package/dist/index-C5wjudc-.js +0 -36
- package/dist/index-CezwiPd_.js +0 -615
- package/dist/index-D02K8KOB.js +0 -54
- package/dist/index-D7hQvndv.cjs +0 -1
- package/dist/index-DQvx1rG_.cjs +0 -1
- package/dist/popover-BjdTqaB8.cjs +0 -1
- package/dist/popover-EnVfE0YA.js +0 -263
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Progress
|
|
2
|
+
|
|
3
|
+
Indicador de progreso basado en Radix UI. Muestra el avance de una tarea con barra animada y variantes de color.
|
|
4
|
+
|
|
5
|
+
## Descripción
|
|
6
|
+
|
|
7
|
+
El componente `Progress` muestra una barra de progreso para indicar el estado de una tarea.
|
|
8
|
+
|
|
9
|
+
## Importación
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { Progress } from "@adamosuiteservices/ui/progress";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Anatomía
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Progress value={33} />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Componentes**: 1 (Progress)
|
|
22
|
+
|
|
23
|
+
## Props
|
|
24
|
+
|
|
25
|
+
| Prop | Tipo | Default | Descripción |
|
|
26
|
+
| ----------- | ------------------------------------------------------ | ----------- | ---------------------- |
|
|
27
|
+
| `value` | `number` | `0` | Progreso (0-100) |
|
|
28
|
+
| `variant` | `"default" \| "destructive" \| "success" \| "warning"` | `"default"` | Variante de color |
|
|
29
|
+
| `max` | `number` | `100` | Valor máximo |
|
|
30
|
+
| `className` | `string` | - | Clases CSS adicionales |
|
|
31
|
+
|
|
32
|
+
## Patrones de Uso
|
|
33
|
+
|
|
34
|
+
### Básico
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<Progress value={33} />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Con Label
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<div className="space-y-2">
|
|
44
|
+
<div className="flex items-center justify-between">
|
|
45
|
+
<Label>File Upload</Label>
|
|
46
|
+
<span className="text-sm text-muted-foreground">45%</span>
|
|
47
|
+
</div>
|
|
48
|
+
<Progress value={45} />
|
|
49
|
+
<p className="text-xs text-muted-foreground">
|
|
50
|
+
Uploading document.pdf (2.3 MB of 5.1 MB)
|
|
51
|
+
</p>
|
|
52
|
+
</div>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Variantes
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<Progress value={70} variant="default" />
|
|
59
|
+
<Progress value={100} variant="success" />
|
|
60
|
+
<Progress value={40} variant="warning" />
|
|
61
|
+
<Progress value={90} variant="destructive" />
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Animado
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { useState, useEffect } from "react";
|
|
68
|
+
|
|
69
|
+
function App() {
|
|
70
|
+
const [progress, setProgress] = useState(13);
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
const timer = setTimeout(() => setProgress(66), 500);
|
|
74
|
+
return () => clearTimeout(timer);
|
|
75
|
+
}, []);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className="space-y-2">
|
|
79
|
+
<div className="flex items-center justify-between">
|
|
80
|
+
<Label>Loading...</Label>
|
|
81
|
+
<span className="text-sm text-muted-foreground">{progress}%</span>
|
|
82
|
+
</div>
|
|
83
|
+
<Progress value={progress} />
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Tamaños Custom
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
<Progress value={60} className="h-1" /> {/* Small */}
|
|
93
|
+
<Progress value={60} /> {/* Default h-2 */}
|
|
94
|
+
<Progress value={60} className="h-4" /> {/* Large */}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Con Iconos
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { Download } from "lucide-react";
|
|
101
|
+
|
|
102
|
+
<div className="space-y-2">
|
|
103
|
+
<div className="flex items-center gap-2">
|
|
104
|
+
<Download className="h-4 w-4" />
|
|
105
|
+
<Label>Download</Label>
|
|
106
|
+
<span className="ml-auto text-sm text-muted-foreground">65%</span>
|
|
107
|
+
</div>
|
|
108
|
+
<Progress value={65} />
|
|
109
|
+
</div>;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Multi-Step
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { useState } from "react";
|
|
116
|
+
|
|
117
|
+
function App() {
|
|
118
|
+
const [currentStep, setCurrentStep] = useState(2);
|
|
119
|
+
const totalSteps = 5;
|
|
120
|
+
const progress = (currentStep / totalSteps) * 100;
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div className="space-y-2">
|
|
124
|
+
<div className="flex items-center justify-between">
|
|
125
|
+
<Label>Setup Progress</Label>
|
|
126
|
+
<span className="text-sm text-muted-foreground">
|
|
127
|
+
Step {currentStep} of {totalSteps}
|
|
128
|
+
</span>
|
|
129
|
+
</div>
|
|
130
|
+
<Progress value={progress} />
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Casos de Uso
|
|
137
|
+
|
|
138
|
+
**File uploads**: Progreso de subida de archivos
|
|
139
|
+
**Downloads**: Descarga de contenido
|
|
140
|
+
**Multi-step forms**: Wizards con pasos
|
|
141
|
+
**System resources**: CPU, memoria, disco
|
|
142
|
+
**Installation**: Instalación de paquetes/apps
|
|
143
|
+
**Processing**: Tareas de procesamiento
|
|
144
|
+
|
|
145
|
+
## Estilos Base
|
|
146
|
+
|
|
147
|
+
- **Height**: `h-2` default
|
|
148
|
+
- **Border radius**: `rounded-full`
|
|
149
|
+
- **Transition**: `transition-all` en indicator
|
|
150
|
+
- **Transform**: `translateX` para animación
|
|
151
|
+
|
|
152
|
+
### Estilos de Variantes
|
|
153
|
+
|
|
154
|
+
- **default**: `bg-primary/20` → `bg-primary`
|
|
155
|
+
- **destructive**: `bg-destructive/20` → `bg-destructive`
|
|
156
|
+
- **success**: `bg-success/20` → `bg-success`
|
|
157
|
+
- **warning**: `bg-warning/20` → `bg-warning`
|
|
158
|
+
|
|
159
|
+
## Accesibilidad
|
|
160
|
+
|
|
161
|
+
- ✅ **ARIA**: `role="progressbar"`, `aria-valuenow`, `aria-valuemin`, `aria-valuemax`
|
|
162
|
+
- ✅ **Screen readers**: Anuncia progreso automáticamente
|
|
163
|
+
- ✅ **Live region**: Actualizaciones en tiempo real
|
|
164
|
+
|
|
165
|
+
## Notas de Implementación
|
|
166
|
+
|
|
167
|
+
- **Radix UI**: Basado en `@radix-ui/react-progress`
|
|
168
|
+
- **CVA**: Variantes con class-variance-authority
|
|
169
|
+
- **Animation**: CSS transform para transición suave
|
|
170
|
+
- **Value clamp**: Valor se limita entre 0-100 automáticamente
|
|
171
|
+
|
|
172
|
+
## Troubleshooting
|
|
173
|
+
|
|
174
|
+
**No se ve progreso**: Verifica que `value` esté entre 0-100
|
|
175
|
+
**No anima**: Asegúrate de que value cambie, usa `transition-all`
|
|
176
|
+
**Variante no cambia color**: Verifica prop `variant` correcta
|
|
177
|
+
**Muy fino**: Ajusta `className="h-3"` o mayor
|
|
178
|
+
|
|
179
|
+
## Referencias
|
|
180
|
+
|
|
181
|
+
- **Radix UI Progress**: <https://www.radix-ui.com/primitives/docs/components/progress>
|
|
182
|
+
- **shadcn/ui Progress**: <https://ui.shadcn.com/docs/components/progress>
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# Radio Group
|
|
2
|
+
|
|
3
|
+
Grupo de opciones mutuamente excluyentes. Usuario selecciona una opción. Basado en Radix UI.
|
|
4
|
+
|
|
5
|
+
## Descripción
|
|
6
|
+
|
|
7
|
+
El componente `RadioGroup` permite seleccionar una opción de un conjunto de opciones mutuamente excluyentes.
|
|
8
|
+
|
|
9
|
+
## Importación
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { RadioGroup, RadioGroupItem } from "@adamosuiteservices/ui/radio-group";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Anatomía
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<RadioGroup defaultValue="option-one">
|
|
19
|
+
<div className="flex items-center space-x-2">
|
|
20
|
+
<RadioGroupItem value="option-one" id="option-one" />
|
|
21
|
+
<Label htmlFor="option-one">Option One</Label>
|
|
22
|
+
</div>
|
|
23
|
+
<div className="flex items-center space-x-2">
|
|
24
|
+
<RadioGroupItem value="option-two" id="option-two" />
|
|
25
|
+
<Label htmlFor="option-two">Option Two</Label>
|
|
26
|
+
</div>
|
|
27
|
+
</RadioGroup>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Componentes**: 2 (RadioGroup, RadioGroupItem)
|
|
31
|
+
|
|
32
|
+
## Props
|
|
33
|
+
|
|
34
|
+
### RadioGroup
|
|
35
|
+
|
|
36
|
+
| Prop | Tipo | Descripción |
|
|
37
|
+
| --------------- | ------------------------- | ------------------------------ |
|
|
38
|
+
| `defaultValue` | `string` | Valor inicial (uncontrolled) |
|
|
39
|
+
| `value` | `string` | Valor controlado |
|
|
40
|
+
| `onValueChange` | `(value: string) => void` | Callback al cambiar valor |
|
|
41
|
+
| `disabled` | `boolean` | Deshabilita todo el grupo |
|
|
42
|
+
| `required` | `boolean` | Campo requerido |
|
|
43
|
+
| `name` | `string` | Nombre del grupo (formularios) |
|
|
44
|
+
| `className` | `string` | Clases CSS adicionales |
|
|
45
|
+
|
|
46
|
+
**Nota**: Acepta todas las props de Radix UI RadioGroup.Root
|
|
47
|
+
|
|
48
|
+
### RadioGroupItem
|
|
49
|
+
|
|
50
|
+
| Prop | Tipo | Descripción |
|
|
51
|
+
| ----------- | --------- | ------------------------- |
|
|
52
|
+
| `value` | `string` | Valor único del item |
|
|
53
|
+
| `id` | `string` | ID para asociar con Label |
|
|
54
|
+
| `disabled` | `boolean` | Deshabilita este item |
|
|
55
|
+
| `className` | `string` | Clases CSS adicionales |
|
|
56
|
+
|
|
57
|
+
**Nota**: Acepta todas las props de Radix UI RadioGroup.Item
|
|
58
|
+
|
|
59
|
+
## Patrones de Uso
|
|
60
|
+
|
|
61
|
+
### Básico
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { RadioGroup, RadioGroupItem } from "@adamosuiteservices/ui/radio-group";
|
|
65
|
+
import { Label } from "@adamosuiteservices/ui/label";
|
|
66
|
+
|
|
67
|
+
<RadioGroup defaultValue="option-one">
|
|
68
|
+
<div className="flex items-center gap-3">
|
|
69
|
+
<RadioGroupItem value="option-one" id="option-one" />
|
|
70
|
+
<Label htmlFor="option-one">Option One</Label>
|
|
71
|
+
</div>
|
|
72
|
+
<div className="flex items-center gap-3">
|
|
73
|
+
<RadioGroupItem value="option-two" id="option-two" />
|
|
74
|
+
<Label htmlFor="option-two">Option Two</Label>
|
|
75
|
+
</div>
|
|
76
|
+
</RadioGroup>;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Controlado
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { useState } from "react";
|
|
83
|
+
|
|
84
|
+
function App() {
|
|
85
|
+
const [value, setValue] = useState("red");
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<RadioGroup value={value} onValueChange={setValue}>
|
|
89
|
+
<div className="flex items-center gap-3">
|
|
90
|
+
<RadioGroupItem value="red" id="red" />
|
|
91
|
+
<Label htmlFor="red">Red</Label>
|
|
92
|
+
</div>
|
|
93
|
+
<div className="flex items-center gap-3">
|
|
94
|
+
<RadioGroupItem value="green" id="green" />
|
|
95
|
+
<Label htmlFor="green">Green</Label>
|
|
96
|
+
</div>
|
|
97
|
+
</RadioGroup>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Con Descripciones
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
<RadioGroup defaultValue="comfortable">
|
|
106
|
+
<div className="flex items-start gap-3">
|
|
107
|
+
<RadioGroupItem value="default" id="default" />
|
|
108
|
+
<div className="grid gap-2">
|
|
109
|
+
<Label htmlFor="default">Default</Label>
|
|
110
|
+
<p className="text-muted-foreground text-sm">
|
|
111
|
+
Recommended for most users. Provides a balanced experience.
|
|
112
|
+
</p>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
<div className="flex items-start gap-3">
|
|
116
|
+
<RadioGroupItem value="comfortable" id="comfortable" />
|
|
117
|
+
<div className="grid gap-2">
|
|
118
|
+
<Label htmlFor="comfortable">Comfortable</Label>
|
|
119
|
+
<p className="text-muted-foreground text-sm">
|
|
120
|
+
More spacing and larger elements for better accessibility.
|
|
121
|
+
</p>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</RadioGroup>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Layout Horizontal
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<RadioGroup defaultValue="medium" className="flex gap-6">
|
|
131
|
+
<div className="flex items-center gap-2">
|
|
132
|
+
<RadioGroupItem value="small" id="small" />
|
|
133
|
+
<Label htmlFor="small">Small</Label>
|
|
134
|
+
</div>
|
|
135
|
+
<div className="flex items-center gap-2">
|
|
136
|
+
<RadioGroupItem value="medium" id="medium" />
|
|
137
|
+
<Label htmlFor="medium">Medium</Label>
|
|
138
|
+
</div>
|
|
139
|
+
<div className="flex items-center gap-2">
|
|
140
|
+
<RadioGroupItem value="large" id="large" />
|
|
141
|
+
<Label htmlFor="large">Large</Label>
|
|
142
|
+
</div>
|
|
143
|
+
</RadioGroup>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Con Badges
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { Badge } from "@adamosuiteservices/ui/badge";
|
|
150
|
+
|
|
151
|
+
<RadioGroup defaultValue="pro">
|
|
152
|
+
<div className="flex items-center gap-3">
|
|
153
|
+
<RadioGroupItem value="free" id="free" />
|
|
154
|
+
<div className="flex items-center gap-2">
|
|
155
|
+
<Label htmlFor="free">Free Plan</Label>
|
|
156
|
+
<Badge variant="secondary">$0/month</Badge>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
<div className="flex items-center gap-3">
|
|
160
|
+
<RadioGroupItem value="pro" id="pro" />
|
|
161
|
+
<div className="flex items-center gap-2">
|
|
162
|
+
<Label htmlFor="pro">Pro Plan</Label>
|
|
163
|
+
<Badge variant="default">$9/month</Badge>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</RadioGroup>;
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### En Formularios
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { Button } from "@adamosuiteservices/ui/button";
|
|
173
|
+
|
|
174
|
+
function App() {
|
|
175
|
+
const [formData, setFormData] = useState({
|
|
176
|
+
notification: "email",
|
|
177
|
+
frequency: "weekly",
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
181
|
+
e.preventDefault();
|
|
182
|
+
console.log("Form submitted:", formData);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<form onSubmit={handleSubmit} className="space-y-6">
|
|
187
|
+
<div className="space-y-3">
|
|
188
|
+
<p className="text-sm font-medium">Notification method</p>
|
|
189
|
+
<RadioGroup
|
|
190
|
+
value={formData.notification}
|
|
191
|
+
onValueChange={(value) =>
|
|
192
|
+
setFormData((prev) => ({ ...prev, notification: value }))
|
|
193
|
+
}
|
|
194
|
+
>
|
|
195
|
+
<div className="flex items-center gap-3">
|
|
196
|
+
<RadioGroupItem value="email" id="email" />
|
|
197
|
+
<Label htmlFor="email">Email notifications</Label>
|
|
198
|
+
</div>
|
|
199
|
+
<div className="flex items-center gap-3">
|
|
200
|
+
<RadioGroupItem value="sms" id="sms" />
|
|
201
|
+
<Label htmlFor="sms">SMS notifications</Label>
|
|
202
|
+
</div>
|
|
203
|
+
</RadioGroup>
|
|
204
|
+
</div>
|
|
205
|
+
<Button type="submit">Save preferences</Button>
|
|
206
|
+
</form>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Nested (Conditional)
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
function App() {
|
|
215
|
+
const [paymentMethod, setPaymentMethod] = useState("card");
|
|
216
|
+
const [cardType, setCardType] = useState("visa");
|
|
217
|
+
|
|
218
|
+
return (
|
|
219
|
+
<div className="space-y-6">
|
|
220
|
+
<RadioGroup value={paymentMethod} onValueChange={setPaymentMethod}>
|
|
221
|
+
<div className="flex items-center gap-3">
|
|
222
|
+
<RadioGroupItem value="card" id="card" />
|
|
223
|
+
<Label htmlFor="card">Credit/Debit Card</Label>
|
|
224
|
+
</div>
|
|
225
|
+
<div className="flex items-center gap-3">
|
|
226
|
+
<RadioGroupItem value="bank" id="bank" />
|
|
227
|
+
<Label htmlFor="bank">Bank Transfer</Label>
|
|
228
|
+
</div>
|
|
229
|
+
</RadioGroup>
|
|
230
|
+
|
|
231
|
+
{paymentMethod === "card" && (
|
|
232
|
+
<div className="ml-6 space-y-3">
|
|
233
|
+
<p className="text-sm font-medium">Card type</p>
|
|
234
|
+
<RadioGroup value={cardType} onValueChange={setCardType}>
|
|
235
|
+
<div className="flex items-center gap-3">
|
|
236
|
+
<RadioGroupItem value="visa" id="visa" />
|
|
237
|
+
<Label htmlFor="visa">Visa</Label>
|
|
238
|
+
</div>
|
|
239
|
+
<div className="flex items-center gap-3">
|
|
240
|
+
<RadioGroupItem value="mastercard" id="mastercard" />
|
|
241
|
+
<Label htmlFor="mastercard">Mastercard</Label>
|
|
242
|
+
</div>
|
|
243
|
+
</RadioGroup>
|
|
244
|
+
</div>
|
|
245
|
+
)}
|
|
246
|
+
</div>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Deshabilitado
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
<RadioGroup defaultValue="option-one" disabled>
|
|
255
|
+
<div className="flex items-center gap-3">
|
|
256
|
+
<RadioGroupItem value="option-one" id="disabled-one" />
|
|
257
|
+
<Label htmlFor="disabled-one">Option One</Label>
|
|
258
|
+
</div>
|
|
259
|
+
<div className="flex items-center gap-3">
|
|
260
|
+
<RadioGroupItem value="option-two" id="disabled-two" />
|
|
261
|
+
<Label htmlFor="disabled-two">Option Two</Label>
|
|
262
|
+
</div>
|
|
263
|
+
</RadioGroup>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Casos de Uso
|
|
267
|
+
|
|
268
|
+
**Opciones mutuamente excluyentes**: Una sola selección de múltiples opciones
|
|
269
|
+
**Settings**: Preferencias de configuración (theme, size, mode)
|
|
270
|
+
**Formularios**: Selección de método de pago, envío, categoría
|
|
271
|
+
**Surveys**: Preguntas con opciones de respuesta única
|
|
272
|
+
**Filtros**: Filtrado por categoría, tipo, estado
|
|
273
|
+
|
|
274
|
+
## Estilos Base
|
|
275
|
+
|
|
276
|
+
- **Size**: `size-5` (20px)
|
|
277
|
+
- **Border**: `border-input` con `shadow-xs`
|
|
278
|
+
- **Checked**: `CircleIcon` con `fill-primary`
|
|
279
|
+
- **Focus**: `ring-ring/50` con `ring-[3px]`
|
|
280
|
+
- **Invalid**: `border-destructive` con `ring-destructive/20`
|
|
281
|
+
- **Spacing**: `gap-3` default entre item y label
|
|
282
|
+
|
|
283
|
+
## Accesibilidad
|
|
284
|
+
|
|
285
|
+
- ✅ **Role**: `role="radio"` y `role="radiogroup"`
|
|
286
|
+
- ✅ **ARIA**: `aria-checked`, `aria-disabled`, `aria-invalid`
|
|
287
|
+
- ✅ **Keyboard**: Arrow keys para navegar, Space para seleccionar
|
|
288
|
+
- ✅ **Label**: Asociar con `htmlFor` e `id`
|
|
289
|
+
- ✅ **Focus**: Focus ring visible en navegación por teclado
|
|
290
|
+
|
|
291
|
+
## Notas de Implementación
|
|
292
|
+
|
|
293
|
+
- **Radix UI**: Basado en `@radix-ui/react-radio-group`
|
|
294
|
+
- **Indicador**: Usa `CircleIcon` de lucide-react con `fill-primary`
|
|
295
|
+
- **Grid layout**: Default usa `grid gap-3` para vertical spacing
|
|
296
|
+
- **Data attributes**: `data-slot` para identificar componentes
|
|
297
|
+
- **Controlled**: Usa `value` + `onValueChange`
|
|
298
|
+
- **Uncontrolled**: Usa `defaultValue`
|
|
299
|
+
|
|
300
|
+
## Troubleshooting
|
|
301
|
+
|
|
302
|
+
**No se puede seleccionar**: Verifica que cada item tenga `value` único
|
|
303
|
+
**Label no clickeable**: Asegura `htmlFor` en Label coincida con `id` del RadioGroupItem
|
|
304
|
+
**Grupo deshabilitado**: `disabled` en RadioGroup deshabilita todos los items
|
|
305
|
+
**Item individual disabled**: `disabled` en RadioGroupItem específico
|
|
306
|
+
**Estado no actualiza**: En modo controlado usa `value` + `onValueChange`, no `defaultValue`
|
|
307
|
+
|
|
308
|
+
## Referencias
|
|
309
|
+
|
|
310
|
+
- **Radix UI Radio Group**: <https://www.radix-ui.com/primitives/docs/components/radio-group>
|
|
311
|
+
- **shadcn/ui Radio Group**: <https://ui.shadcn.com/docs/components/radio-group>
|