@adamosuiteservices/ui 1.7.12 → 1.8.13

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 (307) hide show
  1. package/dist/accordion-rounded.cjs +24 -2
  2. package/dist/accordion-rounded.js +46 -8
  3. package/dist/accordion.cjs +20 -1
  4. package/dist/accordion.js +29 -5
  5. package/dist/alert.cjs +26 -1
  6. package/dist/alert.js +33 -8
  7. package/dist/avatar.cjs +7 -1
  8. package/dist/avatar.js +8 -2
  9. package/dist/badge.cjs +83 -1
  10. package/dist/badge.js +106 -24
  11. package/dist/breadcrumb.cjs +8 -1
  12. package/dist/breadcrumb.js +11 -4
  13. package/dist/button-B7ZP4LZN.js +127 -0
  14. package/dist/button-D-qFRXiM.cjs +70 -0
  15. package/dist/button-group.cjs +25 -1
  16. package/dist/button-group.js +33 -9
  17. package/dist/button.cjs +1 -1
  18. package/dist/button.js +1 -1
  19. package/dist/calendar.cjs +74 -1
  20. package/dist/calendar.js +114 -35
  21. package/dist/card.cjs +35 -1
  22. package/dist/card.js +45 -11
  23. package/dist/{checkbox-YWAnswaW.cjs → checkbox-CdnZ8VFJ.cjs} +21 -1
  24. package/dist/{checkbox-Dr487kAg.js → checkbox-DhBcmKze.js} +34 -4
  25. package/dist/checkbox.cjs +1 -1
  26. package/dist/checkbox.js +1 -1
  27. package/dist/combobox.cjs +36 -2
  28. package/dist/combobox.js +302 -253
  29. package/dist/components/icons/account-balance-icon.d.ts +3 -0
  30. package/dist/components/icons/account-icon.d.ts +3 -0
  31. package/dist/components/icons/add-circle-icon.d.ts +3 -0
  32. package/dist/components/icons/alarm-icon.d.ts +3 -0
  33. package/dist/components/icons/archive-icon.d.ts +3 -0
  34. package/dist/components/icons/arrow-back-icon.d.ts +3 -0
  35. package/dist/components/icons/arrow-circle-up-icon.d.ts +3 -0
  36. package/dist/components/icons/arrow-forward-icon.d.ts +3 -0
  37. package/dist/components/icons/arrow-outward-icon.d.ts +3 -0
  38. package/dist/components/icons/article-icon.d.ts +3 -0
  39. package/dist/components/icons/attach-file-icon.d.ts +3 -0
  40. package/dist/components/icons/autorenew-icon.d.ts +3 -0
  41. package/dist/components/icons/bookmark-icon.d.ts +3 -0
  42. package/dist/components/icons/calculate-icon.d.ts +3 -0
  43. package/dist/components/icons/calendar-today-icon.d.ts +3 -0
  44. package/dist/components/icons/call-split-icon.d.ts +3 -0
  45. package/dist/components/icons/cancel-filled-icon.d.ts +3 -0
  46. package/dist/components/icons/cancel-icon.d.ts +3 -0
  47. package/dist/components/icons/check-circle-icon.d.ts +3 -0
  48. package/dist/components/icons/check-icon.d.ts +3 -0
  49. package/dist/components/icons/chevron-back-icon.d.ts +3 -0
  50. package/dist/components/icons/chevron-down-icon.d.ts +3 -0
  51. package/dist/components/icons/chevron-forward-icon.d.ts +3 -0
  52. package/dist/components/icons/chevron-up-icon.d.ts +3 -0
  53. package/dist/components/icons/clarify-icon.d.ts +3 -0
  54. package/dist/components/icons/clock-icon.d.ts +3 -0
  55. package/dist/components/icons/close-icon.d.ts +3 -0
  56. package/dist/components/icons/confirmation-number-icon.d.ts +3 -0
  57. package/dist/components/icons/contacts-icon.d.ts +3 -0
  58. package/dist/components/icons/contract-delete-icon.d.ts +3 -0
  59. package/dist/components/icons/copy-icon.d.ts +3 -0
  60. package/dist/components/icons/do-not-touch-icon.d.ts +3 -0
  61. package/dist/components/icons/download-icon.d.ts +3 -0
  62. package/dist/components/icons/dragger-icon.d.ts +3 -0
  63. package/dist/components/icons/edit-icon.d.ts +3 -0
  64. package/dist/components/icons/edit-square-icon.d.ts +3 -0
  65. package/dist/components/icons/exclamation-icon.d.ts +3 -0
  66. package/dist/components/icons/expand-circle-right-icon.d.ts +3 -0
  67. package/dist/components/icons/feature-search-icon.d.ts +3 -0
  68. package/dist/components/icons/filter-icon.d.ts +3 -0
  69. package/dist/components/icons/folder-icon.d.ts +3 -0
  70. package/dist/components/icons/folder-open-icon.d.ts +3 -0
  71. package/dist/components/icons/format-list-bulleted-icon.d.ts +3 -0
  72. package/dist/components/icons/hamburger-menu-icon.d.ts +3 -0
  73. package/dist/components/icons/help-icon.d.ts +3 -0
  74. package/dist/components/icons/hide-pass-icon.d.ts +3 -0
  75. package/dist/components/icons/home-icon.d.ts +3 -0
  76. package/dist/components/icons/id-card-icon.d.ts +3 -0
  77. package/dist/components/icons/index.d.ts +88 -0
  78. package/dist/components/icons/info-icon.d.ts +3 -0
  79. package/dist/components/icons/kid-star-icon.d.ts +3 -0
  80. package/dist/components/icons/language-icon.d.ts +3 -0
  81. package/dist/components/icons/last-page-icon.d.ts +3 -0
  82. package/dist/components/icons/layers-icon.d.ts +3 -0
  83. package/dist/components/icons/location-icon.d.ts +3 -0
  84. package/dist/components/icons/mail-icon.d.ts +3 -0
  85. package/dist/components/icons/manage-search-icon.d.ts +3 -0
  86. package/dist/components/icons/menu-icon.d.ts +3 -0
  87. package/dist/components/icons/message-icon.d.ts +3 -0
  88. package/dist/components/icons/metrics-icon.d.ts +3 -0
  89. package/dist/components/icons/mic-icon.d.ts +3 -0
  90. package/dist/components/icons/minus-icon.d.ts +3 -0
  91. package/dist/components/icons/mode-comment-icon.d.ts +3 -0
  92. package/dist/components/icons/money-icon.d.ts +3 -0
  93. package/dist/components/icons/monitoring-icon.d.ts +3 -0
  94. package/dist/components/icons/more-icon.d.ts +3 -0
  95. package/dist/components/icons/notifications-icon.d.ts +3 -0
  96. package/dist/components/icons/open-in-new-icon.d.ts +3 -0
  97. package/dist/components/icons/palette-icon.d.ts +3 -0
  98. package/dist/components/icons/password-icon.d.ts +3 -0
  99. package/dist/components/icons/pending-icon.d.ts +3 -0
  100. package/dist/components/icons/person-add-icon.d.ts +3 -0
  101. package/dist/components/icons/person-search-icon.d.ts +3 -0
  102. package/dist/components/icons/photo-icon.d.ts +3 -0
  103. package/dist/components/icons/plus-icon.d.ts +3 -0
  104. package/dist/components/icons/policy-icon.d.ts +3 -0
  105. package/dist/components/icons/publish-icon.d.ts +3 -0
  106. package/dist/components/icons/ready-icon.d.ts +3 -0
  107. package/dist/components/icons/receipt-icon.d.ts +3 -0
  108. package/dist/components/icons/receive-icon.d.ts +3 -0
  109. package/dist/components/icons/refresh-icon.d.ts +3 -0
  110. package/dist/components/icons/search-icon.d.ts +3 -0
  111. package/dist/components/icons/see-icon.d.ts +3 -0
  112. package/dist/components/icons/send-icon.d.ts +3 -0
  113. package/dist/components/icons/settings-icon.d.ts +3 -0
  114. package/dist/components/icons/shield-icon.d.ts +3 -0
  115. package/dist/components/icons/swap-horiz-icon.d.ts +3 -0
  116. package/dist/components/icons/tag-icon.d.ts +3 -0
  117. package/dist/components/icons/trash-icon.d.ts +3 -0
  118. package/dist/components/layout/toaster/toaster.d.ts +1 -1
  119. package/dist/components/layout/toaster/toaster.stories.d.ts +1 -1
  120. package/dist/components/ui/accordion/accordion.d.ts +1 -1
  121. package/dist/components/ui/accordion/accordion.stories.d.ts +1 -1
  122. package/dist/components/ui/accordion-rounded/accordion-rounded.d.ts +1 -1
  123. package/dist/components/ui/accordion-rounded/accordion-rounded.stories.d.ts +1 -1
  124. package/dist/components/ui/alert/alert.stories.d.ts +1 -1
  125. package/dist/components/ui/avatar/avatar.d.ts +1 -1
  126. package/dist/components/ui/avatar/avatar.stories.d.ts +1 -1
  127. package/dist/components/ui/badge/badge.stories.d.ts +1 -1
  128. package/dist/components/ui/breadcrumb/breadcrumb.stories.d.ts +1 -1
  129. package/dist/components/ui/button/button.stories.d.ts +1 -1
  130. package/dist/components/ui/button-group/button-group.d.ts +1 -1
  131. package/dist/components/ui/button-group/button-group.stories.d.ts +1 -1
  132. package/dist/components/ui/calendar/calendar.d.ts +1 -1
  133. package/dist/components/ui/calendar/calendar.stories.d.ts +1 -1
  134. package/dist/components/ui/card/card.stories.d.ts +1 -1
  135. package/dist/components/ui/checkbox/checkbox.d.ts +1 -1
  136. package/dist/components/ui/checkbox/checkbox.stories.d.ts +1 -1
  137. package/dist/components/ui/collapsible/collapsible.stories.d.ts +1 -1
  138. package/dist/components/ui/combobox/combobox.stories.d.ts +1 -1
  139. package/dist/components/ui/command/command.d.ts +1 -1
  140. package/dist/components/ui/context-menu/context-menu.d.ts +1 -1
  141. package/dist/components/ui/context-menu/context-menu.stories.d.ts +1 -1
  142. package/dist/components/ui/dialog/dialog.d.ts +1 -1
  143. package/dist/components/ui/dialog/dialog.stories.d.ts +1 -1
  144. package/dist/components/ui/dropdown-menu/dropdown-menu.d.ts +1 -1
  145. package/dist/components/ui/dropdown-menu/dropdown-menu.stories.d.ts +1 -1
  146. package/dist/components/ui/field/field.d.ts +1 -1
  147. package/dist/components/ui/field/field.stories.d.ts +1 -1
  148. package/dist/components/ui/hover-card/hover-card.d.ts +1 -1
  149. package/dist/components/ui/hover-card/hover-card.stories.d.ts +1 -1
  150. package/dist/components/ui/input/input.stories.d.ts +1 -1
  151. package/dist/components/ui/input-group/Input-group.stories.d.ts +1 -1
  152. package/dist/components/ui/input-group/input-group.d.ts +1 -1
  153. package/dist/components/ui/kbd/kbd.stories.d.ts +1 -1
  154. package/dist/components/ui/label/label.d.ts +1 -1
  155. package/dist/components/ui/label/label.stories.d.ts +1 -1
  156. package/dist/components/ui/pagination/pagination.stories.d.ts +1 -1
  157. package/dist/components/ui/popover/popover.d.ts +1 -1
  158. package/dist/components/ui/popover/popover.stories.d.ts +1 -1
  159. package/dist/components/ui/progress/progress.d.ts +1 -1
  160. package/dist/components/ui/progress/progress.stories.d.ts +1 -1
  161. package/dist/components/ui/radio-group/radio-group.d.ts +1 -1
  162. package/dist/components/ui/radio-group/radio-group.stories.d.ts +1 -1
  163. package/dist/components/ui/scroll-area/scroll-area.d.ts +1 -1
  164. package/dist/components/ui/scroll-area/scroll-area.stories.d.ts +1 -1
  165. package/dist/components/ui/select/select.d.ts +1 -1
  166. package/dist/components/ui/select/select.stories.d.ts +1 -1
  167. package/dist/components/ui/separator/separator.d.ts +1 -1
  168. package/dist/components/ui/separator/separator.stories.d.ts +1 -1
  169. package/dist/components/ui/sheet/sheet.d.ts +1 -1
  170. package/dist/components/ui/sheet/sheet.stories.d.ts +1 -1
  171. package/dist/components/ui/skeleton/skeleton.stories.d.ts +1 -1
  172. package/dist/components/ui/slider/slider.d.ts +1 -1
  173. package/dist/components/ui/slider/slider.stories.d.ts +1 -1
  174. package/dist/components/ui/spinner/spinner.stories.d.ts +1 -1
  175. package/dist/components/ui/switch/switch.d.ts +1 -1
  176. package/dist/components/ui/switch/switch.stories.d.ts +1 -1
  177. package/dist/components/ui/tabs/tabs.d.ts +1 -1
  178. package/dist/components/ui/tabs/tabs.stories.d.ts +1 -1
  179. package/dist/components/ui/tabs-underline/tabs-underline.d.ts +1 -1
  180. package/dist/components/ui/tabs-underline/tabs-underline.stories.d.ts +1 -1
  181. package/dist/components/ui/textarea/textarea.stories.d.ts +1 -1
  182. package/dist/components/ui/toggle/toggle.d.ts +1 -1
  183. package/dist/components/ui/toggle/toggle.stories.d.ts +1 -1
  184. package/dist/components/ui/tooltip/tooltip.d.ts +1 -1
  185. package/dist/components/ui/tooltip/tooltip.stories.d.ts +1 -1
  186. package/dist/context-menu.cjs +79 -1
  187. package/dist/context-menu.js +101 -11
  188. package/dist/custom-layered-styles.css +1 -1
  189. package/dist/dialog.cjs +30 -1
  190. package/dist/dialog.js +35 -6
  191. package/dist/dropdown-menu.cjs +79 -1
  192. package/dist/dropdown-menu.js +101 -11
  193. package/dist/field.cjs +66 -1
  194. package/dist/field.js +91 -26
  195. package/dist/hover-card.cjs +15 -1
  196. package/dist/hover-card.js +15 -1
  197. package/dist/icons.cjs +1 -0
  198. package/dist/icons.js +1507 -0
  199. package/dist/input-BQZUpTEY.js +42 -0
  200. package/dist/input-DSmxdfq5.cjs +21 -0
  201. package/dist/input-group.cjs +76 -1
  202. package/dist/input-group.js +99 -24
  203. package/dist/input.cjs +1 -1
  204. package/dist/input.js +1 -1
  205. package/dist/kbd.cjs +10 -1
  206. package/dist/kbd.js +11 -2
  207. package/dist/{label-CmwGvhy1.js → label-BJ8Yf6Ft.js} +7 -1
  208. package/dist/{label-BjXORCBM.cjs → label-CNGQhi5L.cjs} +7 -1
  209. package/dist/label.cjs +1 -1
  210. package/dist/label.js +1 -1
  211. package/dist/pagination.cjs +13 -1
  212. package/dist/pagination.js +30 -6
  213. package/dist/{popover-FCKBtFo-.cjs → popover-CYbik-H4.cjs} +15 -1
  214. package/dist/{popover-3rIoNCXs.js → popover-DAwH8jUh.js} +15 -1
  215. package/dist/popover.cjs +1 -1
  216. package/dist/popover.js +1 -1
  217. package/dist/radio-group.cjs +14 -1
  218. package/dist/radio-group.js +20 -2
  219. package/dist/select.cjs +68 -1
  220. package/dist/select.js +83 -10
  221. package/dist/{separator-BaZqZZ9R.cjs → separator-Brpax0EI.cjs} +7 -1
  222. package/dist/{separator-DR7lQjv9.js → separator-DVypR3Qf.js} +7 -1
  223. package/dist/separator.cjs +1 -1
  224. package/dist/separator.js +1 -1
  225. package/dist/sheet-CGahUP7F.cjs +41 -0
  226. package/dist/sheet-Q3dBOQG-.js +174 -0
  227. package/dist/sheet.cjs +1 -1
  228. package/dist/sheet.js +1 -1
  229. package/dist/sidebar.cjs +20 -2
  230. package/dist/sidebar.js +58 -26
  231. package/dist/skeleton.cjs +1 -1
  232. package/dist/skeleton.js +1 -1
  233. package/dist/slider.cjs +27 -1
  234. package/dist/slider.js +30 -4
  235. package/dist/space.css +1 -1
  236. package/dist/styles.css +1 -1
  237. package/dist/switch.cjs +18 -1
  238. package/dist/switch.js +19 -2
  239. package/dist/table.cjs +20 -1
  240. package/dist/table.js +26 -7
  241. package/dist/tabs-underline.cjs +21 -1
  242. package/dist/tabs-underline.js +23 -3
  243. package/dist/tabs.cjs +22 -1
  244. package/dist/tabs.js +24 -3
  245. package/dist/textarea-CG7iQcb3.cjs +14 -0
  246. package/dist/textarea-CUPWKl-S.js +32 -0
  247. package/dist/textarea.cjs +1 -1
  248. package/dist/textarea.js +1 -1
  249. package/dist/toaster.cjs +4 -1
  250. package/dist/toaster.js +9 -6
  251. package/dist/toggle.cjs +17 -1
  252. package/dist/toggle.js +25 -9
  253. package/dist/tooltip.cjs +16 -1
  254. package/dist/tooltip.js +22 -2
  255. package/dist/typography.cjs +1 -1
  256. package/dist/typography.js +6 -6
  257. package/docs/AI-GUIDE.md +321 -321
  258. package/docs/components/layout/sidebar.md +404 -404
  259. package/docs/components/layout/toaster.md +436 -436
  260. package/docs/components/ui/accordion-rounded.md +583 -583
  261. package/docs/components/ui/accordion.md +267 -267
  262. package/docs/components/ui/alert.md +671 -671
  263. package/docs/components/ui/avatar.md +588 -588
  264. package/docs/components/ui/badge.md +1024 -1024
  265. package/docs/components/ui/button-group.md +1002 -1002
  266. package/docs/components/ui/button.md +1078 -1078
  267. package/docs/components/ui/calendar.md +1159 -1159
  268. package/docs/components/ui/card.md +1265 -1265
  269. package/docs/components/ui/checkbox.md +292 -292
  270. package/docs/components/ui/collapsible.md +320 -320
  271. package/docs/components/ui/command.md +454 -454
  272. package/docs/components/ui/context-menu.md +540 -540
  273. package/docs/components/ui/dialog.md +628 -628
  274. package/docs/components/ui/dropdown-menu.md +731 -731
  275. package/docs/components/ui/field.md +706 -706
  276. package/docs/components/ui/hover-card.md +446 -446
  277. package/docs/components/ui/input-group.md +509 -509
  278. package/docs/components/ui/input.md +362 -362
  279. package/docs/components/ui/kbd.md +434 -434
  280. package/docs/components/ui/label.md +359 -359
  281. package/docs/components/ui/pagination.md +650 -650
  282. package/docs/components/ui/popover.md +536 -536
  283. package/docs/components/ui/progress.md +182 -182
  284. package/docs/components/ui/radio-group.md +311 -311
  285. package/docs/components/ui/select.md +352 -352
  286. package/docs/components/ui/separator.md +214 -214
  287. package/docs/components/ui/sheet.md +142 -142
  288. package/docs/components/ui/skeleton.md +140 -140
  289. package/docs/components/ui/slider.md +341 -341
  290. package/docs/components/ui/spinner.md +170 -170
  291. package/docs/components/ui/switch.md +402 -402
  292. package/docs/components/ui/table.md +183 -183
  293. package/docs/components/ui/tabs-underline.md +106 -106
  294. package/docs/components/ui/tabs.md +122 -122
  295. package/docs/components/ui/textarea.md +243 -243
  296. package/docs/components/ui/toggle.md +243 -243
  297. package/docs/components/ui/tooltip.md +320 -320
  298. package/docs/components/ui/typography.md +191 -191
  299. package/package.json +7 -1
  300. package/dist/button-2GdKenQI.js +0 -58
  301. package/dist/button-DEQVHMrX.cjs +0 -1
  302. package/dist/input-BF73maXg.cjs +0 -1
  303. package/dist/input-C04hsVXE.js +0 -22
  304. package/dist/sheet-B-9YHdR5.js +0 -128
  305. package/dist/sheet-CU-sFSaJ.cjs +0 -1
  306. package/dist/textarea-3ZdbFRDN.cjs +0 -1
  307. package/dist/textarea-BZbcAAAu.js +0 -19
