@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.
Files changed (62) hide show
  1. package/dist/{button-Bn4LFAa9.js → button-B0lWuG-D.js} +27 -18
  2. package/dist/{button-Day6_fbu.cjs → button-DVrteFz9.cjs} +2 -2
  3. package/dist/button.cjs +1 -1
  4. package/dist/button.js +1 -1
  5. package/dist/{calendar-B1_ybTg0.js → calendar-CfqtuOWv.js} +1 -1
  6. package/dist/{calendar-CZkzHgYi.cjs → calendar-CpUN6BGK.cjs} +1 -1
  7. package/dist/calendar.cjs +1 -1
  8. package/dist/calendar.js +1 -1
  9. package/dist/{combobox-BOi7QzmO.js → combobox-B8HMlZy6.js} +1 -1
  10. package/dist/{combobox-0ndFo07_.cjs → combobox-Btj-hiBy.cjs} +1 -1
  11. package/dist/combobox.cjs +1 -1
  12. package/dist/combobox.js +1 -1
  13. package/dist/components/ui/alert/alert.d.ts +1 -1
  14. package/dist/components/ui/button/button.d.ts +3 -2
  15. package/dist/components/ui/card/card.d.ts +2 -2
  16. package/dist/date-picker-selector.cjs +1 -1
  17. package/dist/date-picker-selector.js +3 -3
  18. package/dist/file-upload.cjs +1 -1
  19. package/dist/file-upload.js +1 -1
  20. package/dist/full-screen-loader.cjs +1 -1
  21. package/dist/full-screen-loader.js +1 -1
  22. package/dist/input-group.cjs +1 -1
  23. package/dist/input-group.js +1 -1
  24. package/dist/pagination.cjs +1 -1
  25. package/dist/pagination.js +1 -1
  26. package/dist/sidebar.cjs +1 -1
  27. package/dist/sidebar.js +1 -1
  28. package/dist/styles.css +1 -1
  29. package/dist/tabs.cjs +14 -16
  30. package/dist/tabs.js +17 -19
  31. package/docs/AI-GUIDE.md +321 -321
  32. package/docs/components/layout/full-screen-loader.md +2 -2
  33. package/docs/components/layout/sidebar.md +399 -399
  34. package/docs/components/layout/toaster.md +436 -436
  35. package/docs/components/ui/accordion-rounded.md +584 -584
  36. package/docs/components/ui/accordion.md +269 -269
  37. package/docs/components/ui/button.md +35 -23
  38. package/docs/components/ui/calendar.md +1159 -1159
  39. package/docs/components/ui/card.md +1455 -1455
  40. package/docs/components/ui/checkbox.md +292 -292
  41. package/docs/components/ui/collapsible.md +323 -323
  42. package/docs/components/ui/dialog.md +628 -628
  43. package/docs/components/ui/field.md +706 -706
  44. package/docs/components/ui/hover-card.md +446 -446
  45. package/docs/components/ui/kbd.md +434 -434
  46. package/docs/components/ui/label.md +359 -359
  47. package/docs/components/ui/pagination.md +650 -650
  48. package/docs/components/ui/popover.md +536 -536
  49. package/docs/components/ui/progress.md +182 -182
  50. package/docs/components/ui/radio-group.md +311 -311
  51. package/docs/components/ui/separator.md +214 -214
  52. package/docs/components/ui/sheet.md +174 -174
  53. package/docs/components/ui/skeleton.md +140 -140
  54. package/docs/components/ui/spinner.md +170 -170
  55. package/docs/components/ui/switch.md +408 -408
  56. package/docs/components/ui/tabs-underline.md +106 -106
  57. package/docs/components/ui/tabs.md +125 -122
  58. package/docs/components/ui/textarea.md +243 -243
  59. package/docs/components/ui/toggle.md +237 -237
  60. package/docs/components/ui/tooltip.md +317 -317
  61. package/docs/components/ui/typography.md +320 -320
  62. package/package.json +1 -1
