@adamosuiteservices/ui 2.13.4 → 2.14.0
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/dist/{button-Bn4LFAa9.js → button-B0lWuG-D.js} +27 -18
- package/dist/{button-Day6_fbu.cjs → button-DVrteFz9.cjs} +2 -2
- package/dist/button.cjs +1 -1
- package/dist/button.js +1 -1
- package/dist/{calendar-B1_ybTg0.js → calendar-CfqtuOWv.js} +1 -1
- package/dist/{calendar-CZkzHgYi.cjs → calendar-CpUN6BGK.cjs} +1 -1
- package/dist/calendar.cjs +1 -1
- package/dist/calendar.js +1 -1
- package/dist/{combobox-BOi7QzmO.js → combobox-B8HMlZy6.js} +1 -1
- package/dist/{combobox-0ndFo07_.cjs → combobox-Btj-hiBy.cjs} +1 -1
- package/dist/combobox.cjs +1 -1
- package/dist/combobox.js +1 -1
- package/dist/components/ui/alert/alert.d.ts +1 -1
- package/dist/components/ui/button/button.d.ts +3 -2
- package/dist/components/ui/card/card.d.ts +2 -2
- package/dist/date-picker-selector.cjs +1 -1
- package/dist/date-picker-selector.js +3 -3
- package/dist/file-upload.cjs +1 -1
- package/dist/file-upload.js +1 -1
- package/dist/full-screen-loader.cjs +1 -1
- package/dist/full-screen-loader.js +1 -1
- package/dist/input-group.cjs +1 -1
- package/dist/input-group.js +1 -1
- package/dist/pagination.cjs +1 -1
- package/dist/pagination.js +1 -1
- package/dist/sidebar.cjs +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tabs.cjs +14 -16
- package/dist/tabs.js +17 -19
- package/docs/AI-GUIDE.md +321 -321
- package/docs/components/layout/full-screen-loader.md +2 -2
- package/docs/components/layout/sidebar.md +399 -399
- package/docs/components/layout/toaster.md +436 -436
- package/docs/components/ui/accordion-rounded.md +584 -584
- package/docs/components/ui/accordion.md +269 -269
- package/docs/components/ui/button.md +35 -23
- package/docs/components/ui/calendar.md +1159 -1159
- package/docs/components/ui/card.md +1455 -1455
- package/docs/components/ui/checkbox.md +292 -292
- package/docs/components/ui/collapsible.md +323 -323
- package/docs/components/ui/dialog.md +628 -628
- package/docs/components/ui/field.md +706 -706
- package/docs/components/ui/hover-card.md +446 -446
- package/docs/components/ui/kbd.md +434 -434
- package/docs/components/ui/label.md +359 -359
- package/docs/components/ui/pagination.md +650 -650
- package/docs/components/ui/popover.md +536 -536
- package/docs/components/ui/progress.md +182 -182
- package/docs/components/ui/radio-group.md +311 -311
- package/docs/components/ui/separator.md +214 -214
- package/docs/components/ui/sheet.md +174 -174
- package/docs/components/ui/skeleton.md +140 -140
- package/docs/components/ui/spinner.md +170 -170
- package/docs/components/ui/switch.md +408 -408
- package/docs/components/ui/tabs-underline.md +106 -106
- package/docs/components/ui/tabs.md +125 -122
- package/docs/components/ui/textarea.md +243 -243
- package/docs/components/ui/toggle.md +237 -237
- package/docs/components/ui/tooltip.md +317 -317
- package/docs/components/ui/typography.md +320 -320
- package/package.json +1 -1
|
@@ -1,323 +1,323 @@
|
|
|
1
|
-
# Collapsible
|
|
2
|
-
|
|
3
|
-
Componente interactivo basado en Radix UI para expandir/colapsar contenido con animaciones suaves. Útil para FAQs, menús de navegación, y secciones opcionales.
|
|
4
|
-
|
|
5
|
-
## Importación
|
|
6
|
-
|
|
7
|
-
```tsx
|
|
8
|
-
import {
|
|
9
|
-
Collapsible,
|
|
10
|
-
CollapsibleTrigger,
|
|
11
|
-
CollapsibleContent,
|
|
12
|
-
} from "@adamosuiteservices/ui/collapsible";
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Anatomía
|
|
16
|
-
|
|
17
|
-
```tsx
|
|
18
|
-
<Collapsible>
|
|
19
|
-
<CollapsibleTrigger>Click to toggle</CollapsibleTrigger>
|
|
20
|
-
<CollapsibleContent>Hidden content that expands/collapses</CollapsibleContent>
|
|
21
|
-
</Collapsible>
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**Componentes**: 3 (Collapsible root, CollapsibleTrigger, CollapsibleContent)
|
|
25
|
-
|
|
26
|
-
## Props Principales
|
|
27
|
-
|
|
28
|
-
### Collapsible (Root)
|
|
29
|
-
|
|
30
|
-
| Prop | Tipo | Default | Descripción |
|
|
31
|
-
| -------------- | ------------------------- | ------- | ----------------------------------- |
|
|
32
|
-
| `open` | `boolean` | - | Estado controlado (abierto/cerrado) |
|
|
33
|
-
| `defaultOpen` | `boolean` | `false` | Estado inicial no controlado |
|
|
34
|
-
| `onOpenChange` | `(open: boolean) => void` | - | Callback al cambiar estado |
|
|
35
|
-
| `disabled` | `boolean` | `false` | Desactiva interacción |
|
|
36
|
-
| `className` | `string` | - | Clases CSS adicionales |
|
|
37
|
-
|
|
38
|
-
### CollapsibleTrigger
|
|
39
|
-
|
|
40
|
-
| Prop | Tipo | Default | Descripción |
|
|
41
|
-
| ----------- | --------- | ------- | ----------------------------------- |
|
|
42
|
-
| `asChild` | `boolean` | `false` | Usa child como trigger (Radix Slot) |
|
|
43
|
-
| `className` | `string` | - | Clases CSS adicionales |
|
|
44
|
-
|
|
45
|
-
### CollapsibleContent
|
|
46
|
-
|
|
47
|
-
| Prop | Tipo | Default | Descripción |
|
|
48
|
-
| ------------ | --------- | ------- | ----------------------------------------- |
|
|
49
|
-
| `forceMount` | `boolean` | `false` | Fuerza montaje en DOM aunque esté cerrado |
|
|
50
|
-
| `className` | `string` | - | Clases CSS adicionales |
|
|
51
|
-
|
|
52
|
-
## Patrones de Uso
|
|
53
|
-
|
|
54
|
-
### Básico (No Controlado)
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
<Collapsible>
|
|
58
|
-
<CollapsibleTrigger>Show details</CollapsibleTrigger>
|
|
59
|
-
<CollapsibleContent>
|
|
60
|
-
<p>Additional information here.</p>
|
|
61
|
-
</CollapsibleContent>
|
|
62
|
-
</Collapsible>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Controlado con Estado
|
|
66
|
-
|
|
67
|
-
```tsx
|
|
68
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
69
|
-
|
|
70
|
-
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
|
|
71
|
-
<CollapsibleTrigger>{isOpen ? "Hide" : "Show"} content</CollapsibleTrigger>
|
|
72
|
-
<CollapsibleContent>
|
|
73
|
-
<p>Controlled content</p>
|
|
74
|
-
</CollapsibleContent>
|
|
75
|
-
</Collapsible>;
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Con Botón Custom (asChild)
|
|
79
|
-
|
|
80
|
-
```tsx
|
|
81
|
-
import { Button } from "@adamosuiteservices/ui/button";
|
|
82
|
-
import { Icon } from "@adamosuiteservices/ui/icon";
|
|
83
|
-
|
|
84
|
-
<Collapsible>
|
|
85
|
-
<CollapsibleTrigger asChild>
|
|
86
|
-
<Button variant="outline" size="sm">
|
|
87
|
-
<Icon symbol="unfold_more" className="text-base" />
|
|
88
|
-
Toggle
|
|
89
|
-
</Button>
|
|
90
|
-
</CollapsibleTrigger>
|
|
91
|
-
<CollapsibleContent>
|
|
92
|
-
<p>Content</p>
|
|
93
|
-
</CollapsibleContent>
|
|
94
|
-
</Collapsible>;
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Con Chevron Rotatorio
|
|
98
|
-
|
|
99
|
-
```tsx
|
|
100
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
101
|
-
|
|
102
|
-
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
|
|
103
|
-
<CollapsibleTrigger className="flex w-full items-center justify-between p-4 border rounded-lg hover:bg-muted">
|
|
104
|
-
<span>Section Title</span>
|
|
105
|
-
<Icon
|
|
106
|
-
symbol="expand_more"
|
|
107
|
-
className={`text-lg transition-transform ${isOpen ? "rotate-180" : ""}`}
|
|
108
|
-
/>
|
|
109
|
-
</CollapsibleTrigger>
|
|
110
|
-
<CollapsibleContent className="p-4">
|
|
111
|
-
<p>Expandable content</p>
|
|
112
|
-
</CollapsibleContent>
|
|
113
|
-
</Collapsible>;
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### FAQ Pattern
|
|
117
|
-
|
|
118
|
-
```tsx
|
|
119
|
-
<div className="space-y-4">
|
|
120
|
-
<Collapsible>
|
|
121
|
-
<CollapsibleTrigger className="flex w-full items-center justify-between border p-4 rounded-lg hover:bg-muted">
|
|
122
|
-
<span className="font-medium">What is this?</span>
|
|
123
|
-
<Icon symbol="chevron_right" className="text-lg" />
|
|
124
|
-
</CollapsibleTrigger>
|
|
125
|
-
<CollapsibleContent className="px-4 pb-4">
|
|
126
|
-
<p className="text-sm text-muted-foreground">
|
|
127
|
-
This is a reusable UI component library.
|
|
128
|
-
</p>
|
|
129
|
-
</CollapsibleContent>
|
|
130
|
-
</Collapsible>
|
|
131
|
-
|
|
132
|
-
<Collapsible>
|
|
133
|
-
<CollapsibleTrigger className="flex w-full items-center justify-between border p-4 rounded-lg hover:bg-muted">
|
|
134
|
-
<span className="font-medium">How to install?</span>
|
|
135
|
-
<Icon symbol="chevron_right" className="text-lg" />
|
|
136
|
-
</CollapsibleTrigger>
|
|
137
|
-
<CollapsibleContent className="px-4 pb-4">
|
|
138
|
-
<p className="text-sm text-muted-foreground">
|
|
139
|
-
Use: <code>npm install @adamosuiteservices/ui</code>
|
|
140
|
-
</p>
|
|
141
|
-
</CollapsibleContent>
|
|
142
|
-
</Collapsible>
|
|
143
|
-
</div>
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Navigation Menu
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
const [openSections, setOpenSections] = useState<string[]>(["settings"]);
|
|
150
|
-
|
|
151
|
-
const toggleSection = (id: string) => {
|
|
152
|
-
setOpenSections((prev) =>
|
|
153
|
-
prev.includes(id) ? prev.filter((s) => s !== id) : [...prev, id]
|
|
154
|
-
);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
<div className="space-y-2">
|
|
158
|
-
<Collapsible
|
|
159
|
-
open={openSections.includes("settings")}
|
|
160
|
-
onOpenChange={() => toggleSection("settings")}
|
|
161
|
-
>
|
|
162
|
-
<CollapsibleTrigger className="flex w-full items-center gap-2 p-3 rounded-lg hover:bg-muted">
|
|
163
|
-
<Icon symbol="settings" className="text-lg" />
|
|
164
|
-
<span className="flex-1 font-medium">Settings</span>
|
|
165
|
-
<Icon
|
|
166
|
-
symbol="expand_more"
|
|
167
|
-
className={`text-lg transition-transform ${
|
|
168
|
-
openSections.includes("settings") ? "rotate-180" : ""
|
|
169
|
-
}`}
|
|
170
|
-
/>
|
|
171
|
-
</CollapsibleTrigger>
|
|
172
|
-
<CollapsibleContent className="ml-6 space-y-1">
|
|
173
|
-
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
174
|
-
Profile
|
|
175
|
-
</a>
|
|
176
|
-
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
177
|
-
Security
|
|
178
|
-
</a>
|
|
179
|
-
</CollapsibleContent>
|
|
180
|
-
</Collapsible>
|
|
181
|
-
|
|
182
|
-
<Collapsible
|
|
183
|
-
open={openSections.includes("account")}
|
|
184
|
-
onOpenChange={() => toggleSection("account")}
|
|
185
|
-
>
|
|
186
|
-
<CollapsibleTrigger className="flex w-full items-center gap-2 p-3 rounded-lg hover:bg-muted">
|
|
187
|
-
<Icon symbol="person" className="text-lg" />
|
|
188
|
-
<span className="flex-1 font-medium">Account</span>
|
|
189
|
-
<Icon
|
|
190
|
-
symbol="expand_more"
|
|
191
|
-
className={`text-lg transition-transform ${
|
|
192
|
-
openSections.includes("account") ? "rotate-180" : ""
|
|
193
|
-
}`}
|
|
194
|
-
/>
|
|
195
|
-
</CollapsibleTrigger>
|
|
196
|
-
<CollapsibleContent className="ml-6 space-y-1">
|
|
197
|
-
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
198
|
-
Billing
|
|
199
|
-
</a>
|
|
200
|
-
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
201
|
-
API Keys
|
|
202
|
-
</a>
|
|
203
|
-
</CollapsibleContent>
|
|
204
|
-
</Collapsible>
|
|
205
|
-
</div>;
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Lista de Archivos
|
|
209
|
-
|
|
210
|
-
```tsx
|
|
211
|
-
<Collapsible defaultOpen className="w-full space-y-2">
|
|
212
|
-
<CollapsibleTrigger className="w-full border p-3 rounded-lg text-left font-medium hover:bg-muted">
|
|
213
|
-
Recent Files
|
|
214
|
-
</CollapsibleTrigger>
|
|
215
|
-
<CollapsibleContent className="space-y-1">
|
|
216
|
-
<div className="border p-3 rounded text-sm">document.pdf</div>
|
|
217
|
-
<div className="border p-3 rounded text-sm">presentation.pptx</div>
|
|
218
|
-
<div className="border p-3 rounded text-sm">spreadsheet.xlsx</div>
|
|
219
|
-
</CollapsibleContent>
|
|
220
|
-
</Collapsible>
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Sección Deshabilitada
|
|
224
|
-
|
|
225
|
-
```tsx
|
|
226
|
-
<Collapsible disabled>
|
|
227
|
-
<CollapsibleTrigger className="w-full border p-3 rounded-lg text-left font-medium opacity-50 cursor-not-allowed">
|
|
228
|
-
Coming Soon
|
|
229
|
-
</CollapsibleTrigger>
|
|
230
|
-
<CollapsibleContent>
|
|
231
|
-
<p className="p-3 text-sm text-muted-foreground">Not available yet.</p>
|
|
232
|
-
</CollapsibleContent>
|
|
233
|
-
</Collapsible>
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Con Layout de Tarjeta
|
|
237
|
-
|
|
238
|
-
```tsx
|
|
239
|
-
<Collapsible className="border rounded-lg p-4">
|
|
240
|
-
<div className="flex items-center justify-between mb-2">
|
|
241
|
-
<h4 className="font-semibold">@user starred 3 repos</h4>
|
|
242
|
-
<CollapsibleTrigger asChild>
|
|
243
|
-
<Button variant="outline" size="sm">
|
|
244
|
-
<Icon symbol="unfold_more" className="text-base" />
|
|
245
|
-
</Button>
|
|
246
|
-
</CollapsibleTrigger>
|
|
247
|
-
</div>
|
|
248
|
-
|
|
249
|
-
<div className="border px-4 py-2 rounded font-mono text-sm">
|
|
250
|
-
@radix-ui/primitives
|
|
251
|
-
</div>
|
|
252
|
-
|
|
253
|
-
<CollapsibleContent className="mt-2 space-y-2">
|
|
254
|
-
<div className="border px-4 py-2 rounded font-mono text-sm">
|
|
255
|
-
@radix-ui/colors
|
|
256
|
-
</div>
|
|
257
|
-
<div className="border px-4 py-2 rounded font-mono text-sm">
|
|
258
|
-
@stitches/react
|
|
259
|
-
</div>
|
|
260
|
-
</CollapsibleContent>
|
|
261
|
-
</Collapsible>
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## Casos de Uso Comunes
|
|
265
|
-
|
|
266
|
-
**FAQ sections**: Lista de preguntas frecuentes expandibles
|
|
267
|
-
**Navigation menus**: Menús colapsables con subsecciones
|
|
268
|
-
**Details/Summary**: Información adicional opcional
|
|
269
|
-
**File browsers**: Estructuras de carpetas expandibles
|
|
270
|
-
**Settings panels**: Grupos de configuraciones organizadas
|
|
271
|
-
**Table rows**: Filas de tabla con detalles expandibles
|
|
272
|
-
|
|
273
|
-
## Estilos y Animaciones
|
|
274
|
-
|
|
275
|
-
### Data States
|
|
276
|
-
|
|
277
|
-
- **Abierto**: `data-state="open"` en todos los componentes
|
|
278
|
-
- **Cerrado**: `data-state="closed"` en todos los componentes
|
|
279
|
-
- **Disabled**: `data-disabled` cuando `disabled={true}`
|
|
280
|
-
|
|
281
|
-
### Animación Suave
|
|
282
|
-
|
|
283
|
-
El contenido usa animaciones CSS automáticas (height, opacity) al expandir/colapsar. No requiere configuración adicional.
|
|
284
|
-
|
|
285
|
-
### Custom Animations
|
|
286
|
-
|
|
287
|
-
```tsx
|
|
288
|
-
<CollapsibleContent className="data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
|
|
289
|
-
Content with custom animations
|
|
290
|
-
</CollapsibleContent>
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Accesibilidad
|
|
294
|
-
|
|
295
|
-
- ✅ **Navegación teclado**: Enter/Space para toggle en trigger, Tab para navegar
|
|
296
|
-
- ✅ **ARIA**: `aria-expanded`, `aria-controls` automáticos en trigger
|
|
297
|
-
- ✅ **Screen readers**: Anuncia estado expandido/colapsado
|
|
298
|
-
- ✅ **Focus visible**: Trigger recibe focus del teclado
|
|
299
|
-
- ✅ **Disabled state**: `aria-disabled` cuando disabled
|
|
300
|
-
|
|
301
|
-
## Notas de Implementación
|
|
302
|
-
|
|
303
|
-
- **Basado en Radix UI**: `@radix-ui/react-collapsible`
|
|
304
|
-
- **No tiene estilos propios**: Wrapper limpio, agrega tus propios estilos
|
|
305
|
-
- **Data slots**: `data-slot="collapsible"`, `data-slot="collapsible-trigger"`, `data-slot="collapsible-content"`
|
|
306
|
-
- **asChild pattern**: CollapsibleTrigger soporta `asChild` para usar componentes custom
|
|
307
|
-
- **Animaciones automáticas**: Radix maneja transiciones de height/opacity
|
|
308
|
-
- **forceMount**: Útil para animaciones custom o cuando necesitas el DOM montado siempre
|
|
309
|
-
- **Multiple instances**: Puedes tener múltiples Collapsibles independientes
|
|
310
|
-
- **Accordion vs Collapsible**: Usa Accordion cuando solo uno debe estar abierto, Collapsible para control independiente
|
|
311
|
-
|
|
312
|
-
## Troubleshooting
|
|
313
|
-
|
|
314
|
-
**Animación no suave**: Radix maneja animaciones automáticamente, si no se ve suave verifica que no haya `transition` conflictivos en CSS
|
|
315
|
-
**Trigger no clickeable**: Verifica que esté dentro de `<Collapsible>`, no como hermano
|
|
316
|
-
**asChild no funciona**: Asegúrate que el child acepta props `onClick` y `aria-*`
|
|
317
|
-
**Content siempre visible**: Verifica que no tengas `forceMount` activado sin intención
|
|
318
|
-
**Estado no sincroniza**: En modo controlado, asegúrate de usar ambos `open` y `onOpenChange`
|
|
319
|
-
|
|
320
|
-
## Referencias
|
|
321
|
-
|
|
322
|
-
- **Radix UI Collapsible**: https://www.radix-ui.com/primitives/docs/components/collapsible
|
|
323
|
-
- **ARIA Disclosure**: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/
|
|
1
|
+
# Collapsible
|
|
2
|
+
|
|
3
|
+
Componente interactivo basado en Radix UI para expandir/colapsar contenido con animaciones suaves. Útil para FAQs, menús de navegación, y secciones opcionales.
|
|
4
|
+
|
|
5
|
+
## Importación
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
Collapsible,
|
|
10
|
+
CollapsibleTrigger,
|
|
11
|
+
CollapsibleContent,
|
|
12
|
+
} from "@adamosuiteservices/ui/collapsible";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Anatomía
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Collapsible>
|
|
19
|
+
<CollapsibleTrigger>Click to toggle</CollapsibleTrigger>
|
|
20
|
+
<CollapsibleContent>Hidden content that expands/collapses</CollapsibleContent>
|
|
21
|
+
</Collapsible>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Componentes**: 3 (Collapsible root, CollapsibleTrigger, CollapsibleContent)
|
|
25
|
+
|
|
26
|
+
## Props Principales
|
|
27
|
+
|
|
28
|
+
### Collapsible (Root)
|
|
29
|
+
|
|
30
|
+
| Prop | Tipo | Default | Descripción |
|
|
31
|
+
| -------------- | ------------------------- | ------- | ----------------------------------- |
|
|
32
|
+
| `open` | `boolean` | - | Estado controlado (abierto/cerrado) |
|
|
33
|
+
| `defaultOpen` | `boolean` | `false` | Estado inicial no controlado |
|
|
34
|
+
| `onOpenChange` | `(open: boolean) => void` | - | Callback al cambiar estado |
|
|
35
|
+
| `disabled` | `boolean` | `false` | Desactiva interacción |
|
|
36
|
+
| `className` | `string` | - | Clases CSS adicionales |
|
|
37
|
+
|
|
38
|
+
### CollapsibleTrigger
|
|
39
|
+
|
|
40
|
+
| Prop | Tipo | Default | Descripción |
|
|
41
|
+
| ----------- | --------- | ------- | ----------------------------------- |
|
|
42
|
+
| `asChild` | `boolean` | `false` | Usa child como trigger (Radix Slot) |
|
|
43
|
+
| `className` | `string` | - | Clases CSS adicionales |
|
|
44
|
+
|
|
45
|
+
### CollapsibleContent
|
|
46
|
+
|
|
47
|
+
| Prop | Tipo | Default | Descripción |
|
|
48
|
+
| ------------ | --------- | ------- | ----------------------------------------- |
|
|
49
|
+
| `forceMount` | `boolean` | `false` | Fuerza montaje en DOM aunque esté cerrado |
|
|
50
|
+
| `className` | `string` | - | Clases CSS adicionales |
|
|
51
|
+
|
|
52
|
+
## Patrones de Uso
|
|
53
|
+
|
|
54
|
+
### Básico (No Controlado)
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<Collapsible>
|
|
58
|
+
<CollapsibleTrigger>Show details</CollapsibleTrigger>
|
|
59
|
+
<CollapsibleContent>
|
|
60
|
+
<p>Additional information here.</p>
|
|
61
|
+
</CollapsibleContent>
|
|
62
|
+
</Collapsible>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Controlado con Estado
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
69
|
+
|
|
70
|
+
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
|
|
71
|
+
<CollapsibleTrigger>{isOpen ? "Hide" : "Show"} content</CollapsibleTrigger>
|
|
72
|
+
<CollapsibleContent>
|
|
73
|
+
<p>Controlled content</p>
|
|
74
|
+
</CollapsibleContent>
|
|
75
|
+
</Collapsible>;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Con Botón Custom (asChild)
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { Button } from "@adamosuiteservices/ui/button";
|
|
82
|
+
import { Icon } from "@adamosuiteservices/ui/icon";
|
|
83
|
+
|
|
84
|
+
<Collapsible>
|
|
85
|
+
<CollapsibleTrigger asChild>
|
|
86
|
+
<Button variant="outline" size="sm">
|
|
87
|
+
<Icon symbol="unfold_more" className="text-base" />
|
|
88
|
+
Toggle
|
|
89
|
+
</Button>
|
|
90
|
+
</CollapsibleTrigger>
|
|
91
|
+
<CollapsibleContent>
|
|
92
|
+
<p>Content</p>
|
|
93
|
+
</CollapsibleContent>
|
|
94
|
+
</Collapsible>;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Con Chevron Rotatorio
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
101
|
+
|
|
102
|
+
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
|
|
103
|
+
<CollapsibleTrigger className="flex w-full items-center justify-between p-4 border rounded-lg hover:bg-muted">
|
|
104
|
+
<span>Section Title</span>
|
|
105
|
+
<Icon
|
|
106
|
+
symbol="expand_more"
|
|
107
|
+
className={`text-lg transition-transform ${isOpen ? "rotate-180" : ""}`}
|
|
108
|
+
/>
|
|
109
|
+
</CollapsibleTrigger>
|
|
110
|
+
<CollapsibleContent className="p-4">
|
|
111
|
+
<p>Expandable content</p>
|
|
112
|
+
</CollapsibleContent>
|
|
113
|
+
</Collapsible>;
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### FAQ Pattern
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<div className="space-y-4">
|
|
120
|
+
<Collapsible>
|
|
121
|
+
<CollapsibleTrigger className="flex w-full items-center justify-between border p-4 rounded-lg hover:bg-muted">
|
|
122
|
+
<span className="font-medium">What is this?</span>
|
|
123
|
+
<Icon symbol="chevron_right" className="text-lg" />
|
|
124
|
+
</CollapsibleTrigger>
|
|
125
|
+
<CollapsibleContent className="px-4 pb-4">
|
|
126
|
+
<p className="text-sm text-muted-foreground">
|
|
127
|
+
This is a reusable UI component library.
|
|
128
|
+
</p>
|
|
129
|
+
</CollapsibleContent>
|
|
130
|
+
</Collapsible>
|
|
131
|
+
|
|
132
|
+
<Collapsible>
|
|
133
|
+
<CollapsibleTrigger className="flex w-full items-center justify-between border p-4 rounded-lg hover:bg-muted">
|
|
134
|
+
<span className="font-medium">How to install?</span>
|
|
135
|
+
<Icon symbol="chevron_right" className="text-lg" />
|
|
136
|
+
</CollapsibleTrigger>
|
|
137
|
+
<CollapsibleContent className="px-4 pb-4">
|
|
138
|
+
<p className="text-sm text-muted-foreground">
|
|
139
|
+
Use: <code>npm install @adamosuiteservices/ui</code>
|
|
140
|
+
</p>
|
|
141
|
+
</CollapsibleContent>
|
|
142
|
+
</Collapsible>
|
|
143
|
+
</div>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Navigation Menu
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
const [openSections, setOpenSections] = useState<string[]>(["settings"]);
|
|
150
|
+
|
|
151
|
+
const toggleSection = (id: string) => {
|
|
152
|
+
setOpenSections((prev) =>
|
|
153
|
+
prev.includes(id) ? prev.filter((s) => s !== id) : [...prev, id]
|
|
154
|
+
);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
<div className="space-y-2">
|
|
158
|
+
<Collapsible
|
|
159
|
+
open={openSections.includes("settings")}
|
|
160
|
+
onOpenChange={() => toggleSection("settings")}
|
|
161
|
+
>
|
|
162
|
+
<CollapsibleTrigger className="flex w-full items-center gap-2 p-3 rounded-lg hover:bg-muted">
|
|
163
|
+
<Icon symbol="settings" className="text-lg" />
|
|
164
|
+
<span className="flex-1 font-medium">Settings</span>
|
|
165
|
+
<Icon
|
|
166
|
+
symbol="expand_more"
|
|
167
|
+
className={`text-lg transition-transform ${
|
|
168
|
+
openSections.includes("settings") ? "rotate-180" : ""
|
|
169
|
+
}`}
|
|
170
|
+
/>
|
|
171
|
+
</CollapsibleTrigger>
|
|
172
|
+
<CollapsibleContent className="ml-6 space-y-1">
|
|
173
|
+
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
174
|
+
Profile
|
|
175
|
+
</a>
|
|
176
|
+
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
177
|
+
Security
|
|
178
|
+
</a>
|
|
179
|
+
</CollapsibleContent>
|
|
180
|
+
</Collapsible>
|
|
181
|
+
|
|
182
|
+
<Collapsible
|
|
183
|
+
open={openSections.includes("account")}
|
|
184
|
+
onOpenChange={() => toggleSection("account")}
|
|
185
|
+
>
|
|
186
|
+
<CollapsibleTrigger className="flex w-full items-center gap-2 p-3 rounded-lg hover:bg-muted">
|
|
187
|
+
<Icon symbol="person" className="text-lg" />
|
|
188
|
+
<span className="flex-1 font-medium">Account</span>
|
|
189
|
+
<Icon
|
|
190
|
+
symbol="expand_more"
|
|
191
|
+
className={`text-lg transition-transform ${
|
|
192
|
+
openSections.includes("account") ? "rotate-180" : ""
|
|
193
|
+
}`}
|
|
194
|
+
/>
|
|
195
|
+
</CollapsibleTrigger>
|
|
196
|
+
<CollapsibleContent className="ml-6 space-y-1">
|
|
197
|
+
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
198
|
+
Billing
|
|
199
|
+
</a>
|
|
200
|
+
<a href="#" className="block px-3 py-2 text-sm rounded hover:bg-muted">
|
|
201
|
+
API Keys
|
|
202
|
+
</a>
|
|
203
|
+
</CollapsibleContent>
|
|
204
|
+
</Collapsible>
|
|
205
|
+
</div>;
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Lista de Archivos
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
<Collapsible defaultOpen className="w-full space-y-2">
|
|
212
|
+
<CollapsibleTrigger className="w-full border p-3 rounded-lg text-left font-medium hover:bg-muted">
|
|
213
|
+
Recent Files
|
|
214
|
+
</CollapsibleTrigger>
|
|
215
|
+
<CollapsibleContent className="space-y-1">
|
|
216
|
+
<div className="border p-3 rounded text-sm">document.pdf</div>
|
|
217
|
+
<div className="border p-3 rounded text-sm">presentation.pptx</div>
|
|
218
|
+
<div className="border p-3 rounded text-sm">spreadsheet.xlsx</div>
|
|
219
|
+
</CollapsibleContent>
|
|
220
|
+
</Collapsible>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Sección Deshabilitada
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
<Collapsible disabled>
|
|
227
|
+
<CollapsibleTrigger className="w-full border p-3 rounded-lg text-left font-medium opacity-50 cursor-not-allowed">
|
|
228
|
+
Coming Soon
|
|
229
|
+
</CollapsibleTrigger>
|
|
230
|
+
<CollapsibleContent>
|
|
231
|
+
<p className="p-3 text-sm text-muted-foreground">Not available yet.</p>
|
|
232
|
+
</CollapsibleContent>
|
|
233
|
+
</Collapsible>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Con Layout de Tarjeta
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
<Collapsible className="border rounded-lg p-4">
|
|
240
|
+
<div className="flex items-center justify-between mb-2">
|
|
241
|
+
<h4 className="font-semibold">@user starred 3 repos</h4>
|
|
242
|
+
<CollapsibleTrigger asChild>
|
|
243
|
+
<Button variant="outline" size="sm">
|
|
244
|
+
<Icon symbol="unfold_more" className="text-base" />
|
|
245
|
+
</Button>
|
|
246
|
+
</CollapsibleTrigger>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<div className="border px-4 py-2 rounded font-mono text-sm">
|
|
250
|
+
@radix-ui/primitives
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<CollapsibleContent className="mt-2 space-y-2">
|
|
254
|
+
<div className="border px-4 py-2 rounded font-mono text-sm">
|
|
255
|
+
@radix-ui/colors
|
|
256
|
+
</div>
|
|
257
|
+
<div className="border px-4 py-2 rounded font-mono text-sm">
|
|
258
|
+
@stitches/react
|
|
259
|
+
</div>
|
|
260
|
+
</CollapsibleContent>
|
|
261
|
+
</Collapsible>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Casos de Uso Comunes
|
|
265
|
+
|
|
266
|
+
**FAQ sections**: Lista de preguntas frecuentes expandibles
|
|
267
|
+
**Navigation menus**: Menús colapsables con subsecciones
|
|
268
|
+
**Details/Summary**: Información adicional opcional
|
|
269
|
+
**File browsers**: Estructuras de carpetas expandibles
|
|
270
|
+
**Settings panels**: Grupos de configuraciones organizadas
|
|
271
|
+
**Table rows**: Filas de tabla con detalles expandibles
|
|
272
|
+
|
|
273
|
+
## Estilos y Animaciones
|
|
274
|
+
|
|
275
|
+
### Data States
|
|
276
|
+
|
|
277
|
+
- **Abierto**: `data-state="open"` en todos los componentes
|
|
278
|
+
- **Cerrado**: `data-state="closed"` en todos los componentes
|
|
279
|
+
- **Disabled**: `data-disabled` cuando `disabled={true}`
|
|
280
|
+
|
|
281
|
+
### Animación Suave
|
|
282
|
+
|
|
283
|
+
El contenido usa animaciones CSS automáticas (height, opacity) al expandir/colapsar. No requiere configuración adicional.
|
|
284
|
+
|
|
285
|
+
### Custom Animations
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
<CollapsibleContent className="data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
|
|
289
|
+
Content with custom animations
|
|
290
|
+
</CollapsibleContent>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Accesibilidad
|
|
294
|
+
|
|
295
|
+
- ✅ **Navegación teclado**: Enter/Space para toggle en trigger, Tab para navegar
|
|
296
|
+
- ✅ **ARIA**: `aria-expanded`, `aria-controls` automáticos en trigger
|
|
297
|
+
- ✅ **Screen readers**: Anuncia estado expandido/colapsado
|
|
298
|
+
- ✅ **Focus visible**: Trigger recibe focus del teclado
|
|
299
|
+
- ✅ **Disabled state**: `aria-disabled` cuando disabled
|
|
300
|
+
|
|
301
|
+
## Notas de Implementación
|
|
302
|
+
|
|
303
|
+
- **Basado en Radix UI**: `@radix-ui/react-collapsible`
|
|
304
|
+
- **No tiene estilos propios**: Wrapper limpio, agrega tus propios estilos
|
|
305
|
+
- **Data slots**: `data-slot="collapsible"`, `data-slot="collapsible-trigger"`, `data-slot="collapsible-content"`
|
|
306
|
+
- **asChild pattern**: CollapsibleTrigger soporta `asChild` para usar componentes custom
|
|
307
|
+
- **Animaciones automáticas**: Radix maneja transiciones de height/opacity
|
|
308
|
+
- **forceMount**: Útil para animaciones custom o cuando necesitas el DOM montado siempre
|
|
309
|
+
- **Multiple instances**: Puedes tener múltiples Collapsibles independientes
|
|
310
|
+
- **Accordion vs Collapsible**: Usa Accordion cuando solo uno debe estar abierto, Collapsible para control independiente
|
|
311
|
+
|
|
312
|
+
## Troubleshooting
|
|
313
|
+
|
|
314
|
+
**Animación no suave**: Radix maneja animaciones automáticamente, si no se ve suave verifica que no haya `transition` conflictivos en CSS
|
|
315
|
+
**Trigger no clickeable**: Verifica que esté dentro de `<Collapsible>`, no como hermano
|
|
316
|
+
**asChild no funciona**: Asegúrate que el child acepta props `onClick` y `aria-*`
|
|
317
|
+
**Content siempre visible**: Verifica que no tengas `forceMount` activado sin intención
|
|
318
|
+
**Estado no sincroniza**: En modo controlado, asegúrate de usar ambos `open` y `onOpenChange`
|
|
319
|
+
|
|
320
|
+
## Referencias
|
|
321
|
+
|
|
322
|
+
- **Radix UI Collapsible**: https://www.radix-ui.com/primitives/docs/components/collapsible
|
|
323
|
+
- **ARIA Disclosure**: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/
|