@@ -1,536 +1,536 @@
1
- # Popover
2
-
3
- Contenido flotante anclado a un trigger, basado en Radix UI. Ideal para forms compactos, settings, información adicional o acciones contextuales.
4
-
5
- ## Descripción
6
-
7
- El componente `Popover` muestra contenido flotante anclado a un elemento trigger.
8
-
9
- ## Importación
10
-
11
- ```typescript
12
- import {
13
- Popover,
14
- PopoverContent,
15
- PopoverTrigger,
16
- } from "@adamosuiteservices/ui/popover";
17
- ```
18
-
19
- ## Anatomía
20
-
21
- ```tsx
22
- <Popover>
23
- <PopoverTrigger>Open</PopoverTrigger>
24
- <PopoverContent>Place content for the popover here.</PopoverContent>
25
- </Popover>
26
- ```
27
-
28
- **Componentes**: 4 (Popover, PopoverTrigger, PopoverContent, PopoverAnchor)
29
-
30
- ## Props Principales
31
-
32
- ### Popover (Root)
33
-
34
- | Prop | Tipo | Default | Descripción |
35
- | -------------- | ------------------------- | ------- | --------------------------------------- |
36
- | `open` | `boolean` | - | Estado controlado |
37
- | `defaultOpen` | `boolean` | `false` | Estado inicial no controlado |
38
- | `onOpenChange` | `(open: boolean) => void` | - | Callback cuando cambia estado |
39
- | `modal` | `boolean` | `false` | Si es modal (bloquea interacción fuera) |
40
-
41
- ### PopoverTrigger
42
-
43
- | Prop | Tipo | Descripción |
44
- | ----------- | --------- | -------------------------------------------------- |
45
- | `asChild` | `boolean` | Pasa props al child en lugar de renderizar wrapper |
46
- | `className` | `string` | Clases CSS adicionales |
47
-
48
- ### PopoverContent
49
-
50
- | Prop | Tipo | Default | Descripción |
51
- | ------------- | ---------------------------------------- | ---------- | -------------------------------- |
52
- | `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Lado donde aparece |
53
- | `align` | `"start" \| "center" \| "end"` | `"center"` | Alineamiento horizontal/vertical |
54
- | `sideOffset` | `number` | `4` | Distancia desde trigger (px) |
55
- | `alignOffset` | `number` | `0` | Offset del alineamiento |
56
- | `className` | `string` | - | Clases CSS adicionales |
57
-
58
- **Estilos default**: `w-72`, `p-4`, `rounded-md`, `border`, `shadow-md`, `z-50`
59
-
60
- ### PopoverAnchor
61
-
62
- | Prop | Tipo | Descripción |
63
- | ----------- | --------- | ---------------------- |
64
- | `asChild` | `boolean` | Pasa props al child |
65
- | `className` | `string` | Clases CSS adicionales |
66
-
67
- **Uso**: Ancla popover a elemento diferente del trigger
68
-
69
- ## Patrones de Uso
70
-
71
- ### Básico
72
-
73
- ```tsx
74
- <Popover>
75
- <PopoverTrigger asChild>
76
- <Button variant="outline">Open popover</Button>
77
- </PopoverTrigger>
78
- <PopoverContent className="w-80">
79
- <div className="grid gap-4">
80
- <div className="space-y-2">
81
- <h4 className="font-medium leading-none">Dimensions</h4>
82
- <p className="text-sm text-muted-foreground">
83
- Set the dimensions for the layer.
84
- </p>
85
- </div>
86
- <div className="grid gap-2">
87
- <div className="grid grid-cols-3 items-center gap-4">
88
- <Label htmlFor="width">Width</Label>
89
- <Input id="width" defaultValue="100%" className="col-span-2 h-8" />
90
- </div>
91
- <div className="grid grid-cols-3 items-center gap-4">
92
- <Label htmlFor="height">Height</Label>
93
- <Input id="height" defaultValue="25px" className="col-span-2 h-8" />
94
- </div>
95
- </div>
96
- </div>
97
- </PopoverContent>
98
- </Popover>
99
- ```
100
-
101
- ### Simple
102
-
103
- ```tsx
104
- <Popover>
105
- <PopoverTrigger asChild>
106
- <Button variant="outline">Click me</Button>
107
- </PopoverTrigger>
108
- <PopoverContent>
109
- <p>This is a simple popover with just text content.</p>
110
- </PopoverContent>
111
- </Popover>
112
- ```
113
-
114
- ### Con User Profile
115
-
116
- ```tsx
117
- import {
118
- Avatar,
119
- AvatarImage,
120
- AvatarFallback,
121
- } from "@adamosuiteservices/ui/avatar";
122
- import { Calendar } from "lucide-react";
123
-
124
- <Popover>
125
- <PopoverTrigger asChild>
126
- <Button variant="ghost" className="h-auto p-2">
127
- <Avatar className="h-8 w-8">
128
- <AvatarImage src="https://github.com/shadcn.png" />
129
- <AvatarFallback>SC</AvatarFallback>
130
- </Avatar>
131
- </Button>
132
- </PopoverTrigger>
133
- <PopoverContent className="w-80">
134
- <div className="flex gap-4">
135
- <Avatar>
136
- <AvatarImage src="https://github.com/shadcn.png" />
137
- <AvatarFallback>SC</AvatarFallback>
138
- </Avatar>
139
- <div className="space-y-1">
140
- <h4 className="text-sm font-semibold">@shadcn</h4>
141
- <p className="text-sm">
142
- The React Framework – created and maintained by @vercel.
143
- </p>
144
- <div className="flex items-center pt-2">
145
- <Calendar className="mr-2 h-4 w-4 opacity-70" />
146
- <span className="text-xs text-muted-foreground">
147
- Joined December 2021
148
- </span>
149
- </div>
150
- </div>
151
- </div>
152
- </PopoverContent>
153
- </Popover>;
154
- ```
155
-
156
- ### Con Settings
157
-
158
- ```tsx
159
- import { Switch } from "@adamosuiteservices/ui/switch";
160
- import { Separator } from "@adamosuiteservices/ui/separator";
161
- import { Settings } from "lucide-react";
162
-
163
- <Popover>
164
- <PopoverTrigger asChild>
165
- <Button variant="outline" size="icon">
166
- <Settings className="h-4 w-4" />
167
- </Button>
168
- </PopoverTrigger>
169
- <PopoverContent className="w-80">
170
- <div className="grid gap-4">
171
- <div className="space-y-2">
172
- <h4 className="font-medium leading-none">Settings</h4>
173
- <p className="text-sm text-muted-foreground">
174
- Configure your preferences
175
- </p>
176
- </div>
177
- <div className="grid gap-2">
178
- <div className="flex items-center justify-between">
179
- <Label htmlFor="notifications">Push notifications</Label>
180
- <Switch id="notifications" />
181
- </div>
182
- <div className="flex items-center justify-between">
183
- <Label htmlFor="emails">Email updates</Label>
184
- <Switch id="emails" defaultChecked />
185
- </div>
186
- </div>
187
- <Separator />
188
- <div className="flex justify-between">
189
- <Button variant="outline" size="sm">
190
- Cancel
191
- </Button>
192
- <Button size="sm">Save changes</Button>
193
- </div>
194
- </div>
195
- </PopoverContent>
196
- </Popover>;
197
- ```
198
-
199
- ### Con Calendar
200
-
201
- ```tsx
202
- import { useState } from "react";
203
- import { Calendar } from "@adamosuiteservices/ui/calendar";
204
- import { Calendar as CalendarIcon } from "lucide-react";
205
-
206
- function App() {
207
- const [date, setDate] = useState<Date | undefined>(new Date());
208
-
209
- return (
210
- <Popover>
211
- <PopoverTrigger asChild>
212
- <Button
213
- variant="outline"
214
- className={cn(
215
- "w-[240px] justify-start text-left font-normal",
216
- !date && "text-muted-foreground"
217
- )}
218
- >
219
- <CalendarIcon className="mr-2 h-4 w-4" />
220
- {date ? date.toLocaleDateString() : "Pick a date"}
221
- </Button>
222
- </PopoverTrigger>
223
- <PopoverContent className="w-auto p-0" align="start">
224
- <Calendar
225
- mode="single"
226
- selected={date}
227
- onSelect={setDate}
228
- initialFocus
229
- />
230
- </PopoverContent>
231
- </Popover>
232
- );
233
- }
234
- ```
235
-
236
- ### Con Counter
237
-
238
- ```tsx
239
- import { useState } from "react";
240
- import { Plus, Minus } from "lucide-react";
241
-
242
- function App() {
243
- const [count, setCount] = useState(0);
244
-
245
- return (
246
- <Popover>
247
- <PopoverTrigger asChild>
248
- <Button variant="outline">Counter: {count}</Button>
249
- </PopoverTrigger>
250
- <PopoverContent className="w-64">
251
- <div className="grid gap-4">
252
- <div className="space-y-2">
253
- <h4 className="font-medium leading-none">Counter Control</h4>
254
- <p className="text-sm text-muted-foreground">
255
- Adjust the counter value
256
- </p>
257
- </div>
258
- <div className="flex items-center justify-center space-x-2">
259
- <Button
260
- variant="outline"
261
- size="icon"
262
- onClick={() => setCount(Math.max(0, count - 1))}
263
- disabled={count === 0}
264
- >
265
- <Minus className="h-4 w-4" />
266
- </Button>
267
- <div className="flex items-center justify-center w-16 h-10 border rounded">
268
- {count}
269
- </div>
270
- <Button
271
- variant="outline"
272
- size="icon"
273
- onClick={() => setCount(count + 1)}
274
- >
275
- <Plus className="h-4 w-4" />
276
- </Button>
277
- </div>
278
- <div className="flex gap-2">
279
- <Button variant="outline" size="sm" onClick={() => setCount(0)}>
280
- Reset
281
- </Button>
282
- <Button size="sm" onClick={() => setCount(10)}>
283
- Set to 10
284
- </Button>
285
- </div>
286
- </div>
287
- </PopoverContent>
288
- </Popover>
289
- );
290
- }
291
- ```
292
-
293
- ### Con Info Icon
294
-
295
- ```tsx
296
- import { Info, AlertCircle } from "lucide-react";
297
-
298
- <div className="flex items-center gap-4">
299
- <span>Complex Feature</span>
300
- <Popover>
301
- <PopoverTrigger asChild>
302
- <Button variant="ghost" size="icon" className="h-5 w-5">
303
- <Info className="h-3 w-3" />
304
- </Button>
305
- </PopoverTrigger>
306
- <PopoverContent className="w-80">
307
- <div className="space-y-3">
308
- <div className="flex items-center gap-2">
309
- <AlertCircle className="h-4 w-4 text-blue-500" />
310
- <h4 className="font-medium">About this feature</h4>
311
- </div>
312
- <p className="text-sm text-muted-foreground">
313
- This is a complex feature that requires additional explanation.
314
- </p>
315
- <div className="space-y-2">
316
- <h5 className="text-sm font-medium">Key benefits:</h5>
317
- <ul className="text-sm space-y-1 text-muted-foreground">
318
- <li>• Improved performance</li>
319
- <li>• Better user experience</li>
320
- <li>• Advanced customization</li>
321
- </ul>
322
- </div>
323
- </div>
324
- </PopoverContent>
325
- </Popover>
326
- </div>;
327
- ```
328
-
329
- ### Con Notifications
330
-
331
- ```tsx
332
- import { Mail } from "lucide-react";
333
- import { Badge } from "@adamosuiteservices/ui/badge";
334
- import { Separator } from "@adamosuiteservices/ui/separator";
335
-
336
- <Popover>
337
- <PopoverTrigger asChild>
338
- <Button variant="outline" size="icon" className="relative">
339
- <Mail className="h-4 w-4" />
340
- <Badge
341
- className="absolute -top-2 -right-2 h-5 w-5 p-0 flex items-center justify-center"
342
- variant="destructive"
343
- >
344
- 3
345
- </Badge>
346
- </Button>
347
- </PopoverTrigger>
348
- <PopoverContent className="w-80">
349
- <div className="space-y-3">
350
- <div className="flex items-center justify-between">
351
- <h4 className="font-medium">Notifications</h4>
352
- <Button variant="ghost" size="sm">
353
- Mark all read
354
- </Button>
355
- </div>
356
- <div className="space-y-2">
357
- <div className="flex items-start gap-3 p-2 rounded hover:bg-muted bg-muted/50">
358
- <div className="flex-1">
359
- <p className="text-sm font-medium">New message</p>
360
- <p className="text-xs text-muted-foreground">2 min ago</p>
361
- </div>
362
- <div className="h-2 w-2 bg-blue-500 rounded-full mt-1" />
363
- </div>
364
- </div>
365
- <Separator />
366
- <Button variant="outline" size="sm" className="w-full">
367
- View all notifications
368
- </Button>
369
- </div>
370
- </PopoverContent>
371
- </Popover>;
372
- ```
373
-
374
- ### Posicionamiento Custom
375
-
376
- ```tsx
377
- {
378
- /* Top */
379
- }
380
- <Popover>
381
- <PopoverTrigger asChild>
382
- <Button variant="outline">Top</Button>
383
- </PopoverTrigger>
384
- <PopoverContent side="top">
385
- <p>This popover appears on top</p>
386
- </PopoverContent>
387
- </Popover>;
388
-
389
- {
390
- /* Right */
391
- }
392
- <Popover>
393
- <PopoverTrigger asChild>
394
- <Button variant="outline">Right</Button>
395
- </PopoverTrigger>
396
- <PopoverContent side="right">
397
- <p>This popover appears on the right</p>
398
- </PopoverContent>
399
- </Popover>;
400
-
401
- {
402
- /* Start aligned */
403
- }
404
- <Popover>
405
- <PopoverTrigger asChild>
406
- <Button variant="outline">Start aligned</Button>
407
- </PopoverTrigger>
408
- <PopoverContent align="start">
409
- <p>This popover is aligned to the start</p>
410
- </PopoverContent>
411
- </Popover>;
412
- ```
413
-
414
- ### Con Anchor
415
-
416
- ```tsx
417
- <div className="space-y-4">
418
- <p>
419
- This is some text with an{" "}
420
- <Popover>
421
- <PopoverAnchor asChild>
422
- <span className="underline cursor-pointer">anchored element</span>
423
- </PopoverAnchor>
424
- <PopoverTrigger asChild>
425
- <Button variant="outline" className="ml-2">
426
- Show info
427
- </Button>
428
- </PopoverTrigger>
429
- <PopoverContent>
430
- <p>This popover is anchored to the underlined text above!</p>
431
- </PopoverContent>
432
- </Popover>
433
- </p>
434
- </div>
435
- ```
436
-
437
- ### Controlado
438
-
439
- ```tsx
440
- import { useState } from "react";
441
-
442
- function App() {
443
- const [open, setOpen] = useState(false);
444
-
445
- return (
446
- <Popover open={open} onOpenChange={setOpen}>
447
- <PopoverTrigger asChild>
448
- <Button variant="outline">Toggle</Button>
449
- </PopoverTrigger>
450
- <PopoverContent>
451
- <div className="space-y-2">
452
- <p>Controlled popover content</p>
453
- <Button onClick={() => setOpen(false)}>Close</Button>
454
- </div>
455
- </PopoverContent>
456
- </Popover>
457
- );
458
- }
459
- ```
460
-
461
- ## Casos de Uso Comunes
462
-
463
- **Date pickers**: Mostrar calendar en popover
464
- **Settings**: Controles compactos de configuración
465
- **User profiles**: Preview de perfiles al hover/click
466
- **Notifications**: Lista de notificaciones
467
- **Quick actions**: Acciones contextuales sin modal
468
- **Info tooltips**: Información rica vs tooltip simple
469
- **Forms**: Formularios compactos inline
470
-
471
- ## Estados y Data Attributes
472
-
473
- ### PopoverContent States
474
-
475
- - **Open**: `data-[state=open]` → `animate-in`, `fade-in-0`, `zoom-in-95`
476
- - **Closed**: `data-[state=closed]` → `animate-out`, `fade-out-0`, `zoom-out-95`
477
-
478
- ### Side Animations
479
-
480
- - **Top**: `data-[side=top]` → `slide-in-from-bottom-2`
481
- - **Right**: `data-[side=right]` → `slide-in-from-left-2`
482
- - **Bottom**: `data-[side=bottom]` → `slide-in-from-top-2`
483
- - **Left**: `data-[side=left]` → `slide-in-from-right-2`
484
-
485
- ## Interacción
486
-
487
- - ✅ **Click to open**: Click en trigger abre popover
488
- - ✅ **Click outside**: Click fuera cierra popover (si no es modal)
489
- - ✅ **Escape**: Presionar Esc cierra popover
490
- - ✅ **Focus trap**: Si `modal=true`, foco queda atrapado dentro
491
- - ✅ **Keyboard**: Tab navega entre elementos internos
492
-
493
- ## Accesibilidad
494
-
495
- - ✅ **ARIA**: `role="dialog"`, `aria-labelledby`, `aria-describedby` según contenido
496
- - ✅ **Focus management**: Focus automático al abrir
497
- - ✅ **Keyboard**: Esc para cerrar, Tab para navegar
498
- - ✅ **Portal**: Renderiza en `document.body` para evitar problemas de z-index
499
- - ✅ **Modal mode**: `modal=true` para bloquear interacción fuera del popover
500
-
501
- ## Notas de Implementación
502
-
503
- - **Radix UI**: Basado en `@radix-ui/react-popover`
504
- - **Portal rendering**: Content se renderiza en `document.body`
505
- - **Collision detection**: Auto-ajusta posición si sale del viewport
506
- - **Transform origin**: CSS variables de Radix para animaciones
507
- - **Default width**: `w-72` (288px)
508
- - **Default padding**: `p-4`
509
- - **Z-index**: 50 para aparecer sobre contenido
510
- - **Modal**: Por defecto `modal=false` (permite interacción fuera)
511
-
512
- ## Diferencias con Dialog y HoverCard
513
-
514
- | Aspecto | Popover | Dialog | HoverCard |
515
- | ---------------- | ----------------- | --------------------- | --------------- |
516
- | **Trigger** | Click | Click | Hover |
517
- | **Modal** | Opcional | Siempre | No |
518
- | **Backdrop** | Opcional | Sí | No |
519
- | **Contenido** | Compacto | Extenso | Preview |
520
- | **Persistencia** | Hasta click fuera | Hasta close explícito | Hasta hover out |
521
-
522
- ## Troubleshooting
523
-
524
- **No aparece**: Verifica que PopoverContent esté dentro de Popover root
525
- **Posición incorrecta**: Ajusta `side`, `align`, `sideOffset` y `alignOffset`
526
- **Contenido cortado**: Verifica que no haya `overflow: hidden` en containers
527
- **No cierra**: Si `modal=true`, solo cierra con Esc o close explícito
528
- **Focus no funciona**: Content debe tener elementos focuseables
529
- **Backdrop no se ve**: Popover no tiene backdrop por defecto, usa `modal=true` y customiza
530
- **Z-index issues**: Content usa portal, debe aparecer sobre todo
531
- **Anchor no funciona**: PopoverAnchor debe estar dentro de Popover root
532
-
533
- ## Referencias
534
-
535
- - **Radix UI Popover**: <https://www.radix-ui.com/primitives/docs/components/popover>
536
- - **shadcn/ui Popover**: <https://ui.shadcn.com/docs/components/popover>
1
+ # Popover
2
+
3
+ Contenido flotante anclado a un trigger, basado en Radix UI. Ideal para forms compactos, settings, información adicional o acciones contextuales.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Popover` muestra contenido flotante anclado a un elemento trigger.
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import {
13
+ Popover,
14
+ PopoverContent,
15
+ PopoverTrigger,
16
+ } from "@adamosuiteservices/ui/popover";
17
+ ```
18
+
19
+ ## Anatomía
20
+
21
+ ```tsx
22
+ <Popover>
23
+ <PopoverTrigger>Open</PopoverTrigger>
24
+ <PopoverContent>Place content for the popover here.</PopoverContent>
25
+ </Popover>
26
+ ```
27
+
28
+ **Componentes**: 4 (Popover, PopoverTrigger, PopoverContent, PopoverAnchor)
29
+
30
+ ## Props Principales
31
+
32
+ ### Popover (Root)
33
+
34
+ | Prop | Tipo | Default | Descripción |
35
+ | -------------- | ------------------------- | ------- | --------------------------------------- |
36
+ | `open` | `boolean` | - | Estado controlado |
37
+ | `defaultOpen` | `boolean` | `false` | Estado inicial no controlado |
38
+ | `onOpenChange` | `(open: boolean) => void` | - | Callback cuando cambia estado |
39
+ | `modal` | `boolean` | `false` | Si es modal (bloquea interacción fuera) |
40
+
41
+ ### PopoverTrigger
42
+
43
+ | Prop | Tipo | Descripción |
44
+ | ----------- | --------- | -------------------------------------------------- |
45
+ | `asChild` | `boolean` | Pasa props al child en lugar de renderizar wrapper |
46
+ | `className` | `string` | Clases CSS adicionales |
47
+
48
+ ### PopoverContent
49
+
50
+ | Prop | Tipo | Default | Descripción |
51
+ | ------------- | ---------------------------------------- | ---------- | -------------------------------- |
52
+ | `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Lado donde aparece |
53
+ | `align` | `"start" \| "center" \| "end"` | `"center"` | Alineamiento horizontal/vertical |
54
+ | `sideOffset` | `number` | `4` | Distancia desde trigger (px) |
55
+ | `alignOffset` | `number` | `0` | Offset del alineamiento |
56
+ | `className` | `string` | - | Clases CSS adicionales |
57
+
58
+ **Estilos default**: `w-72`, `p-4`, `rounded-md`, `border`, `shadow-md`, `z-50`
59
+
60
+ ### PopoverAnchor
61
+
62
+ | Prop | Tipo | Descripción |
63
+ | ----------- | --------- | ---------------------- |
64
+ | `asChild` | `boolean` | Pasa props al child |
65
+ | `className` | `string` | Clases CSS adicionales |
66
+
67
+ **Uso**: Ancla popover a elemento diferente del trigger
68
+
69
+ ## Patrones de Uso
70
+
71
+ ### Básico
72
+
73
+ ```tsx
74
+ <Popover>
75
+ <PopoverTrigger asChild>
76
+ <Button variant="outline">Open popover</Button>
77
+ </PopoverTrigger>
78
+ <PopoverContent className="w-80">
79
+ <div className="grid gap-4">
80
+ <div className="space-y-2">
81
+ <h4 className="font-medium leading-none">Dimensions</h4>
82
+ <p className="text-sm text-muted-foreground">
83
+ Set the dimensions for the layer.
84
+ </p>
85
+ </div>
86
+ <div className="grid gap-2">
87
+ <div className="grid grid-cols-3 items-center gap-4">
88
+ <Label htmlFor="width">Width</Label>
89
+ <Input id="width" defaultValue="100%" className="col-span-2 h-8" />
90
+ </div>
91
+ <div className="grid grid-cols-3 items-center gap-4">
92
+ <Label htmlFor="height">Height</Label>
93
+ <Input id="height" defaultValue="25px" className="col-span-2 h-8" />
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </PopoverContent>
98
+ </Popover>
99
+ ```
100
+
101
+ ### Simple
102
+
103
+ ```tsx
104
+ <Popover>
105
+ <PopoverTrigger asChild>
106
+ <Button variant="outline">Click me</Button>
107
+ </PopoverTrigger>
108
+ <PopoverContent>
109
+ <p>This is a simple popover with just text content.</p>
110
+ </PopoverContent>
111
+ </Popover>
112
+ ```
113
+
114
+ ### Con User Profile
115
+
116
+ ```tsx
117
+ import {
118
+ Avatar,
119
+ AvatarImage,
120
+ AvatarFallback,
121
+ } from "@adamosuiteservices/ui/avatar";
122
+ import { Calendar } from "lucide-react";
123
+
124
+ <Popover>
125
+ <PopoverTrigger asChild>
126
+ <Button variant="ghost" className="h-auto p-2">
127
+ <Avatar className="h-8 w-8">
128
+ <AvatarImage src="https://github.com/shadcn.png" />
129
+ <AvatarFallback>SC</AvatarFallback>
130
+ </Avatar>
131
+ </Button>
132
+ </PopoverTrigger>
133
+ <PopoverContent className="w-80">
134
+ <div className="flex gap-4">
135
+ <Avatar>
136
+ <AvatarImage src="https://github.com/shadcn.png" />
137
+ <AvatarFallback>SC</AvatarFallback>
138
+ </Avatar>
139
+ <div className="space-y-1">
140
+ <h4 className="text-sm font-semibold">@shadcn</h4>
141
+ <p className="text-sm">
142
+ The React Framework – created and maintained by @vercel.
143
+ </p>
144
+ <div className="flex items-center pt-2">
145
+ <Calendar className="mr-2 h-4 w-4 opacity-70" />
146
+ <span className="text-xs text-muted-foreground">
147
+ Joined December 2021
148
+ </span>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ </PopoverContent>
153
+ </Popover>;
154
+ ```
155
+
156
+ ### Con Settings
157
+
158
+ ```tsx
159
+ import { Switch } from "@adamosuiteservices/ui/switch";
160
+ import { Separator } from "@adamosuiteservices/ui/separator";
161
+ import { Settings } from "lucide-react";
162
+
163
+ <Popover>
164
+ <PopoverTrigger asChild>
165
+ <Button variant="outline" size="icon">
166
+ <Settings className="h-4 w-4" />
167
+ </Button>
168
+ </PopoverTrigger>
169
+ <PopoverContent className="w-80">
170
+ <div className="grid gap-4">
171
+ <div className="space-y-2">
172
+ <h4 className="font-medium leading-none">Settings</h4>
173
+ <p className="text-sm text-muted-foreground">
174
+ Configure your preferences
175
+ </p>
176
+ </div>
177
+ <div className="grid gap-2">
178
+ <div className="flex items-center justify-between">
179
+ <Label htmlFor="notifications">Push notifications</Label>
180
+ <Switch id="notifications" />
181
+ </div>
182
+ <div className="flex items-center justify-between">
183
+ <Label htmlFor="emails">Email updates</Label>
184
+ <Switch id="emails" defaultChecked />
185
+ </div>
186
+ </div>
187
+ <Separator />
188
+ <div className="flex justify-between">
189
+ <Button variant="outline" size="sm">
190
+ Cancel
191
+ </Button>
192
+ <Button size="sm">Save changes</Button>
193
+ </div>
194
+ </div>
195
+ </PopoverContent>
196
+ </Popover>;
197
+ ```
198
+
199
+ ### Con Calendar
200
+
201
+ ```tsx
202
+ import { useState } from "react";
203
+ import { Calendar } from "@adamosuiteservices/ui/calendar";
204
+ import { Calendar as CalendarIcon } from "lucide-react";
205
+
206
+ function App() {
207
+ const [date, setDate] = useState<Date | undefined>(new Date());
208
+
209
+ return (
210
+ <Popover>
211
+ <PopoverTrigger asChild>
212
+ <Button
213
+ variant="outline"
214
+ className={cn(
215
+ "w-[240px] justify-start text-left font-normal",
216
+ !date && "text-muted-foreground"
217
+ )}
218
+ >
219
+ <CalendarIcon className="mr-2 h-4 w-4" />
220
+ {date ? date.toLocaleDateString() : "Pick a date"}
221
+ </Button>
222
+ </PopoverTrigger>
223
+ <PopoverContent className="w-auto p-0" align="start">
224
+ <Calendar
225
+ mode="single"
226
+ selected={date}
227
+ onSelect={setDate}
228
+ initialFocus
229
+ />
230
+ </PopoverContent>
231
+ </Popover>
232
+ );
233
+ }
234
+ ```
235
+
236
+ ### Con Counter
237
+
238
+ ```tsx
239
+ import { useState } from "react";
240
+ import { Plus, Minus } from "lucide-react";
241
+
242
+ function App() {
243
+ const [count, setCount] = useState(0);
244
+
245
+ return (
246
+ <Popover>
247
+ <PopoverTrigger asChild>
248
+ <Button variant="outline">Counter: {count}</Button>
249
+ </PopoverTrigger>
250
+ <PopoverContent className="w-64">
251
+ <div className="grid gap-4">
252
+ <div className="space-y-2">
253
+ <h4 className="font-medium leading-none">Counter Control</h4>
254
+ <p className="text-sm text-muted-foreground">
255
+ Adjust the counter value
256
+ </p>
257
+ </div>
258
+ <div className="flex items-center justify-center space-x-2">
259
+ <Button
260
+ variant="outline"
261
+ size="icon"
262
+ onClick={() => setCount(Math.max(0, count - 1))}
263
+ disabled={count === 0}
264
+ >
265
+ <Minus className="h-4 w-4" />
266
+ </Button>
267
+ <div className="flex items-center justify-center w-16 h-10 border rounded">
268
+ {count}
269
+ </div>
270
+ <Button
271
+ variant="outline"
272
+ size="icon"
273
+ onClick={() => setCount(count + 1)}
274
+ >
275
+ <Plus className="h-4 w-4" />
276
+ </Button>
277
+ </div>
278
+ <div className="flex gap-2">
279
+ <Button variant="outline" size="sm" onClick={() => setCount(0)}>
280
+ Reset
281
+ </Button>
282
+ <Button size="sm" onClick={() => setCount(10)}>
283
+ Set to 10
284
+ </Button>
285
+ </div>
286
+ </div>
287
+ </PopoverContent>
288
+ </Popover>
289
+ );
290
+ }
291
+ ```
292
+
293
+ ### Con Info Icon
294
+
295
+ ```tsx
296
+ import { Info, AlertCircle } from "lucide-react";
297
+
298
+ <div className="flex items-center gap-4">
299
+ <span>Complex Feature</span>
300
+ <Popover>
301
+ <PopoverTrigger asChild>
302
+ <Button variant="ghost" size="icon" className="h-5 w-5">
303
+ <Info className="h-3 w-3" />
304
+ </Button>
305
+ </PopoverTrigger>
306
+ <PopoverContent className="w-80">
307
+ <div className="space-y-3">
308
+ <div className="flex items-center gap-2">
309
+ <AlertCircle className="h-4 w-4 text-blue-500" />
310
+ <h4 className="font-medium">About this feature</h4>
311
+ </div>
312
+ <p className="text-sm text-muted-foreground">
313
+ This is a complex feature that requires additional explanation.
314
+ </p>
315
+ <div className="space-y-2">
316
+ <h5 className="text-sm font-medium">Key benefits:</h5>
317
+ <ul className="text-sm space-y-1 text-muted-foreground">
318
+ <li>• Improved performance</li>
319
+ <li>• Better user experience</li>
320
+ <li>• Advanced customization</li>
321
+ </ul>
322
+ </div>
323
+ </div>
324
+ </PopoverContent>
325
+ </Popover>
326
+ </div>;
327
+ ```
328
+
329
+ ### Con Notifications
330
+
331
+ ```tsx
332
+ import { Mail } from "lucide-react";
333
+ import { Badge } from "@adamosuiteservices/ui/badge";
334
+ import { Separator } from "@adamosuiteservices/ui/separator";
335
+
336
+ <Popover>
337
+ <PopoverTrigger asChild>
338
+ <Button variant="outline" size="icon" className="relative">
339
+ <Mail className="h-4 w-4" />
340
+ <Badge
341
+ className="absolute -top-2 -right-2 h-5 w-5 p-0 flex items-center justify-center"
342
+ variant="destructive"
343
+ >
344
+ 3
345
+ </Badge>
346
+ </Button>
347
+ </PopoverTrigger>
348
+ <PopoverContent className="w-80">
349
+ <div className="space-y-3">
350
+ <div className="flex items-center justify-between">
351
+ <h4 className="font-medium">Notifications</h4>
352
+ <Button variant="ghost" size="sm">
353
+ Mark all read
354
+ </Button>
355
+ </div>
356
+ <div className="space-y-2">
357
+ <div className="flex items-start gap-3 p-2 rounded hover:bg-muted bg-muted/50">
358
+ <div className="flex-1">
359
+ <p className="text-sm font-medium">New message</p>
360
+ <p className="text-xs text-muted-foreground">2 min ago</p>
361
+ </div>
362
+ <div className="h-2 w-2 bg-blue-500 rounded-full mt-1" />
363
+ </div>
364
+ </div>
365
+ <Separator />
366
+ <Button variant="outline" size="sm" className="w-full">
367
+ View all notifications
368
+ </Button>
369
+ </div>
370
+ </PopoverContent>
371
+ </Popover>;
372
+ ```
373
+
374
+ ### Posicionamiento Custom
375
+
376
+ ```tsx
377
+ {
378
+ /* Top */
379
+ }
380
+ <Popover>
381
+ <PopoverTrigger asChild>
382
+ <Button variant="outline">Top</Button>
383
+ </PopoverTrigger>
384
+ <PopoverContent side="top">
385
+ <p>This popover appears on top</p>
386
+ </PopoverContent>
387
+ </Popover>;
388
+
389
+ {
390
+ /* Right */
391
+ }
392
+ <Popover>
393
+ <PopoverTrigger asChild>
394
+ <Button variant="outline">Right</Button>
395
+ </PopoverTrigger>
396
+ <PopoverContent side="right">
397
+ <p>This popover appears on the right</p>
398
+ </PopoverContent>
399
+ </Popover>;
400
+
401
+ {
402
+ /* Start aligned */
403
+ }
404
+ <Popover>
405
+ <PopoverTrigger asChild>
406
+ <Button variant="outline">Start aligned</Button>
407
+ </PopoverTrigger>
408
+ <PopoverContent align="start">
409
+ <p>This popover is aligned to the start</p>
410
+ </PopoverContent>
411
+ </Popover>;
412
+ ```
413
+
414
+ ### Con Anchor
415
+
416
+ ```tsx
417
+ <div className="space-y-4">
418
+ <p>
419
+ This is some text with an{" "}
420
+ <Popover>
421
+ <PopoverAnchor asChild>
422
+ <span className="underline cursor-pointer">anchored element</span>
423
+ </PopoverAnchor>
424
+ <PopoverTrigger asChild>
425
+ <Button variant="outline" className="ml-2">
426
+ Show info
427
+ </Button>
428
+ </PopoverTrigger>
429
+ <PopoverContent>
430
+ <p>This popover is anchored to the underlined text above!</p>
431
+ </PopoverContent>
432
+ </Popover>
433
+ </p>
434
+ </div>
435
+ ```
436
+
437
+ ### Controlado
438
+
439
+ ```tsx
440
+ import { useState } from "react";
441
+
442
+ function App() {
443
+ const [open, setOpen] = useState(false);
444
+
445
+ return (
446
+ <Popover open={open} onOpenChange={setOpen}>
447
+ <PopoverTrigger asChild>
448
+ <Button variant="outline">Toggle</Button>
449
+ </PopoverTrigger>
450
+ <PopoverContent>
451
+ <div className="space-y-2">
452
+ <p>Controlled popover content</p>
453
+ <Button onClick={() => setOpen(false)}>Close</Button>
454
+ </div>
455
+ </PopoverContent>
456
+ </Popover>
457
+ );
458
+ }
459
+ ```
460
+
461
+ ## Casos de Uso Comunes
462
+
463
+ **Date pickers**: Mostrar calendar en popover
464
+ **Settings**: Controles compactos de configuración
465
+ **User profiles**: Preview de perfiles al hover/click
466
+ **Notifications**: Lista de notificaciones
467
+ **Quick actions**: Acciones contextuales sin modal
468
+ **Info tooltips**: Información rica vs tooltip simple
469
+ **Forms**: Formularios compactos inline
470
+
471
+ ## Estados y Data Attributes
472
+
473
+ ### PopoverContent States
474
+
475
+ - **Open**: `data-[state=open]` → `animate-in`, `fade-in-0`, `zoom-in-95`
476
+ - **Closed**: `data-[state=closed]` → `animate-out`, `fade-out-0`, `zoom-out-95`
477
+
478
+ ### Side Animations
479
+
480
+ - **Top**: `data-[side=top]` → `slide-in-from-bottom-2`
481
+ - **Right**: `data-[side=right]` → `slide-in-from-left-2`
482
+ - **Bottom**: `data-[side=bottom]` → `slide-in-from-top-2`
483
+ - **Left**: `data-[side=left]` → `slide-in-from-right-2`
484
+
485
+ ## Interacción
486
+
487
+ - ✅ **Click to open**: Click en trigger abre popover
488
+ - ✅ **Click outside**: Click fuera cierra popover (si no es modal)
489
+ - ✅ **Escape**: Presionar Esc cierra popover
490
+ - ✅ **Focus trap**: Si `modal=true`, foco queda atrapado dentro
491
+ - ✅ **Keyboard**: Tab navega entre elementos internos
492
+
493
+ ## Accesibilidad
494
+
495
+ - ✅ **ARIA**: `role="dialog"`, `aria-labelledby`, `aria-describedby` según contenido
496
+ - ✅ **Focus management**: Focus automático al abrir
497
+ - ✅ **Keyboard**: Esc para cerrar, Tab para navegar
498
+ - ✅ **Portal**: Renderiza en `document.body` para evitar problemas de z-index
499
+ - ✅ **Modal mode**: `modal=true` para bloquear interacción fuera del popover
500
+
501
+ ## Notas de Implementación
502
+
503
+ - **Radix UI**: Basado en `@radix-ui/react-popover`
504
+ - **Portal rendering**: Content se renderiza en `document.body`
505
+ - **Collision detection**: Auto-ajusta posición si sale del viewport
506
+ - **Transform origin**: CSS variables de Radix para animaciones
507
+ - **Default width**: `w-72` (288px)
508
+ - **Default padding**: `p-4`
509
+ - **Z-index**: 50 para aparecer sobre contenido
510
+ - **Modal**: Por defecto `modal=false` (permite interacción fuera)
511
+
512
+ ## Diferencias con Dialog y HoverCard
513
+
514
+ | Aspecto | Popover | Dialog | HoverCard |
515
+ | ---------------- | ----------------- | --------------------- | --------------- |
516
+ | **Trigger** | Click | Click | Hover |
517
+ | **Modal** | Opcional | Siempre | No |
518
+ | **Backdrop** | Opcional | Sí | No |
519
+ | **Contenido** | Compacto | Extenso | Preview |
520
+ | **Persistencia** | Hasta click fuera | Hasta close explícito | Hasta hover out |
521
+
522
+ ## Troubleshooting
523
+
524
+ **No aparece**: Verifica que PopoverContent esté dentro de Popover root
525
+ **Posición incorrecta**: Ajusta `side`, `align`, `sideOffset` y `alignOffset`
526
+ **Contenido cortado**: Verifica que no haya `overflow: hidden` en containers
527
+ **No cierra**: Si `modal=true`, solo cierra con Esc o close explícito
528
+ **Focus no funciona**: Content debe tener elementos focuseables
529
+ **Backdrop no se ve**: Popover no tiene backdrop por defecto, usa `modal=true` y customiza
530
+ **Z-index issues**: Content usa portal, debe aparecer sobre todo
531
+ **Anchor no funciona**: PopoverAnchor debe estar dentro de Popover root
532
+
533
+ ## Referencias
534
+
535
+ - **Radix UI Popover**: <https://www.radix-ui.com/primitives/docs/components/popover>
536
+ - **shadcn/ui Popover**: <https://ui.shadcn.com/docs/components/popover>