@@ -1,628 +1,628 @@
1
- # Dialog
2
-
3
- Ventana modal centrada sobre overlay semi-transparente, basada en Radix UI. Soporta formularios, confirmaciones, información, y acciones. Útil para capturar atención del usuario en tareas críticas.
4
-
5
- ## Importación
6
-
7
- ```tsx
8
- import {
9
- Dialog,
10
- DialogTrigger,
11
- DialogContent,
12
- DialogHeader,
13
- DialogTitle,
14
- DialogDescription,
15
- DialogBody,
16
- DialogFooter,
17
- DialogClose,
18
- DialogOverlay,
19
- DialogPortal,
20
- } from "@adamosuiteservices/ui/dialog";
21
- ```
22
-
23
- ## Anatomía
24
-
25
- ```tsx
26
- <Dialog>
27
- <DialogTrigger>Open Dialog</DialogTrigger>
28
- <DialogContent>
29
- <DialogHeader>
30
- <DialogTitle>Title</DialogTitle>
31
- <DialogDescription>Description text</DialogDescription>
32
- </DialogHeader>
33
- <DialogBody>{/* Main content */}</DialogBody>
34
- <DialogFooter>
35
- <DialogClose asChild>
36
- <Button variant="outline">Cancel</Button>
37
- </DialogClose>
38
- <Button>Confirm</Button>
39
- </DialogFooter>
40
- </DialogContent>
41
- </Dialog>
42
- ```
43
-
44
- **Componentes**: 10 (Dialog, Trigger, Content, Header, Title, Description, Body, Footer, Close, Overlay, Portal)
45
-
46
- ## Props Principales
47
-
48
- ### Dialog (Root)
49
-
50
- | Prop | Tipo | Default | Descripción |
51
- | -------------- | ------------------------- | ------- | ----------------------------------------- |
52
- | `open` | `boolean` | - | Estado controlado del dialog |
53
- | `onOpenChange` | `(open: boolean) => void` | - | Callback cuando cambia estado |
54
- | `defaultOpen` | `boolean` | `false` | Estado inicial no controlado |
55
- | `modal` | `boolean` | `true` | Bloquea interacción con contenido externo |
56
-
57
- ### DialogTrigger
58
-
59
- | Prop | Tipo | Descripción |
60
- | ----------- | --------- | -------------------------------------------------- |
61
- | `asChild` | `boolean` | Pasa props al child en lugar de renderizar wrapper |
62
- | `className` | `string` | Clases CSS adicionales |
63
-
64
- ### DialogContent
65
-
66
- | Prop | Tipo | Default | Descripción |
67
- | ---------------------- | ----------------- | ------- | ------------------------------------------------------- |
68
- | `showCloseButton` | `boolean` | `true` | Muestra botón X en esquina superior derecha |
69
- | `theme` | `Theme` | - | Tema personalizado (default, dark, pay, sign, risk, id) |
70
- | `className` | `string` | - | Clases CSS adicionales |
71
- | `onEscapeKeyDown` | `(event) => void` | - | Callback al presionar Escape |
72
- | `onPointerDownOutside` | `(event) => void` | - | Callback al hacer clic fuera |
73
- | `onInteractOutside` | `(event) => void` | - | Callback al interactuar fuera |
74
-
75
- **Estilos default**: `max-w-lg`, `max-w-[calc(100%-2rem)]` en mobile, centrado, `rounded-lg`, `p-6`, `shadow-lg`
76
-
77
- ### DialogTitle
78
-
79
- | Prop | Tipo | Descripción |
80
- | ----------- | -------- | ---------------------- |
81
- | `className` | `string` | Clases CSS adicionales |
82
-
83
- **Estilos**: `text-lg`, `font-semibold`, `leading-none`
84
-
85
- ### DialogDescription
86
-
87
- | Prop | Tipo | Descripción |
88
- | ----------- | -------- | ---------------------- |
89
- | `className` | `string` | Clases CSS adicionales |
90
-
91
- **Estilos**: `text-sm`, `text-muted-foreground`
92
-
93
- ### DialogBody
94
-
95
- | Prop | Tipo | Descripción |
96
- | ----------- | -------- | ---------------------- |
97
- | `className` | `string` | Clases CSS adicionales |
98
-
99
- **Estilos**: `mt-2 mb-6`
100
- **Propósito**: Contenedor para el contenido principal del dialog entre el header y footer. Proporciona espaciado vertical consistente.
101
-
102
- ### DialogHeader
103
-
104
- | Prop | Tipo | Descripción |
105
- | ----------- | -------- | ---------------------- |
106
- | `className` | `string` | Clases CSS adicionales |
107
-
108
- **Estilos**: `flex flex-col gap-2`, `text-center` en mobile, `sm:text-left`
109
-
110
- ### DialogFooter
111
-
112
- | Prop | Tipo | Descripción |
113
- | ----------- | -------- | ---------------------- |
114
- | `className` | `string` | Clases CSS adicionales |
115
-
116
- **Estilos**: `flex-col-reverse` en mobile, `sm:flex-row sm:justify-end`, `gap-2`
117
-
118
- ### DialogClose
119
-
120
- | Prop | Tipo | Descripción |
121
- | ----------- | --------- | ------------------------------------------------- |
122
- | `asChild` | `boolean` | Pasa props al child en lugar de renderizar button |
123
- | `className` | `string` | Clases CSS adicionales |
124
-
125
- ## Patrones de Uso
126
-
127
- ### Básico
128
-
129
- ```tsx
130
- <Dialog>
131
- <DialogTrigger>Open</DialogTrigger>
132
- <DialogContent>
133
- <DialogHeader>
134
- <DialogTitle>Are you absolutely sure?</DialogTitle>
135
- <DialogDescription>
136
- This action cannot be undone. This will permanently delete your account.
137
- </DialogDescription>
138
- </DialogHeader>
139
- </DialogContent>
140
- </Dialog>
141
- ```
142
-
143
- ### Con Trigger Custom (asChild)
144
-
145
- ```tsx
146
- <Dialog>
147
- <DialogTrigger asChild>
148
- <Button variant="outline">Edit Profile</Button>
149
- </DialogTrigger>
150
- <DialogContent>
151
- <DialogHeader>
152
- <DialogTitle>Edit Profile</DialogTitle>
153
- <DialogDescription>Make changes to your profile here.</DialogDescription>
154
- </DialogHeader>
155
- </DialogContent>
156
- </Dialog>
157
- ```
158
-
159
- ### Formulario de Edición
160
-
161
- ```tsx
162
- import { Icon } from "@adamosuiteservices/ui/icon";
163
- import { Input } from "@adamosuiteservices/ui/input";
164
- import { Label } from "@adamosuiteservices/ui/label";
165
-
166
- <Dialog>
167
- <DialogTrigger asChild>
168
- <Button variant="outline">Edit Profile</Button>
169
- </DialogTrigger>
170
- <DialogContent className="sm:max-w-[425px]">
171
- <DialogHeader>
172
- <DialogTitle>Edit profile</DialogTitle>
173
- <DialogDescription>
174
- Make changes to your profile here. Click save when you're done.
175
- </DialogDescription>
176
- </DialogHeader>
177
- <DialogBody className="grid gap-4">
178
- <div className="grid grid-cols-4 items-center gap-4">
179
- <Label htmlFor="name" className="text-right">
180
- Name
181
- </Label>
182
- <Input id="name" defaultValue="Pedro Duarte" className="col-span-3" />
183
- </div>
184
- <div className="grid grid-cols-4 items-center gap-4">
185
- <Label htmlFor="username" className="text-right">
186
- Username
187
- </Label>
188
- <Input id="username" defaultValue="@peduarte" className="col-span-3" />
189
- </div>
190
- </DialogBody>
191
- <DialogFooter>
192
- <Button type="submit">
193
- <Icon symbol="save" />
194
- Save changes
195
- </Button>
196
- </DialogFooter>
197
- </DialogContent>
198
- </Dialog>;
199
- ```
200
-
201
- ### Compartir Link
202
-
203
- ```tsx
204
- import { Icon } from "@adamosuiteservices/ui/icon";
205
-
206
- <Dialog>
207
- <DialogTrigger asChild>
208
- <Button variant="outline">
209
- <Icon symbol="share" />
210
- Share
211
- </Button>
212
- </DialogTrigger>
213
- <DialogContent className="sm:max-w-md">
214
- <DialogHeader>
215
- <DialogTitle>Share link</DialogTitle>
216
- <DialogDescription>
217
- Anyone who has this link will be able to view this.
218
- </DialogDescription>
219
- </DialogHeader>
220
- <DialogBody className="flex items-center space-x-2">
221
- <div className="grid flex-1 gap-2">
222
- <Label htmlFor="link" className="sr-only">
223
- Link
224
- </Label>
225
- <Input
226
- id="link"
227
- defaultValue="https://ui.shadcn.com/docs/installation"
228
- readOnly
229
- />
230
- </div>
231
- <Button type="submit" size="sm" className="px-3">
232
- <Icon symbol="content_copy" />
233
- </Button>
234
- </DialogBody>
235
- <DialogFooter className="sm:justify-start">
236
- <DialogClose asChild>
237
- <Button type="button" variant="secondary">
238
- Close
239
- </Button>
240
- </DialogClose>
241
- </DialogFooter>
242
- </DialogContent>
243
- </Dialog>;
244
- ```
245
-
246
- ### Confirmación de Eliminación
247
-
248
- ```tsx
249
- import { Icon } from "@adamosuiteservices/ui/icon";
250
- import { Checkbox } from "@adamosuiteservices/ui/checkbox";
251
-
252
- <Dialog>
253
- <DialogTrigger asChild>
254
- <Button variant="destructive">
255
- <Icon symbol="delete" />
256
- Delete Account
257
- </Button>
258
- </DialogTrigger>
259
- <DialogContent>
260
- <DialogHeader>
261
- <DialogTitle>Delete Account</DialogTitle>
262
- <DialogDescription>
263
- This action cannot be undone. This will permanently delete your account
264
- and remove all of your data from our servers.
265
- </DialogDescription>
266
- </DialogHeader>
267
- <DialogBody>
268
- <Label className="flex items-center gap-2 text-sm">
269
- <Checkbox />I understand that this action is irreversible
270
- </Label>
271
- </DialogBody>
272
- <DialogFooter>
273
- <DialogClose asChild>
274
- <Button variant="outline">Cancel</Button>
275
- </DialogClose>
276
- <Button variant="destructive">
277
- <Icon symbol="delete" />
278
- Delete Account
279
- </Button>
280
- </DialogFooter>
281
- </DialogContent>
282
- </Dialog>;
283
- ```
284
-
285
- ### Crear Proyecto
286
-
287
- ```tsx
288
- import { Icon } from "@adamosuiteservices/ui/icon";
289
-
290
- <Dialog>
291
- <DialogTrigger asChild>
292
- <Button>
293
- <Icon symbol="add" />
294
- New Project
295
- </Button>
296
- </DialogTrigger>
297
- <DialogContent className="sm:max-w-[425px]">
298
- <DialogHeader>
299
- <DialogTitle>Create Project</DialogTitle>
300
- <DialogDescription>
301
- Create a new project to get started. You can always change these
302
- settings later.
303
- </DialogDescription>
304
- </DialogHeader>
305
- <DialogBody className="grid gap-4">
306
- <div className="grid gap-2">
307
- <Label htmlFor="project-name">Project Name</Label>
308
- <Input id="project-name" placeholder="My Awesome Project" />
309
- </div>
310
- <div className="grid gap-2">
311
- <Label htmlFor="description">Description</Label>
312
- <Input id="description" placeholder="Brief description" />
313
- </div>
314
- <div className="grid gap-2">
315
- <Label htmlFor="repository">Repository URL (optional)</Label>
316
- <Input id="repository" placeholder="https://github.com/username/repo" />
317
- </div>
318
- <div className="flex items-center space-x-2">
319
- <Checkbox id="public" />
320
- <Label htmlFor="public" className="text-sm">
321
- Make this project public
322
- </Label>
323
- </div>
324
- </DialogBody>
325
- <DialogFooter>
326
- <DialogClose asChild>
327
- <Button variant="outline">Cancel</Button>
328
- </DialogClose>
329
- <Button type="submit">
330
- <Icon symbol="add" />
331
- Create Project
332
- </Button>
333
- </DialogFooter>
334
- </DialogContent>
335
- </Dialog>;
336
- ```
337
-
338
- ### Ver Detalles (Read-only)
339
-
340
- ```tsx
341
- import { Icon } from "@adamosuiteservices/ui/icon";
342
-
343
- <Dialog>
344
- <DialogTrigger asChild>
345
- <Button variant="outline">
346
- <Icon symbol="person" />
347
- View Details
348
- </Button>
349
- </DialogTrigger>
350
- <DialogContent>
351
- <DialogHeader>
352
- <DialogTitle>User Details</DialogTitle>
353
- <DialogDescription>
354
- View detailed information about this user account.
355
- </DialogDescription>
356
- </DialogHeader>
357
- <DialogBody className="space-y-4">
358
- <div className="grid grid-cols-3 gap-4">
359
- <div className="font-medium">Name:</div>
360
- <div className="col-span-2">John Doe</div>
361
- </div>
362
- <div className="grid grid-cols-3 gap-4">
363
- <div className="font-medium">Email:</div>
364
- <div className="col-span-2">john.doe@example.com</div>
365
- </div>
366
- <div className="grid grid-cols-3 gap-4">
367
- <div className="font-medium">Role:</div>
368
- <div className="col-span-2">Administrator</div>
369
- </div>
370
- <div className="grid grid-cols-3 gap-4">
371
- <div className="font-medium">Joined:</div>
372
- <div className="col-span-2">January 15, 2024</div>
373
- </div>
374
- <div className="grid grid-cols-3 gap-4">
375
- <div className="font-medium">Last Active:</div>
376
- <div className="col-span-2">2 hours ago</div>
377
- </div>
378
- </DialogBody>
379
- <DialogFooter>
380
- <DialogClose asChild>
381
- <Button variant="outline">Close</Button>
382
- </DialogClose>
383
- <Button>
384
- <Icon symbol="person" />
385
- Edit User
386
- </Button>
387
- </DialogFooter>
388
- </DialogContent>
389
- </Dialog>;
390
- ```
391
-
392
- ### Información Estructurada
393
-
394
- ```tsx
395
- import { Icon } from "@adamosuiteservices/ui/icon";
396
-
397
- <Dialog>
398
- <DialogTrigger asChild>
399
- <Button variant="outline">
400
- <Icon symbol="info" />
401
- More Info
402
- </Button>
403
- </DialogTrigger>
404
- <DialogContent>
405
- <DialogHeader>
406
- <DialogTitle>Important Information</DialogTitle>
407
- <DialogDescription>
408
- Please read the following information carefully before proceeding.
409
- </DialogDescription>
410
- </DialogHeader>
411
- <DialogBody className="space-y-4 text-sm">
412
- <div>
413
- <h4 className="font-medium mb-2">Data Processing</h4>
414
- <p className="text-muted-foreground">
415
- Your data will be processed according to our privacy policy. We ensure
416
- full compliance with GDPR and other data protection regulations.
417
- </p>
418
- </div>
419
- <div>
420
- <h4 className="font-medium mb-2">Security</h4>
421
- <p className="text-muted-foreground">
422
- All data is encrypted both in transit and at rest using
423
- industry-standard encryption protocols.
424
- </p>
425
- </div>
426
- <div>
427
- <h4 className="font-medium mb-2">Support</h4>
428
- <p className="text-muted-foreground">
429
- If you have any questions or concerns, please contact our support team
430
- at support@example.com.
431
- </p>
432
- </div>
433
- </DialogBody>
434
- <DialogFooter>
435
- <DialogClose asChild>
436
- <Button>Got it</Button>
437
- </DialogClose>
438
- </DialogFooter>
439
- </DialogContent>
440
- </Dialog>;
441
- ```
442
-
443
- ### Sin Botón de Cerrar
444
-
445
- ```tsx
446
- <Dialog>
447
- <DialogTrigger asChild>
448
- <Button variant="outline">Open (No X)</Button>
449
- </DialogTrigger>
450
- <DialogContent showCloseButton={false}>
451
- <DialogHeader>
452
- <DialogTitle>Custom Close Behavior</DialogTitle>
453
- <DialogDescription>
454
- This dialog doesn't have the X button. You must use the action buttons.
455
- </DialogDescription>
456
- </DialogHeader>
457
- <DialogBody>
458
- <p className="text-sm text-muted-foreground">
459
- This pattern is useful when you want to force users to make a deliberate
460
- choice rather than accidentally closing the dialog.
461
- </p>
462
- </DialogBody>
463
- <DialogFooter>
464
- <DialogClose asChild>
465
- <Button variant="outline">Cancel</Button>
466
- </DialogClose>
467
- <DialogClose asChild>
468
- <Button>Confirm</Button>
469
- </DialogClose>
470
- </DialogFooter>
471
- </DialogContent>
472
- </Dialog>
473
- ```
474
-
475
- **Uso**: Forzar decisión deliberada, prevenir cierre accidental
476
-
477
- ### Controlado
478
-
479
- ```tsx
480
- import { useState } from "react";
481
-
482
- function App() {
483
- const [open, setOpen] = useState(false);
484
-
485
- return (
486
- <Dialog open={open} onOpenChange={setOpen}>
487
- <DialogTrigger>Open Dialog</DialogTrigger>
488
- <DialogContent>
489
- <DialogHeader>
490
- <DialogTitle>Controlled Dialog</DialogTitle>
491
- </DialogHeader>
492
- <Button onClick={() => setOpen(false)}>Close Programmatically</Button>
493
- </DialogContent>
494
- </Dialog>
495
- );
496
- }
497
- ```
498
-
499
- ### Con Tema Custom
500
-
501
- ```tsx
502
- <DialogContent theme="dark">
503
- <DialogHeader>
504
- <DialogTitle>Dark Theme Dialog</DialogTitle>
505
- <DialogDescription>This dialog uses a custom theme.</DialogDescription>
506
- </DialogHeader>
507
- </DialogContent>
508
- ```
509
-
510
- **Temas disponibles**: `default`, `dark`, `pay`, `sign`, `risk`, `id`
511
-
512
- ## Casos de Uso Comunes
513
-
514
- **Formularios de edición**: Edit profile, settings, preferences
515
- **Confirmaciones destructivas**: Delete account, remove items, clear data
516
- **Crear nuevos items**: New project, add user, create record
517
- **Compartir contenido**: Share links, export data, send invitations
518
- **Ver detalles**: User info, product details, transaction summary
519
- **Información**: Disclaimers, terms, help content
520
-
521
- ## Estados y Data Attributes
522
-
523
- ### Dialog States
524
-
525
- - **Open**: `data-[state=open]` → animaciones de entrada
526
- - **Closed**: `data-[state=closed]` → animaciones de salida
527
-
528
- ### Overlay Animations
529
-
530
- - **Opening**: `fade-in-0`
531
- - **Closing**: `fade-out-0`
532
-
533
- ### Content Animations
534
-
535
- - **Opening**: `fade-in-0`, `zoom-in-95`
536
- - **Closing**: `fade-out-0`, `zoom-out-95`
537
- - **Duration**: `200ms`
538
-
539
- ## Navegación por Teclado
540
-
541
- - ✅ **Escape**: Cierra el dialog (previene con `onEscapeKeyDown`)
542
- - ✅ **Tab**: Navega entre elementos focusables dentro del dialog
543
- - ✅ **Shift+Tab**: Navegación inversa
544
- - ✅ **Enter**: Activa botón/elemento enfocado
545
-
546
- ## Accesibilidad
547
-
548
- - ✅ **ARIA**: `role="dialog"`, `aria-labelledby` (title), `aria-describedby` (description)
549
- - ✅ **Focus trap**: Focus queda dentro del dialog mientras está abierto
550
- - ✅ **Focus restoration**: Focus vuelve al trigger al cerrar
551
- - ✅ **Screen readers**: Anuncia título, descripción, y contenido
552
- - ✅ **Keyboard navigation**: Completamente navegable por teclado
553
- - ✅ **Close button**: `aria-label="Close"` en botón X
554
- - ✅ **Modal behavior**: Bloquea interacción con contenido externo
555
-
556
- ## Notas de Implementación
557
-
558
- - **Basado en Radix UI**: `@radix-ui/react-dialog`
559
- - **Portal rendering**: Content se renderiza en `document.body`
560
- - **Overlay**: `bg-black/50`, `fixed inset-0`, `z-50`
561
- - **Centrado**: `top-[50%] left-[50%]`, `translate-x-[-50%] translate-y-[-50%]`
562
- - **Responsive**: `max-w-[calc(100%-2rem)]` en mobile, `sm:max-w-lg` en desktop
563
- - **Close button**: XIcon automático en esquina superior derecha si `showCloseButton={true}`
564
- - **Auto-close**: Cierra con Escape, clic fuera, o DialogClose
565
- - **Focus management**: Primer elemento focusable recibe focus al abrir
566
- - **Theme support**: Prop `theme` aplica `data-theme` al content
567
- - **Z-index**: 50 para overlay y content
568
-
569
- ## Responsive Behavior
570
-
571
- ### Mobile
572
-
573
- - `max-w-[calc(100%-2rem)]`: Margen de 1rem a cada lado
574
- - `text-center`: Header centrado
575
- - `flex-col-reverse`: Footer con botones apilados (Confirm arriba, Cancel abajo)
576
-
577
- ### Desktop (sm+)
578
-
579
- - `sm:max-w-lg`: Ancho máximo 32rem
580
- - `sm:text-left`: Header alineado a izquierda
581
- - `sm:flex-row sm:justify-end`: Footer horizontal con botones a la derecha
582
-
583
- ## Customización de Ancho
584
-
585
- ```tsx
586
- {
587
- /* Small dialog */
588
- }
589
- <DialogContent className="sm:max-w-md">...</DialogContent>;
590
-
591
- {
592
- /* Medium (default) */
593
- }
594
- <DialogContent className="sm:max-w-lg">...</DialogContent>;
595
-
596
- {
597
- /* Large */
598
- }
599
- <DialogContent className="sm:max-w-2xl">...</DialogContent>;
600
-
601
- {
602
- /* Extra large */
603
- }
604
- <DialogContent className="sm:max-w-4xl">...</DialogContent>;
605
-
606
- {
607
- /* Full width with margin */
608
- }
609
- <DialogContent className="sm:max-w-[90vw]">...</DialogContent>;
610
- ```
611
-
612
- ## Troubleshooting
613
-
614
- **Dialog no cierra con Escape**: Verifica que no estés previniendo evento con `onEscapeKeyDown`
615
- **Dialog no cierra al hacer clic fuera**: Verifica `onPointerDownOutside` o `modal={false}`
616
- **Focus no vuelve al trigger**: Asegúrate de que el trigger sigue en el DOM
617
- **Scroll bloqueado después de cerrar**: Radix maneja esto automáticamente, verifica conflictos con CSS
618
- **Content no centrado**: Evita `transform` CSS en elementos padre que afecten positioning
619
- **Animaciones no funcionan**: Verifica que `@tailwindcss/animate` esté instalado
620
- **Botón X no aparece**: Verifica `showCloseButton={true}` (default)
621
- **Overlay no oscurece**: Z-index conflict, aumenta z-index del overlay
622
- **Title/Description no anunciados**: Asegúrate de usar componentes DialogTitle y DialogDescription (no divs)
623
-
624
- ## Referencias
625
-
626
- - **Radix UI Dialog**: https://www.radix-ui.com/primitives/docs/components/dialog
627
- - **shadcn/ui Dialog**: https://ui.shadcn.com/docs/components/dialog
628
- - **ARIA Dialog Pattern**: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
1
+ # Dialog
2
+
3
+ Ventana modal centrada sobre overlay semi-transparente, basada en Radix UI. Soporta formularios, confirmaciones, información, y acciones. Útil para capturar atención del usuario en tareas críticas.
4
+
5
+ ## Importación
6
+
7
+ ```tsx
8
+ import {
9
+ Dialog,
10
+ DialogTrigger,
11
+ DialogContent,
12
+ DialogHeader,
13
+ DialogTitle,
14
+ DialogDescription,
15
+ DialogBody,
16
+ DialogFooter,
17
+ DialogClose,
18
+ DialogOverlay,
19
+ DialogPortal,
20
+ } from "@adamosuiteservices/ui/dialog";
21
+ ```
22
+
23
+ ## Anatomía
24
+
25
+ ```tsx
26
+ <Dialog>
27
+ <DialogTrigger>Open Dialog</DialogTrigger>
28
+ <DialogContent>
29
+ <DialogHeader>
30
+ <DialogTitle>Title</DialogTitle>
31
+ <DialogDescription>Description text</DialogDescription>
32
+ </DialogHeader>
33
+ <DialogBody>{/* Main content */}</DialogBody>
34
+ <DialogFooter>
35
+ <DialogClose asChild>
36
+ <Button variant="outline">Cancel</Button>
37
+ </DialogClose>
38
+ <Button>Confirm</Button>
39
+ </DialogFooter>
40
+ </DialogContent>
41
+ </Dialog>
42
+ ```
43
+
44
+ **Componentes**: 10 (Dialog, Trigger, Content, Header, Title, Description, Body, Footer, Close, Overlay, Portal)
45
+
46
+ ## Props Principales
47
+
48
+ ### Dialog (Root)
49
+
50
+ | Prop | Tipo | Default | Descripción |
51
+ | -------------- | ------------------------- | ------- | ----------------------------------------- |
52
+ | `open` | `boolean` | - | Estado controlado del dialog |
53
+ | `onOpenChange` | `(open: boolean) => void` | - | Callback cuando cambia estado |
54
+ | `defaultOpen` | `boolean` | `false` | Estado inicial no controlado |
55
+ | `modal` | `boolean` | `true` | Bloquea interacción con contenido externo |
56
+
57
+ ### DialogTrigger
58
+
59
+ | Prop | Tipo | Descripción |
60
+ | ----------- | --------- | -------------------------------------------------- |
61
+ | `asChild` | `boolean` | Pasa props al child en lugar de renderizar wrapper |
62
+ | `className` | `string` | Clases CSS adicionales |
63
+
64
+ ### DialogContent
65
+
66
+ | Prop | Tipo | Default | Descripción |
67
+ | ---------------------- | ----------------- | ------- | ------------------------------------------------------- |
68
+ | `showCloseButton` | `boolean` | `true` | Muestra botón X en esquina superior derecha |
69
+ | `theme` | `Theme` | - | Tema personalizado (default, dark, pay, sign, risk, id) |
70
+ | `className` | `string` | - | Clases CSS adicionales |
71
+ | `onEscapeKeyDown` | `(event) => void` | - | Callback al presionar Escape |
72
+ | `onPointerDownOutside` | `(event) => void` | - | Callback al hacer clic fuera |
73
+ | `onInteractOutside` | `(event) => void` | - | Callback al interactuar fuera |
74
+
75
+ **Estilos default**: `max-w-lg`, `max-w-[calc(100%-2rem)]` en mobile, centrado, `rounded-lg`, `p-6`, `shadow-lg`
76
+
77
+ ### DialogTitle
78
+
79
+ | Prop | Tipo | Descripción |
80
+ | ----------- | -------- | ---------------------- |
81
+ | `className` | `string` | Clases CSS adicionales |
82
+
83
+ **Estilos**: `text-lg`, `font-semibold`, `leading-none`
84
+
85
+ ### DialogDescription
86
+
87
+ | Prop | Tipo | Descripción |
88
+ | ----------- | -------- | ---------------------- |
89
+ | `className` | `string` | Clases CSS adicionales |
90
+
91
+ **Estilos**: `text-sm`, `text-muted-foreground`
92
+
93
+ ### DialogBody
94
+
95
+ | Prop | Tipo | Descripción |
96
+ | ----------- | -------- | ---------------------- |
97
+ | `className` | `string` | Clases CSS adicionales |
98
+
99
+ **Estilos**: `mt-2 mb-6`
100
+ **Propósito**: Contenedor para el contenido principal del dialog entre el header y footer. Proporciona espaciado vertical consistente.
101
+
102
+ ### DialogHeader
103
+
104
+ | Prop | Tipo | Descripción |
105
+ | ----------- | -------- | ---------------------- |
106
+ | `className` | `string` | Clases CSS adicionales |
107
+
108
+ **Estilos**: `flex flex-col gap-2`, `text-center` en mobile, `sm:text-left`
109
+
110
+ ### DialogFooter
111
+
112
+ | Prop | Tipo | Descripción |
113
+ | ----------- | -------- | ---------------------- |
114
+ | `className` | `string` | Clases CSS adicionales |
115
+
116
+ **Estilos**: `flex-col-reverse` en mobile, `sm:flex-row sm:justify-end`, `gap-2`
117
+
118
+ ### DialogClose
119
+
120
+ | Prop | Tipo | Descripción |
121
+ | ----------- | --------- | ------------------------------------------------- |
122
+ | `asChild` | `boolean` | Pasa props al child en lugar de renderizar button |
123
+ | `className` | `string` | Clases CSS adicionales |
124
+
125
+ ## Patrones de Uso
126
+
127
+ ### Básico
128
+
129
+ ```tsx
130
+ <Dialog>
131
+ <DialogTrigger>Open</DialogTrigger>
132
+ <DialogContent>
133
+ <DialogHeader>
134
+ <DialogTitle>Are you absolutely sure?</DialogTitle>
135
+ <DialogDescription>
136
+ This action cannot be undone. This will permanently delete your account.
137
+ </DialogDescription>
138
+ </DialogHeader>
139
+ </DialogContent>
140
+ </Dialog>
141
+ ```
142
+
143
+ ### Con Trigger Custom (asChild)
144
+
145
+ ```tsx
146
+ <Dialog>
147
+ <DialogTrigger asChild>
148
+ <Button variant="outline">Edit Profile</Button>
149
+ </DialogTrigger>
150
+ <DialogContent>
151
+ <DialogHeader>
152
+ <DialogTitle>Edit Profile</DialogTitle>
153
+ <DialogDescription>Make changes to your profile here.</DialogDescription>
154
+ </DialogHeader>
155
+ </DialogContent>
156
+ </Dialog>
157
+ ```
158
+
159
+ ### Formulario de Edición
160
+
161
+ ```tsx
162
+ import { Icon } from "@adamosuiteservices/ui/icon";
163
+ import { Input } from "@adamosuiteservices/ui/input";
164
+ import { Label } from "@adamosuiteservices/ui/label";
165
+
166
+ <Dialog>
167
+ <DialogTrigger asChild>
168
+ <Button variant="outline">Edit Profile</Button>
169
+ </DialogTrigger>
170
+ <DialogContent className="sm:max-w-[425px]">
171
+ <DialogHeader>
172
+ <DialogTitle>Edit profile</DialogTitle>
173
+ <DialogDescription>
174
+ Make changes to your profile here. Click save when you're done.
175
+ </DialogDescription>
176
+ </DialogHeader>
177
+ <DialogBody className="grid gap-4">
178
+ <div className="grid grid-cols-4 items-center gap-4">
179
+ <Label htmlFor="name" className="text-right">
180
+ Name
181
+ </Label>
182
+ <Input id="name" defaultValue="Pedro Duarte" className="col-span-3" />
183
+ </div>
184
+ <div className="grid grid-cols-4 items-center gap-4">
185
+ <Label htmlFor="username" className="text-right">
186
+ Username
187
+ </Label>
188
+ <Input id="username" defaultValue="@peduarte" className="col-span-3" />
189
+ </div>
190
+ </DialogBody>
191
+ <DialogFooter>
192
+ <Button type="submit">
193
+ <Icon symbol="save" />
194
+ Save changes
195
+ </Button>
196
+ </DialogFooter>
197
+ </DialogContent>
198
+ </Dialog>;
199
+ ```
200
+
201
+ ### Compartir Link
202
+
203
+ ```tsx
204
+ import { Icon } from "@adamosuiteservices/ui/icon";
205
+
206
+ <Dialog>
207
+ <DialogTrigger asChild>
208
+ <Button variant="outline">
209
+ <Icon symbol="share" />
210
+ Share
211
+ </Button>
212
+ </DialogTrigger>
213
+ <DialogContent className="sm:max-w-md">
214
+ <DialogHeader>
215
+ <DialogTitle>Share link</DialogTitle>
216
+ <DialogDescription>
217
+ Anyone who has this link will be able to view this.
218
+ </DialogDescription>
219
+ </DialogHeader>
220
+ <DialogBody className="flex items-center space-x-2">
221
+ <div className="grid flex-1 gap-2">
222
+ <Label htmlFor="link" className="sr-only">
223
+ Link
224
+ </Label>
225
+ <Input
226
+ id="link"
227
+ defaultValue="https://ui.shadcn.com/docs/installation"
228
+ readOnly
229
+ />
230
+ </div>
231
+ <Button type="submit" size="sm" className="px-3">
232
+ <Icon symbol="content_copy" />
233
+ </Button>
234
+ </DialogBody>
235
+ <DialogFooter className="sm:justify-start">
236
+ <DialogClose asChild>
237
+ <Button type="button" variant="secondary">
238
+ Close
239
+ </Button>
240
+ </DialogClose>
241
+ </DialogFooter>
242
+ </DialogContent>
243
+ </Dialog>;
244
+ ```
245
+
246
+ ### Confirmación de Eliminación
247
+
248
+ ```tsx
249
+ import { Icon } from "@adamosuiteservices/ui/icon";
250
+ import { Checkbox } from "@adamosuiteservices/ui/checkbox";
251
+
252
+ <Dialog>
253
+ <DialogTrigger asChild>
254
+ <Button variant="destructive">
255
+ <Icon symbol="delete" />
256
+ Delete Account
257
+ </Button>
258
+ </DialogTrigger>
259
+ <DialogContent>
260
+ <DialogHeader>
261
+ <DialogTitle>Delete Account</DialogTitle>
262
+ <DialogDescription>
263
+ This action cannot be undone. This will permanently delete your account
264
+ and remove all of your data from our servers.
265
+ </DialogDescription>
266
+ </DialogHeader>
267
+ <DialogBody>
268
+ <Label className="flex items-center gap-2 text-sm">
269
+ <Checkbox />I understand that this action is irreversible
270
+ </Label>
271
+ </DialogBody>
272
+ <DialogFooter>
273
+ <DialogClose asChild>
274
+ <Button variant="outline">Cancel</Button>
275
+ </DialogClose>
276
+ <Button variant="destructive">
277
+ <Icon symbol="delete" />
278
+ Delete Account
279
+ </Button>
280
+ </DialogFooter>
281
+ </DialogContent>
282
+ </Dialog>;
283
+ ```
284
+
285
+ ### Crear Proyecto
286
+
287
+ ```tsx
288
+ import { Icon } from "@adamosuiteservices/ui/icon";
289
+
290
+ <Dialog>
291
+ <DialogTrigger asChild>
292
+ <Button>
293
+ <Icon symbol="add" />
294
+ New Project
295
+ </Button>
296
+ </DialogTrigger>
297
+ <DialogContent className="sm:max-w-[425px]">
298
+ <DialogHeader>
299
+ <DialogTitle>Create Project</DialogTitle>
300
+ <DialogDescription>
301
+ Create a new project to get started. You can always change these
302
+ settings later.
303
+ </DialogDescription>
304
+ </DialogHeader>
305
+ <DialogBody className="grid gap-4">
306
+ <div className="grid gap-2">
307
+ <Label htmlFor="project-name">Project Name</Label>
308
+ <Input id="project-name" placeholder="My Awesome Project" />
309
+ </div>
310
+ <div className="grid gap-2">
311
+ <Label htmlFor="description">Description</Label>
312
+ <Input id="description" placeholder="Brief description" />
313
+ </div>
314
+ <div className="grid gap-2">
315
+ <Label htmlFor="repository">Repository URL (optional)</Label>
316
+ <Input id="repository" placeholder="https://github.com/username/repo" />
317
+ </div>
318
+ <div className="flex items-center space-x-2">
319
+ <Checkbox id="public" />
320
+ <Label htmlFor="public" className="text-sm">
321
+ Make this project public
322
+ </Label>
323
+ </div>
324
+ </DialogBody>
325
+ <DialogFooter>
326
+ <DialogClose asChild>
327
+ <Button variant="outline">Cancel</Button>
328
+ </DialogClose>
329
+ <Button type="submit">
330
+ <Icon symbol="add" />
331
+ Create Project
332
+ </Button>
333
+ </DialogFooter>
334
+ </DialogContent>
335
+ </Dialog>;
336
+ ```
337
+
338
+ ### Ver Detalles (Read-only)
339
+
340
+ ```tsx
341
+ import { Icon } from "@adamosuiteservices/ui/icon";
342
+
343
+ <Dialog>
344
+ <DialogTrigger asChild>
345
+ <Button variant="outline">
346
+ <Icon symbol="person" />
347
+ View Details
348
+ </Button>
349
+ </DialogTrigger>
350
+ <DialogContent>
351
+ <DialogHeader>
352
+ <DialogTitle>User Details</DialogTitle>
353
+ <DialogDescription>
354
+ View detailed information about this user account.
355
+ </DialogDescription>
356
+ </DialogHeader>
357
+ <DialogBody className="space-y-4">
358
+ <div className="grid grid-cols-3 gap-4">
359
+ <div className="font-medium">Name:</div>
360
+ <div className="col-span-2">John Doe</div>
361
+ </div>
362
+ <div className="grid grid-cols-3 gap-4">
363
+ <div className="font-medium">Email:</div>
364
+ <div className="col-span-2">john.doe@example.com</div>
365
+ </div>
366
+ <div className="grid grid-cols-3 gap-4">
367
+ <div className="font-medium">Role:</div>
368
+ <div className="col-span-2">Administrator</div>
369
+ </div>
370
+ <div className="grid grid-cols-3 gap-4">
371
+ <div className="font-medium">Joined:</div>
372
+ <div className="col-span-2">January 15, 2024</div>
373
+ </div>
374
+ <div className="grid grid-cols-3 gap-4">
375
+ <div className="font-medium">Last Active:</div>
376
+ <div className="col-span-2">2 hours ago</div>
377
+ </div>
378
+ </DialogBody>
379
+ <DialogFooter>
380
+ <DialogClose asChild>
381
+ <Button variant="outline">Close</Button>
382
+ </DialogClose>
383
+ <Button>
384
+ <Icon symbol="person" />
385
+ Edit User
386
+ </Button>
387
+ </DialogFooter>
388
+ </DialogContent>
389
+ </Dialog>;
390
+ ```
391
+
392
+ ### Información Estructurada
393
+
394
+ ```tsx
395
+ import { Icon } from "@adamosuiteservices/ui/icon";
396
+
397
+ <Dialog>
398
+ <DialogTrigger asChild>
399
+ <Button variant="outline">
400
+ <Icon symbol="info" />
401
+ More Info
402
+ </Button>
403
+ </DialogTrigger>
404
+ <DialogContent>
405
+ <DialogHeader>
406
+ <DialogTitle>Important Information</DialogTitle>
407
+ <DialogDescription>
408
+ Please read the following information carefully before proceeding.
409
+ </DialogDescription>
410
+ </DialogHeader>
411
+ <DialogBody className="space-y-4 text-sm">
412
+ <div>
413
+ <h4 className="font-medium mb-2">Data Processing</h4>
414
+ <p className="text-muted-foreground">
415
+ Your data will be processed according to our privacy policy. We ensure
416
+ full compliance with GDPR and other data protection regulations.
417
+ </p>
418
+ </div>
419
+ <div>
420
+ <h4 className="font-medium mb-2">Security</h4>
421
+ <p className="text-muted-foreground">
422
+ All data is encrypted both in transit and at rest using
423
+ industry-standard encryption protocols.
424
+ </p>
425
+ </div>
426
+ <div>
427
+ <h4 className="font-medium mb-2">Support</h4>
428
+ <p className="text-muted-foreground">
429
+ If you have any questions or concerns, please contact our support team
430
+ at support@example.com.
431
+ </p>
432
+ </div>
433
+ </DialogBody>
434
+ <DialogFooter>
435
+ <DialogClose asChild>
436
+ <Button>Got it</Button>
437
+ </DialogClose>
438
+ </DialogFooter>
439
+ </DialogContent>
440
+ </Dialog>;
441
+ ```
442
+
443
+ ### Sin Botón de Cerrar
444
+
445
+ ```tsx
446
+ <Dialog>
447
+ <DialogTrigger asChild>
448
+ <Button variant="outline">Open (No X)</Button>
449
+ </DialogTrigger>
450
+ <DialogContent showCloseButton={false}>
451
+ <DialogHeader>
452
+ <DialogTitle>Custom Close Behavior</DialogTitle>
453
+ <DialogDescription>
454
+ This dialog doesn't have the X button. You must use the action buttons.
455
+ </DialogDescription>
456
+ </DialogHeader>
457
+ <DialogBody>
458
+ <p className="text-sm text-muted-foreground">
459
+ This pattern is useful when you want to force users to make a deliberate
460
+ choice rather than accidentally closing the dialog.
461
+ </p>
462
+ </DialogBody>
463
+ <DialogFooter>
464
+ <DialogClose asChild>
465
+ <Button variant="outline">Cancel</Button>
466
+ </DialogClose>
467
+ <DialogClose asChild>
468
+ <Button>Confirm</Button>
469
+ </DialogClose>
470
+ </DialogFooter>
471
+ </DialogContent>
472
+ </Dialog>
473
+ ```
474
+
475
+ **Uso**: Forzar decisión deliberada, prevenir cierre accidental
476
+
477
+ ### Controlado
478
+
479
+ ```tsx
480
+ import { useState } from "react";
481
+
482
+ function App() {
483
+ const [open, setOpen] = useState(false);
484
+
485
+ return (
486
+ <Dialog open={open} onOpenChange={setOpen}>
487
+ <DialogTrigger>Open Dialog</DialogTrigger>
488
+ <DialogContent>
489
+ <DialogHeader>
490
+ <DialogTitle>Controlled Dialog</DialogTitle>
491
+ </DialogHeader>
492
+ <Button onClick={() => setOpen(false)}>Close Programmatically</Button>
493
+ </DialogContent>
494
+ </Dialog>
495
+ );
496
+ }
497
+ ```
498
+
499
+ ### Con Tema Custom
500
+
501
+ ```tsx
502
+ <DialogContent theme="dark">
503
+ <DialogHeader>
504
+ <DialogTitle>Dark Theme Dialog</DialogTitle>
505
+ <DialogDescription>This dialog uses a custom theme.</DialogDescription>
506
+ </DialogHeader>
507
+ </DialogContent>
508
+ ```
509
+
510
+ **Temas disponibles**: `default`, `dark`, `pay`, `sign`, `risk`, `id`
511
+
512
+ ## Casos de Uso Comunes
513
+
514
+ **Formularios de edición**: Edit profile, settings, preferences
515
+ **Confirmaciones destructivas**: Delete account, remove items, clear data
516
+ **Crear nuevos items**: New project, add user, create record
517
+ **Compartir contenido**: Share links, export data, send invitations
518
+ **Ver detalles**: User info, product details, transaction summary
519
+ **Información**: Disclaimers, terms, help content
520
+
521
+ ## Estados y Data Attributes
522
+
523
+ ### Dialog States
524
+
525
+ - **Open**: `data-[state=open]` → animaciones de entrada
526
+ - **Closed**: `data-[state=closed]` → animaciones de salida
527
+
528
+ ### Overlay Animations
529
+
530
+ - **Opening**: `fade-in-0`
531
+ - **Closing**: `fade-out-0`
532
+
533
+ ### Content Animations
534
+
535
+ - **Opening**: `fade-in-0`, `zoom-in-95`
536
+ - **Closing**: `fade-out-0`, `zoom-out-95`
537
+ - **Duration**: `200ms`
538
+
539
+ ## Navegación por Teclado
540
+
541
+ - ✅ **Escape**: Cierra el dialog (previene con `onEscapeKeyDown`)
542
+ - ✅ **Tab**: Navega entre elementos focusables dentro del dialog
543
+ - ✅ **Shift+Tab**: Navegación inversa
544
+ - ✅ **Enter**: Activa botón/elemento enfocado
545
+
546
+ ## Accesibilidad
547
+
548
+ - ✅ **ARIA**: `role="dialog"`, `aria-labelledby` (title), `aria-describedby` (description)
549
+ - ✅ **Focus trap**: Focus queda dentro del dialog mientras está abierto
550
+ - ✅ **Focus restoration**: Focus vuelve al trigger al cerrar
551
+ - ✅ **Screen readers**: Anuncia título, descripción, y contenido
552
+ - ✅ **Keyboard navigation**: Completamente navegable por teclado
553
+ - ✅ **Close button**: `aria-label="Close"` en botón X
554
+ - ✅ **Modal behavior**: Bloquea interacción con contenido externo
555
+
556
+ ## Notas de Implementación
557
+
558
+ - **Basado en Radix UI**: `@radix-ui/react-dialog`
559
+ - **Portal rendering**: Content se renderiza en `document.body`
560
+ - **Overlay**: `bg-black/50`, `fixed inset-0`, `z-50`
561
+ - **Centrado**: `top-[50%] left-[50%]`, `translate-x-[-50%] translate-y-[-50%]`
562
+ - **Responsive**: `max-w-[calc(100%-2rem)]` en mobile, `sm:max-w-lg` en desktop
563
+ - **Close button**: XIcon automático en esquina superior derecha si `showCloseButton={true}`
564
+ - **Auto-close**: Cierra con Escape, clic fuera, o DialogClose
565
+ - **Focus management**: Primer elemento focusable recibe focus al abrir
566
+ - **Theme support**: Prop `theme` aplica `data-theme` al content
567
+ - **Z-index**: 50 para overlay y content
568
+
569
+ ## Responsive Behavior
570
+
571
+ ### Mobile
572
+
573
+ - `max-w-[calc(100%-2rem)]`: Margen de 1rem a cada lado
574
+ - `text-center`: Header centrado
575
+ - `flex-col-reverse`: Footer con botones apilados (Confirm arriba, Cancel abajo)
576
+
577
+ ### Desktop (sm+)
578
+
579
+ - `sm:max-w-lg`: Ancho máximo 32rem
580
+ - `sm:text-left`: Header alineado a izquierda
581
+ - `sm:flex-row sm:justify-end`: Footer horizontal con botones a la derecha
582
+
583
+ ## Customización de Ancho
584
+
585
+ ```tsx
586
+ {
587
+ /* Small dialog */
588
+ }
589
+ <DialogContent className="sm:max-w-md">...</DialogContent>;
590
+
591
+ {
592
+ /* Medium (default) */
593
+ }
594
+ <DialogContent className="sm:max-w-lg">...</DialogContent>;
595
+
596
+ {
597
+ /* Large */
598
+ }
599
+ <DialogContent className="sm:max-w-2xl">...</DialogContent>;
600
+
601
+ {
602
+ /* Extra large */
603
+ }
604
+ <DialogContent className="sm:max-w-4xl">...</DialogContent>;
605
+
606
+ {
607
+ /* Full width with margin */
608
+ }
609
+ <DialogContent className="sm:max-w-[90vw]">...</DialogContent>;
610
+ ```
611
+
612
+ ## Troubleshooting
613
+
614
+ **Dialog no cierra con Escape**: Verifica que no estés previniendo evento con `onEscapeKeyDown`
615
+ **Dialog no cierra al hacer clic fuera**: Verifica `onPointerDownOutside` o `modal={false}`
616
+ **Focus no vuelve al trigger**: Asegúrate de que el trigger sigue en el DOM
617
+ **Scroll bloqueado después de cerrar**: Radix maneja esto automáticamente, verifica conflictos con CSS
618
+ **Content no centrado**: Evita `transform` CSS en elementos padre que afecten positioning
619
+ **Animaciones no funcionan**: Verifica que `@tailwindcss/animate` esté instalado
620
+ **Botón X no aparece**: Verifica `showCloseButton={true}` (default)
621
+ **Overlay no oscurece**: Z-index conflict, aumenta z-index del overlay
622
+ **Title/Description no anunciados**: Asegúrate de usar componentes DialogTitle y DialogDescription (no divs)
623
+
624
+ ## Referencias
625
+
626
+ - **Radix UI Dialog**: https://www.radix-ui.com/primitives/docs/components/dialog
627
+ - **shadcn/ui Dialog**: https://ui.shadcn.com/docs/components/dialog
628
+ - **ARIA Dialog Pattern**: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/