@adamosuiteservices/ui 1.7.13 → 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 +62 -22
  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,650 +1,650 @@
1
- # Pagination
2
-
3
- Controles de navegación para contenido paginado. Incluye Previous/Next, números de página, ellipsis para gaps y estado activo.
4
-
5
- ## Descripción
6
-
7
- El componente `Pagination` proporciona controles de navegación para contenido paginado.
8
-
9
- ## Importación
10
-
11
- ```typescript
12
- import {
13
- Pagination,
14
- PaginationContent,
15
- PaginationEllipsis,
16
- PaginationItem,
17
- PaginationLink,
18
- PaginationNext,
19
- PaginationPrevious,
20
- } from "@adamosuiteservices/ui/pagination";
21
- ```
22
-
23
- ## Anatomía
24
-
25
- ```tsx
26
- <Pagination>
27
- <PaginationContent>
28
- <PaginationItem>
29
- <PaginationPrevious href="#" />
30
- </PaginationItem>
31
- <PaginationItem>
32
- <PaginationLink href="#">1</PaginationLink>
33
- </PaginationItem>
34
- <PaginationItem>
35
- <PaginationLink href="#" isActive>
36
- 2
37
- </PaginationLink>
38
- </PaginationItem>
39
- <PaginationItem>
40
- <PaginationLink href="#">3</PaginationLink>
41
- </PaginationItem>
42
- <PaginationItem>
43
- <PaginationEllipsis />
44
- </PaginationItem>
45
- <PaginationItem>
46
- <PaginationNext href="#" />
47
- </PaginationItem>
48
- </PaginationContent>
49
- </Pagination>
50
- ```
51
-
52
- **Componentes**: 7 (Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis)
53
-
54
- ## Props Principales
55
-
56
- ### Pagination (Root)
57
-
58
- | Prop | Tipo | Descripción |
59
- | ----------- | -------- | ---------------------- |
60
- | `className` | `string` | Clases CSS adicionales |
61
-
62
- **Nota**: `<nav>` con `role="navigation"` y `aria-label="pagination"`
63
-
64
- ### PaginationContent
65
-
66
- | Prop | Tipo | Descripción |
67
- | ----------- | -------- | ---------------------- |
68
- | `className` | `string` | Clases CSS adicionales |
69
-
70
- **Nota**: `<ul>` con flex y gap-1
71
-
72
- ### PaginationItem
73
-
74
- | Prop | Tipo | Descripción |
75
- | ----------- | -------- | ---------------------- |
76
- | `className` | `string` | Clases CSS adicionales |
77
-
78
- **Nota**: `<li>` wrapper simple
79
-
80
- ### PaginationLink
81
-
82
- | Prop | Tipo | Default | Descripción |
83
- | ----------- | ------------- | -------- | ------------------------ |
84
- | `isActive` | `boolean` | `false` | Marca página como activa |
85
- | `size` | Button size | `"icon"` | Tamaño del link |
86
- | `href` | `string` | - | URL destino |
87
- | `onClick` | `(e) => void` | - | Click handler |
88
- | `className` | `string` | - | Clases CSS adicionales |
89
-
90
- **Nota**: `<a>` estilizado como Button
91
-
92
- ### PaginationPrevious
93
-
94
- | Prop | Tipo | Default | Descripción |
95
- | ----------- | ------------- | ------------ | ---------------------- |
96
- | `children` | `ReactNode` | `"Previous"` | Texto del botón |
97
- | `href` | `string` | - | URL destino |
98
- | `onClick` | `(e) => void` | - | Click handler |
99
- | `className` | `string` | - | Clases CSS adicionales |
100
-
101
- **Nota**: PaginationLink con ChevronLeft icon, texto "Previous" oculto en mobile
102
-
103
- ### PaginationNext
104
-
105
- | Prop | Tipo | Default | Descripción |
106
- | ----------- | ------------- | -------- | ---------------------- |
107
- | `children` | `ReactNode` | `"Next"` | Texto del botón |
108
- | `href` | `string` | - | URL destino |
109
- | `onClick` | `(e) => void` | - | Click handler |
110
- | `className` | `string` | - | Clases CSS adicionales |
111
-
112
- **Nota**: PaginationLink con ChevronRight icon, texto "Next" oculto en mobile
113
-
114
- ### PaginationEllipsis
115
-
116
- | Prop | Tipo | Descripción |
117
- | ----------- | -------- | ---------------------- |
118
- | `className` | `string` | Clases CSS adicionales |
119
-
120
- **Nota**: `<span>` con MoreHorizontal icon y `aria-hidden`
121
-
122
- ## Patrones de Uso
123
-
124
- ### Básico
125
-
126
- ```tsx
127
- <Pagination>
128
- <PaginationContent>
129
- <PaginationItem>
130
- <PaginationPrevious href="#" />
131
- </PaginationItem>
132
- <PaginationItem>
133
- <PaginationLink href="#">1</PaginationLink>
134
- </PaginationItem>
135
- <PaginationItem>
136
- <PaginationLink href="#" isActive>
137
- 2
138
- </PaginationLink>
139
- </PaginationItem>
140
- <PaginationItem>
141
- <PaginationLink href="#">3</PaginationLink>
142
- </PaginationItem>
143
- <PaginationItem>
144
- <PaginationEllipsis />
145
- </PaginationItem>
146
- <PaginationItem>
147
- <PaginationNext href="#" />
148
- </PaginationItem>
149
- </PaginationContent>
150
- </Pagination>
151
- ```
152
-
153
- ### Simple (Sin Ellipsis)
154
-
155
- ```tsx
156
- <Pagination>
157
- <PaginationContent>
158
- <PaginationItem>
159
- <PaginationPrevious href="#" />
160
- </PaginationItem>
161
- <PaginationItem>
162
- <PaginationLink href="#">1</PaginationLink>
163
- </PaginationItem>
164
- <PaginationItem>
165
- <PaginationLink href="#">2</PaginationLink>
166
- </PaginationItem>
167
- <PaginationItem>
168
- <PaginationLink href="#">3</PaginationLink>
169
- </PaginationItem>
170
- <PaginationItem>
171
- <PaginationNext href="#" />
172
- </PaginationItem>
173
- </PaginationContent>
174
- </Pagination>
175
- ```
176
-
177
- ### Con Ellipsis Doble
178
-
179
- ```tsx
180
- <Pagination>
181
- <PaginationContent>
182
- <PaginationItem>
183
- <PaginationPrevious href="#" />
184
- </PaginationItem>
185
- <PaginationItem>
186
- <PaginationLink href="#">1</PaginationLink>
187
- </PaginationItem>
188
- <PaginationItem>
189
- <PaginationEllipsis />
190
- </PaginationItem>
191
- <PaginationItem>
192
- <PaginationLink href="#">10</PaginationLink>
193
- </PaginationItem>
194
- <PaginationItem>
195
- <PaginationLink href="#" isActive>
196
- 11
197
- </PaginationLink>
198
- </PaginationItem>
199
- <PaginationItem>
200
- <PaginationLink href="#">12</PaginationLink>
201
- </PaginationItem>
202
- <PaginationItem>
203
- <PaginationEllipsis />
204
- </PaginationItem>
205
- <PaginationItem>
206
- <PaginationLink href="#">50</PaginationLink>
207
- </PaginationItem>
208
- <PaginationItem>
209
- <PaginationNext href="#" />
210
- </PaginationItem>
211
- </PaginationContent>
212
- </Pagination>
213
- ```
214
-
215
- ### Primera Página (Disabled Previous)
216
-
217
- ```tsx
218
- <Pagination>
219
- <PaginationContent>
220
- <PaginationItem>
221
- <PaginationPrevious href="#" className="pointer-events-none opacity-50" />
222
- </PaginationItem>
223
- <PaginationItem>
224
- <PaginationLink href="#" isActive>
225
- 1
226
- </PaginationLink>
227
- </PaginationItem>
228
- <PaginationItem>
229
- <PaginationLink href="#">2</PaginationLink>
230
- </PaginationItem>
231
- <PaginationItem>
232
- <PaginationLink href="#">3</PaginationLink>
233
- </PaginationItem>
234
- <PaginationItem>
235
- <PaginationEllipsis />
236
- </PaginationItem>
237
- <PaginationItem>
238
- <PaginationLink href="#">25</PaginationLink>
239
- </PaginationItem>
240
- <PaginationItem>
241
- <PaginationNext href="#" />
242
- </PaginationItem>
243
- </PaginationContent>
244
- </Pagination>
245
- ```
246
-
247
- ### Última Página (Disabled Next)
248
-
249
- ```tsx
250
- <Pagination>
251
- <PaginationContent>
252
- <PaginationItem>
253
- <PaginationPrevious href="#" />
254
- </PaginationItem>
255
- <PaginationItem>
256
- <PaginationLink href="#">1</PaginationLink>
257
- </PaginationItem>
258
- <PaginationItem>
259
- <PaginationEllipsis />
260
- </PaginationItem>
261
- <PaginationItem>
262
- <PaginationLink href="#">23</PaginationLink>
263
- </PaginationItem>
264
- <PaginationItem>
265
- <PaginationLink href="#">24</PaginationLink>
266
- </PaginationItem>
267
- <PaginationItem>
268
- <PaginationLink href="#" isActive>
269
- 25
270
- </PaginationLink>
271
- </PaginationItem>
272
- <PaginationItem>
273
- <PaginationNext href="#" className="pointer-events-none opacity-50" />
274
- </PaginationItem>
275
- </PaginationContent>
276
- </Pagination>
277
- ```
278
-
279
- ### Página Única
280
-
281
- ```tsx
282
- <Pagination>
283
- <PaginationContent>
284
- <PaginationItem>
285
- <PaginationPrevious href="#" className="pointer-events-none opacity-50" />
286
- </PaginationItem>
287
- <PaginationItem>
288
- <PaginationLink href="#" isActive>
289
- 1
290
- </PaginationLink>
291
- </PaginationItem>
292
- <PaginationItem>
293
- <PaginationNext href="#" className="pointer-events-none opacity-50" />
294
- </PaginationItem>
295
- </PaginationContent>
296
- </Pagination>
297
- ```
298
-
299
- ### Compacto (Solo Previous/Next)
300
-
301
- ```tsx
302
- <Pagination className="justify-start">
303
- <PaginationContent>
304
- <PaginationItem>
305
- <PaginationPrevious href="#" />
306
- </PaginationItem>
307
- <PaginationItem>
308
- <PaginationNext href="#" />
309
- </PaginationItem>
310
- </PaginationContent>
311
- </Pagination>
312
- ```
313
-
314
- ### Con Información de Página
315
-
316
- ```tsx
317
- <div className="space-y-4">
318
- <div className="flex items-center justify-between text-sm text-muted-foreground">
319
- <span>Showing 1-10 of 250 results</span>
320
- <span>Page 2 of 25</span>
321
- </div>
322
-
323
- <Pagination>
324
- <PaginationContent>
325
- <PaginationItem>
326
- <PaginationPrevious href="#" />
327
- </PaginationItem>
328
- <PaginationItem>
329
- <PaginationLink href="#">1</PaginationLink>
330
- </PaginationItem>
331
- <PaginationItem>
332
- <PaginationLink href="#" isActive>
333
- 2
334
- </PaginationLink>
335
- </PaginationItem>
336
- <PaginationItem>
337
- <PaginationLink href="#">3</PaginationLink>
338
- </PaginationItem>
339
- <PaginationItem>
340
- <PaginationEllipsis />
341
- </PaginationItem>
342
- <PaginationItem>
343
- <PaginationLink href="#">25</PaginationLink>
344
- </PaginationItem>
345
- <PaginationItem>
346
- <PaginationNext href="#" />
347
- </PaginationItem>
348
- </PaginationContent>
349
- </Pagination>
350
- </div>
351
- ```
352
-
353
- ### Interactivo (Con Estado)
354
-
355
- ```tsx
356
- import { useState } from "react";
357
-
358
- function App() {
359
- const [currentPage, setCurrentPage] = useState(5);
360
- const totalPages = 20;
361
-
362
- const generatePageNumbers = () => {
363
- const pages = [];
364
-
365
- // Always show first page
366
- pages.push(1);
367
-
368
- // Add ellipsis if there's a gap
369
- if (currentPage > 4) {
370
- pages.push(-1); // -1 represents ellipsis
371
- }
372
-
373
- // Show pages around current page
374
- const start = Math.max(2, currentPage - 1);
375
- const end = Math.min(totalPages - 1, currentPage + 1);
376
-
377
- for (let i = start; i <= end; i++) {
378
- if (i !== 1 && i !== totalPages) {
379
- pages.push(i);
380
- }
381
- }
382
-
383
- // Add ellipsis if there's a gap
384
- if (currentPage < totalPages - 3) {
385
- pages.push(-2); // -2 represents ellipsis
386
- }
387
-
388
- // Always show last page if more than 1 page
389
- if (totalPages > 1) {
390
- pages.push(totalPages);
391
- }
392
-
393
- return pages;
394
- };
395
-
396
- const pages = generatePageNumbers();
397
-
398
- const handlePageClick = (page: number) => {
399
- setCurrentPage(page);
400
- };
401
-
402
- const handlePrevious = () => {
403
- if (currentPage > 1) {
404
- setCurrentPage(currentPage - 1);
405
- }
406
- };
407
-
408
- const handleNext = () => {
409
- if (currentPage < totalPages) {
410
- setCurrentPage(currentPage + 1);
411
- }
412
- };
413
-
414
- return (
415
- <div className="space-y-4">
416
- <p className="text-center text-sm text-muted-foreground">
417
- Page {currentPage} of {totalPages}
418
- </p>
419
-
420
- <Pagination>
421
- <PaginationContent>
422
- <PaginationItem>
423
- <PaginationPrevious
424
- href="#"
425
- onClick={(e) => {
426
- e.preventDefault();
427
- handlePrevious();
428
- }}
429
- className={
430
- currentPage === 1 ? "pointer-events-none opacity-50" : ""
431
- }
432
- />
433
- </PaginationItem>
434
-
435
- {pages.map((page, index) => (
436
- <PaginationItem key={index}>
437
- {page < 0 ? (
438
- <PaginationEllipsis />
439
- ) : (
440
- <PaginationLink
441
- href="#"
442
- isActive={page === currentPage}
443
- onClick={(e) => {
444
- e.preventDefault();
445
- handlePageClick(page);
446
- }}
447
- >
448
- {page}
449
- </PaginationLink>
450
- )}
451
- </PaginationItem>
452
- ))}
453
-
454
- <PaginationItem>
455
- <PaginationNext
456
- href="#"
457
- onClick={(e) => {
458
- e.preventDefault();
459
- handleNext();
460
- }}
461
- className={
462
- currentPage === totalPages
463
- ? "pointer-events-none opacity-50"
464
- : ""
465
- }
466
- />
467
- </PaginationItem>
468
- </PaginationContent>
469
- </Pagination>
470
- </div>
471
- );
472
- }
473
- ```
474
-
475
- ### Tamaños Personalizados
476
-
477
- ```tsx
478
- {
479
- /* Small */
480
- }
481
- <Pagination>
482
- <PaginationContent className="gap-0.5">
483
- <PaginationItem>
484
- <PaginationPrevious href="#" className="h-8 px-2 text-xs" />
485
- </PaginationItem>
486
- <PaginationItem>
487
- <PaginationLink href="#" className="h-8 w-8 text-xs">
488
- 1
489
- </PaginationLink>
490
- </PaginationItem>
491
- <PaginationItem>
492
- <PaginationLink href="#" isActive className="h-8 w-8 text-xs">
493
- 2
494
- </PaginationLink>
495
- </PaginationItem>
496
- <PaginationItem>
497
- <PaginationNext href="#" className="h-8 px-2 text-xs" />
498
- </PaginationItem>
499
- </PaginationContent>
500
- </Pagination>;
501
-
502
- {
503
- /* Large */
504
- }
505
- <Pagination>
506
- <PaginationContent className="gap-2">
507
- <PaginationItem>
508
- <PaginationPrevious href="#" className="h-12 px-4 text-base" />
509
- </PaginationItem>
510
- <PaginationItem>
511
- <PaginationLink href="#" className="h-12 w-12 text-base">
512
- 1
513
- </PaginationLink>
514
- </PaginationItem>
515
- <PaginationItem>
516
- <PaginationLink href="#" isActive className="h-12 w-12 text-base">
517
- 2
518
- </PaginationLink>
519
- </PaginationItem>
520
- <PaginationItem>
521
- <PaginationNext href="#" className="h-12 px-4 text-base" />
522
- </PaginationItem>
523
- </PaginationContent>
524
- </Pagination>;
525
- ```
526
-
527
- ## Casos de Uso Comunes
528
-
529
- **Tables**: Paginación de tablas con muchas filas
530
- **Lists**: Listas largas de items (productos, usuarios, posts)
531
- **Search results**: Resultados de búsqueda paginados
532
- **Galleries**: Galerías de imágenes o archivos
533
- **Admin panels**: Dashboards con data paginada
534
- **API results**: Navegación de resultados de API con offset/limit
535
-
536
- ## Estados y Data Attributes
537
-
538
- ### PaginationLink
539
-
540
- - **Active**: `isActive` → variant outline, `aria-current="page"`
541
- - **Inactive**: variant ghost
542
-
543
- ### Disabled (Previous/Next)
544
-
545
- No hay prop disabled nativa, se simula con:
546
-
547
- ```tsx
548
- className = "pointer-events-none opacity-50";
549
- ```
550
-
551
- ## Estilos Base
552
-
553
- ### Pagination (Root)
554
-
555
- - **Layout**: `mx-auto flex w-full justify-center`
556
- - **Semantic**: `<nav role="navigation" aria-label="pagination">`
557
-
558
- ### PaginationContent
559
-
560
- - **Layout**: `flex flex-row items-center gap-1`
561
-
562
- ### PaginationLink
563
-
564
- - **Size default**: `size="icon"` (h-9 w-9)
565
- - **Variants**: ghost (inactive), outline (active)
566
-
567
- ### PaginationPrevious/Next
568
-
569
- - **Size**: `size="default"`
570
- - **Padding**: `px-2.5`
571
- - **Responsive**: Texto oculto en mobile (`hidden sm:block`)
572
- - **Gap**: `gap-1` entre icono y texto
573
-
574
- ### PaginationEllipsis
575
-
576
- - **Size**: `size-9`
577
- - **Icon**: MoreHorizontal `size-4`
578
- - **Layout**: `flex items-center justify-center`
579
- - **ARIA**: `aria-hidden`
580
-
581
- ## Responsive
582
-
583
- - **Mobile**: Previous/Next solo muestran icono
584
- - **Desktop (sm+)**: Previous/Next muestran icono + texto
585
-
586
- ## Accesibilidad
587
-
588
- - ✅ **Semantic**: `<nav role="navigation" aria-label="pagination">`
589
- - ✅ **Current page**: `aria-current="page"` en página activa
590
- - ✅ **Screen readers**: Ellipsis tiene `<span className="sr-only">More pages</span>`
591
- - ✅ **Keyboard**: Navegación con Tab, activación con Enter/Space
592
- - ✅ **Labels**: Previous/Next tienen `aria-label` descriptivo
593
- - ⚠️ **Disabled**: Usa `pointer-events-none opacity-50` + previene click en handler
594
-
595
- ## Notas de Implementación
596
-
597
- - **Links**: PaginationLink es `<a>` no `<button>`, usa Button styles
598
- - **Icons**: ChevronLeft, ChevronRight, MoreHorizontal de lucide-react
599
- - **Responsive text**: Previous/Next usan `hidden sm:block` en texto
600
- - **No state**: Componente stateless, maneja estado externamente
601
- - **Ellipsis logic**: Representación negativa (-1, -2) común para identificar ellipsis
602
- - **Disabled**: No hay prop disabled, usa className manual
603
- - **Centering**: Root tiene `mx-auto justify-center`
604
-
605
- ## Algoritmo de Generación de Páginas
606
-
607
- Patrón común para mostrar páginas con ellipsis:
608
-
609
- ```tsx
610
- const generatePageNumbers = (current: number, total: number) => {
611
- const pages = [];
612
-
613
- // Siempre primera página
614
- pages.push(1);
615
-
616
- // Ellipsis izquierda si hay gap
617
- if (current > 4) pages.push(-1);
618
-
619
- // Páginas alrededor de current
620
- const start = Math.max(2, current - 1);
621
- const end = Math.min(total - 1, current + 1);
622
- for (let i = start; i <= end; i++) {
623
- if (i !== 1 && i !== total) pages.push(i);
624
- }
625
-
626
- // Ellipsis derecha si hay gap
627
- if (current < total - 3) pages.push(-2);
628
-
629
- // Siempre última página
630
- if (total > 1) pages.push(total);
631
-
632
- return pages;
633
- };
634
- ```
635
-
636
- ## Troubleshooting
637
-
638
- **Previous/Next no se deshabilitan**: No hay prop disabled, usa `className="pointer-events-none opacity-50"` y previene click en handler
639
- **Active no se ve**: Verifica `isActive` prop y que solo una página lo tenga
640
- **Texto Previous/Next no se ve en mobile**: Comportamiento esperado, usa `hidden sm:block`
641
- **Ellipsis clickeable**: Ellipsis no debe ser clickeable, es `<span>` no link
642
- **Spacing inconsistente**: PaginationContent tiene `gap-1`, ajusta con className
643
- **No centrado**: Root tiene `justify-center`, override con `className="justify-start"` si necesario
644
- **Links no funcionan**: PaginationLink usa `<a>`, asegúrate de pasar `href` o `onClick`
645
- **Too many pages**: Usa ellipsis y lógica de generación de páginas para mostrar subset
646
-
647
- ## Referencias
648
-
649
- - **shadcn/ui Pagination**: <https://ui.shadcn.com/docs/components/pagination>
650
- - **WAI-ARIA Pagination**: <https://www.w3.org/WAI/ARIA/apg/patterns/pagination/>
1
+ # Pagination
2
+
3
+ Controles de navegación para contenido paginado. Incluye Previous/Next, números de página, ellipsis para gaps y estado activo.
4
+
5
+ ## Descripción
6
+
7
+ El componente `Pagination` proporciona controles de navegación para contenido paginado.
8
+
9
+ ## Importación
10
+
11
+ ```typescript
12
+ import {
13
+ Pagination,
14
+ PaginationContent,
15
+ PaginationEllipsis,
16
+ PaginationItem,
17
+ PaginationLink,
18
+ PaginationNext,
19
+ PaginationPrevious,
20
+ } from "@adamosuiteservices/ui/pagination";
21
+ ```
22
+
23
+ ## Anatomía
24
+
25
+ ```tsx
26
+ <Pagination>
27
+ <PaginationContent>
28
+ <PaginationItem>
29
+ <PaginationPrevious href="#" />
30
+ </PaginationItem>
31
+ <PaginationItem>
32
+ <PaginationLink href="#">1</PaginationLink>
33
+ </PaginationItem>
34
+ <PaginationItem>
35
+ <PaginationLink href="#" isActive>
36
+ 2
37
+ </PaginationLink>
38
+ </PaginationItem>
39
+ <PaginationItem>
40
+ <PaginationLink href="#">3</PaginationLink>
41
+ </PaginationItem>
42
+ <PaginationItem>
43
+ <PaginationEllipsis />
44
+ </PaginationItem>
45
+ <PaginationItem>
46
+ <PaginationNext href="#" />
47
+ </PaginationItem>
48
+ </PaginationContent>
49
+ </Pagination>
50
+ ```
51
+
52
+ **Componentes**: 7 (Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis)
53
+
54
+ ## Props Principales
55
+
56
+ ### Pagination (Root)
57
+
58
+ | Prop | Tipo | Descripción |
59
+ | ----------- | -------- | ---------------------- |
60
+ | `className` | `string` | Clases CSS adicionales |
61
+
62
+ **Nota**: `<nav>` con `role="navigation"` y `aria-label="pagination"`
63
+
64
+ ### PaginationContent
65
+
66
+ | Prop | Tipo | Descripción |
67
+ | ----------- | -------- | ---------------------- |
68
+ | `className` | `string` | Clases CSS adicionales |
69
+
70
+ **Nota**: `<ul>` con flex y gap-1
71
+
72
+ ### PaginationItem
73
+
74
+ | Prop | Tipo | Descripción |
75
+ | ----------- | -------- | ---------------------- |
76
+ | `className` | `string` | Clases CSS adicionales |
77
+
78
+ **Nota**: `<li>` wrapper simple
79
+
80
+ ### PaginationLink
81
+
82
+ | Prop | Tipo | Default | Descripción |
83
+ | ----------- | ------------- | -------- | ------------------------ |
84
+ | `isActive` | `boolean` | `false` | Marca página como activa |
85
+ | `size` | Button size | `"icon"` | Tamaño del link |
86
+ | `href` | `string` | - | URL destino |
87
+ | `onClick` | `(e) => void` | - | Click handler |
88
+ | `className` | `string` | - | Clases CSS adicionales |
89
+
90
+ **Nota**: `<a>` estilizado como Button
91
+
92
+ ### PaginationPrevious
93
+
94
+ | Prop | Tipo | Default | Descripción |
95
+ | ----------- | ------------- | ------------ | ---------------------- |
96
+ | `children` | `ReactNode` | `"Previous"` | Texto del botón |
97
+ | `href` | `string` | - | URL destino |
98
+ | `onClick` | `(e) => void` | - | Click handler |
99
+ | `className` | `string` | - | Clases CSS adicionales |
100
+
101
+ **Nota**: PaginationLink con ChevronLeft icon, texto "Previous" oculto en mobile
102
+
103
+ ### PaginationNext
104
+
105
+ | Prop | Tipo | Default | Descripción |
106
+ | ----------- | ------------- | -------- | ---------------------- |
107
+ | `children` | `ReactNode` | `"Next"` | Texto del botón |
108
+ | `href` | `string` | - | URL destino |
109
+ | `onClick` | `(e) => void` | - | Click handler |
110
+ | `className` | `string` | - | Clases CSS adicionales |
111
+
112
+ **Nota**: PaginationLink con ChevronRight icon, texto "Next" oculto en mobile
113
+
114
+ ### PaginationEllipsis
115
+
116
+ | Prop | Tipo | Descripción |
117
+ | ----------- | -------- | ---------------------- |
118
+ | `className` | `string` | Clases CSS adicionales |
119
+
120
+ **Nota**: `<span>` con MoreHorizontal icon y `aria-hidden`
121
+
122
+ ## Patrones de Uso
123
+
124
+ ### Básico
125
+
126
+ ```tsx
127
+ <Pagination>
128
+ <PaginationContent>
129
+ <PaginationItem>
130
+ <PaginationPrevious href="#" />
131
+ </PaginationItem>
132
+ <PaginationItem>
133
+ <PaginationLink href="#">1</PaginationLink>
134
+ </PaginationItem>
135
+ <PaginationItem>
136
+ <PaginationLink href="#" isActive>
137
+ 2
138
+ </PaginationLink>
139
+ </PaginationItem>
140
+ <PaginationItem>
141
+ <PaginationLink href="#">3</PaginationLink>
142
+ </PaginationItem>
143
+ <PaginationItem>
144
+ <PaginationEllipsis />
145
+ </PaginationItem>
146
+ <PaginationItem>
147
+ <PaginationNext href="#" />
148
+ </PaginationItem>
149
+ </PaginationContent>
150
+ </Pagination>
151
+ ```
152
+
153
+ ### Simple (Sin Ellipsis)
154
+
155
+ ```tsx
156
+ <Pagination>
157
+ <PaginationContent>
158
+ <PaginationItem>
159
+ <PaginationPrevious href="#" />
160
+ </PaginationItem>
161
+ <PaginationItem>
162
+ <PaginationLink href="#">1</PaginationLink>
163
+ </PaginationItem>
164
+ <PaginationItem>
165
+ <PaginationLink href="#">2</PaginationLink>
166
+ </PaginationItem>
167
+ <PaginationItem>
168
+ <PaginationLink href="#">3</PaginationLink>
169
+ </PaginationItem>
170
+ <PaginationItem>
171
+ <PaginationNext href="#" />
172
+ </PaginationItem>
173
+ </PaginationContent>
174
+ </Pagination>
175
+ ```
176
+
177
+ ### Con Ellipsis Doble
178
+
179
+ ```tsx
180
+ <Pagination>
181
+ <PaginationContent>
182
+ <PaginationItem>
183
+ <PaginationPrevious href="#" />
184
+ </PaginationItem>
185
+ <PaginationItem>
186
+ <PaginationLink href="#">1</PaginationLink>
187
+ </PaginationItem>
188
+ <PaginationItem>
189
+ <PaginationEllipsis />
190
+ </PaginationItem>
191
+ <PaginationItem>
192
+ <PaginationLink href="#">10</PaginationLink>
193
+ </PaginationItem>
194
+ <PaginationItem>
195
+ <PaginationLink href="#" isActive>
196
+ 11
197
+ </PaginationLink>
198
+ </PaginationItem>
199
+ <PaginationItem>
200
+ <PaginationLink href="#">12</PaginationLink>
201
+ </PaginationItem>
202
+ <PaginationItem>
203
+ <PaginationEllipsis />
204
+ </PaginationItem>
205
+ <PaginationItem>
206
+ <PaginationLink href="#">50</PaginationLink>
207
+ </PaginationItem>
208
+ <PaginationItem>
209
+ <PaginationNext href="#" />
210
+ </PaginationItem>
211
+ </PaginationContent>
212
+ </Pagination>
213
+ ```
214
+
215
+ ### Primera Página (Disabled Previous)
216
+
217
+ ```tsx
218
+ <Pagination>
219
+ <PaginationContent>
220
+ <PaginationItem>
221
+ <PaginationPrevious href="#" className="pointer-events-none opacity-50" />
222
+ </PaginationItem>
223
+ <PaginationItem>
224
+ <PaginationLink href="#" isActive>
225
+ 1
226
+ </PaginationLink>
227
+ </PaginationItem>
228
+ <PaginationItem>
229
+ <PaginationLink href="#">2</PaginationLink>
230
+ </PaginationItem>
231
+ <PaginationItem>
232
+ <PaginationLink href="#">3</PaginationLink>
233
+ </PaginationItem>
234
+ <PaginationItem>
235
+ <PaginationEllipsis />
236
+ </PaginationItem>
237
+ <PaginationItem>
238
+ <PaginationLink href="#">25</PaginationLink>
239
+ </PaginationItem>
240
+ <PaginationItem>
241
+ <PaginationNext href="#" />
242
+ </PaginationItem>
243
+ </PaginationContent>
244
+ </Pagination>
245
+ ```
246
+
247
+ ### Última Página (Disabled Next)
248
+
249
+ ```tsx
250
+ <Pagination>
251
+ <PaginationContent>
252
+ <PaginationItem>
253
+ <PaginationPrevious href="#" />
254
+ </PaginationItem>
255
+ <PaginationItem>
256
+ <PaginationLink href="#">1</PaginationLink>
257
+ </PaginationItem>
258
+ <PaginationItem>
259
+ <PaginationEllipsis />
260
+ </PaginationItem>
261
+ <PaginationItem>
262
+ <PaginationLink href="#">23</PaginationLink>
263
+ </PaginationItem>
264
+ <PaginationItem>
265
+ <PaginationLink href="#">24</PaginationLink>
266
+ </PaginationItem>
267
+ <PaginationItem>
268
+ <PaginationLink href="#" isActive>
269
+ 25
270
+ </PaginationLink>
271
+ </PaginationItem>
272
+ <PaginationItem>
273
+ <PaginationNext href="#" className="pointer-events-none opacity-50" />
274
+ </PaginationItem>
275
+ </PaginationContent>
276
+ </Pagination>
277
+ ```
278
+
279
+ ### Página Única
280
+
281
+ ```tsx
282
+ <Pagination>
283
+ <PaginationContent>
284
+ <PaginationItem>
285
+ <PaginationPrevious href="#" className="pointer-events-none opacity-50" />
286
+ </PaginationItem>
287
+ <PaginationItem>
288
+ <PaginationLink href="#" isActive>
289
+ 1
290
+ </PaginationLink>
291
+ </PaginationItem>
292
+ <PaginationItem>
293
+ <PaginationNext href="#" className="pointer-events-none opacity-50" />
294
+ </PaginationItem>
295
+ </PaginationContent>
296
+ </Pagination>
297
+ ```
298
+
299
+ ### Compacto (Solo Previous/Next)
300
+
301
+ ```tsx
302
+ <Pagination className="justify-start">
303
+ <PaginationContent>
304
+ <PaginationItem>
305
+ <PaginationPrevious href="#" />
306
+ </PaginationItem>
307
+ <PaginationItem>
308
+ <PaginationNext href="#" />
309
+ </PaginationItem>
310
+ </PaginationContent>
311
+ </Pagination>
312
+ ```
313
+
314
+ ### Con Información de Página
315
+
316
+ ```tsx
317
+ <div className="space-y-4">
318
+ <div className="flex items-center justify-between text-sm text-muted-foreground">
319
+ <span>Showing 1-10 of 250 results</span>
320
+ <span>Page 2 of 25</span>
321
+ </div>
322
+
323
+ <Pagination>
324
+ <PaginationContent>
325
+ <PaginationItem>
326
+ <PaginationPrevious href="#" />
327
+ </PaginationItem>
328
+ <PaginationItem>
329
+ <PaginationLink href="#">1</PaginationLink>
330
+ </PaginationItem>
331
+ <PaginationItem>
332
+ <PaginationLink href="#" isActive>
333
+ 2
334
+ </PaginationLink>
335
+ </PaginationItem>
336
+ <PaginationItem>
337
+ <PaginationLink href="#">3</PaginationLink>
338
+ </PaginationItem>
339
+ <PaginationItem>
340
+ <PaginationEllipsis />
341
+ </PaginationItem>
342
+ <PaginationItem>
343
+ <PaginationLink href="#">25</PaginationLink>
344
+ </PaginationItem>
345
+ <PaginationItem>
346
+ <PaginationNext href="#" />
347
+ </PaginationItem>
348
+ </PaginationContent>
349
+ </Pagination>
350
+ </div>
351
+ ```
352
+
353
+ ### Interactivo (Con Estado)
354
+
355
+ ```tsx
356
+ import { useState } from "react";
357
+
358
+ function App() {
359
+ const [currentPage, setCurrentPage] = useState(5);
360
+ const totalPages = 20;
361
+
362
+ const generatePageNumbers = () => {
363
+ const pages = [];
364
+
365
+ // Always show first page
366
+ pages.push(1);
367
+
368
+ // Add ellipsis if there's a gap
369
+ if (currentPage > 4) {
370
+ pages.push(-1); // -1 represents ellipsis
371
+ }
372
+
373
+ // Show pages around current page
374
+ const start = Math.max(2, currentPage - 1);
375
+ const end = Math.min(totalPages - 1, currentPage + 1);
376
+
377
+ for (let i = start; i <= end; i++) {
378
+ if (i !== 1 && i !== totalPages) {
379
+ pages.push(i);
380
+ }
381
+ }
382
+
383
+ // Add ellipsis if there's a gap
384
+ if (currentPage < totalPages - 3) {
385
+ pages.push(-2); // -2 represents ellipsis
386
+ }
387
+
388
+ // Always show last page if more than 1 page
389
+ if (totalPages > 1) {
390
+ pages.push(totalPages);
391
+ }
392
+
393
+ return pages;
394
+ };
395
+
396
+ const pages = generatePageNumbers();
397
+
398
+ const handlePageClick = (page: number) => {
399
+ setCurrentPage(page);
400
+ };
401
+
402
+ const handlePrevious = () => {
403
+ if (currentPage > 1) {
404
+ setCurrentPage(currentPage - 1);
405
+ }
406
+ };
407
+
408
+ const handleNext = () => {
409
+ if (currentPage < totalPages) {
410
+ setCurrentPage(currentPage + 1);
411
+ }
412
+ };
413
+
414
+ return (
415
+ <div className="space-y-4">
416
+ <p className="text-center text-sm text-muted-foreground">
417
+ Page {currentPage} of {totalPages}
418
+ </p>
419
+
420
+ <Pagination>
421
+ <PaginationContent>
422
+ <PaginationItem>
423
+ <PaginationPrevious
424
+ href="#"
425
+ onClick={(e) => {
426
+ e.preventDefault();
427
+ handlePrevious();
428
+ }}
429
+ className={
430
+ currentPage === 1 ? "pointer-events-none opacity-50" : ""
431
+ }
432
+ />
433
+ </PaginationItem>
434
+
435
+ {pages.map((page, index) => (
436
+ <PaginationItem key={index}>
437
+ {page < 0 ? (
438
+ <PaginationEllipsis />
439
+ ) : (
440
+ <PaginationLink
441
+ href="#"
442
+ isActive={page === currentPage}
443
+ onClick={(e) => {
444
+ e.preventDefault();
445
+ handlePageClick(page);
446
+ }}
447
+ >
448
+ {page}
449
+ </PaginationLink>
450
+ )}
451
+ </PaginationItem>
452
+ ))}
453
+
454
+ <PaginationItem>
455
+ <PaginationNext
456
+ href="#"
457
+ onClick={(e) => {
458
+ e.preventDefault();
459
+ handleNext();
460
+ }}
461
+ className={
462
+ currentPage === totalPages
463
+ ? "pointer-events-none opacity-50"
464
+ : ""
465
+ }
466
+ />
467
+ </PaginationItem>
468
+ </PaginationContent>
469
+ </Pagination>
470
+ </div>
471
+ );
472
+ }
473
+ ```
474
+
475
+ ### Tamaños Personalizados
476
+
477
+ ```tsx
478
+ {
479
+ /* Small */
480
+ }
481
+ <Pagination>
482
+ <PaginationContent className="gap-0.5">
483
+ <PaginationItem>
484
+ <PaginationPrevious href="#" className="h-8 px-2 text-xs" />
485
+ </PaginationItem>
486
+ <PaginationItem>
487
+ <PaginationLink href="#" className="h-8 w-8 text-xs">
488
+ 1
489
+ </PaginationLink>
490
+ </PaginationItem>
491
+ <PaginationItem>
492
+ <PaginationLink href="#" isActive className="h-8 w-8 text-xs">
493
+ 2
494
+ </PaginationLink>
495
+ </PaginationItem>
496
+ <PaginationItem>
497
+ <PaginationNext href="#" className="h-8 px-2 text-xs" />
498
+ </PaginationItem>
499
+ </PaginationContent>
500
+ </Pagination>;
501
+
502
+ {
503
+ /* Large */
504
+ }
505
+ <Pagination>
506
+ <PaginationContent className="gap-2">
507
+ <PaginationItem>
508
+ <PaginationPrevious href="#" className="h-12 px-4 text-base" />
509
+ </PaginationItem>
510
+ <PaginationItem>
511
+ <PaginationLink href="#" className="h-12 w-12 text-base">
512
+ 1
513
+ </PaginationLink>
514
+ </PaginationItem>
515
+ <PaginationItem>
516
+ <PaginationLink href="#" isActive className="h-12 w-12 text-base">
517
+ 2
518
+ </PaginationLink>
519
+ </PaginationItem>
520
+ <PaginationItem>
521
+ <PaginationNext href="#" className="h-12 px-4 text-base" />
522
+ </PaginationItem>
523
+ </PaginationContent>
524
+ </Pagination>;
525
+ ```
526
+
527
+ ## Casos de Uso Comunes
528
+
529
+ **Tables**: Paginación de tablas con muchas filas
530
+ **Lists**: Listas largas de items (productos, usuarios, posts)
531
+ **Search results**: Resultados de búsqueda paginados
532
+ **Galleries**: Galerías de imágenes o archivos
533
+ **Admin panels**: Dashboards con data paginada
534
+ **API results**: Navegación de resultados de API con offset/limit
535
+
536
+ ## Estados y Data Attributes
537
+
538
+ ### PaginationLink
539
+
540
+ - **Active**: `isActive` → variant outline, `aria-current="page"`
541
+ - **Inactive**: variant ghost
542
+
543
+ ### Disabled (Previous/Next)
544
+
545
+ No hay prop disabled nativa, se simula con:
546
+
547
+ ```tsx
548
+ className = "pointer-events-none opacity-50";
549
+ ```
550
+
551
+ ## Estilos Base
552
+
553
+ ### Pagination (Root)
554
+
555
+ - **Layout**: `mx-auto flex w-full justify-center`
556
+ - **Semantic**: `<nav role="navigation" aria-label="pagination">`
557
+
558
+ ### PaginationContent
559
+
560
+ - **Layout**: `flex flex-row items-center gap-1`
561
+
562
+ ### PaginationLink
563
+
564
+ - **Size default**: `size="icon"` (h-9 w-9)
565
+ - **Variants**: ghost (inactive), outline (active)
566
+
567
+ ### PaginationPrevious/Next
568
+
569
+ - **Size**: `size="default"`
570
+ - **Padding**: `px-2.5`
571
+ - **Responsive**: Texto oculto en mobile (`hidden sm:block`)
572
+ - **Gap**: `gap-1` entre icono y texto
573
+
574
+ ### PaginationEllipsis
575
+
576
+ - **Size**: `size-9`
577
+ - **Icon**: MoreHorizontal `size-4`
578
+ - **Layout**: `flex items-center justify-center`
579
+ - **ARIA**: `aria-hidden`
580
+
581
+ ## Responsive
582
+
583
+ - **Mobile**: Previous/Next solo muestran icono
584
+ - **Desktop (sm+)**: Previous/Next muestran icono + texto
585
+
586
+ ## Accesibilidad
587
+
588
+ - ✅ **Semantic**: `<nav role="navigation" aria-label="pagination">`
589
+ - ✅ **Current page**: `aria-current="page"` en página activa
590
+ - ✅ **Screen readers**: Ellipsis tiene `<span className="sr-only">More pages</span>`
591
+ - ✅ **Keyboard**: Navegación con Tab, activación con Enter/Space
592
+ - ✅ **Labels**: Previous/Next tienen `aria-label` descriptivo
593
+ - ⚠️ **Disabled**: Usa `pointer-events-none opacity-50` + previene click en handler
594
+
595
+ ## Notas de Implementación
596
+
597
+ - **Links**: PaginationLink es `<a>` no `<button>`, usa Button styles
598
+ - **Icons**: ChevronLeft, ChevronRight, MoreHorizontal de lucide-react
599
+ - **Responsive text**: Previous/Next usan `hidden sm:block` en texto
600
+ - **No state**: Componente stateless, maneja estado externamente
601
+ - **Ellipsis logic**: Representación negativa (-1, -2) común para identificar ellipsis
602
+ - **Disabled**: No hay prop disabled, usa className manual
603
+ - **Centering**: Root tiene `mx-auto justify-center`
604
+
605
+ ## Algoritmo de Generación de Páginas
606
+
607
+ Patrón común para mostrar páginas con ellipsis:
608
+
609
+ ```tsx
610
+ const generatePageNumbers = (current: number, total: number) => {
611
+ const pages = [];
612
+
613
+ // Siempre primera página
614
+ pages.push(1);
615
+
616
+ // Ellipsis izquierda si hay gap
617
+ if (current > 4) pages.push(-1);
618
+
619
+ // Páginas alrededor de current
620
+ const start = Math.max(2, current - 1);
621
+ const end = Math.min(total - 1, current + 1);
622
+ for (let i = start; i <= end; i++) {
623
+ if (i !== 1 && i !== total) pages.push(i);
624
+ }
625
+
626
+ // Ellipsis derecha si hay gap
627
+ if (current < total - 3) pages.push(-2);
628
+
629
+ // Siempre última página
630
+ if (total > 1) pages.push(total);
631
+
632
+ return pages;
633
+ };
634
+ ```
635
+
636
+ ## Troubleshooting
637
+
638
+ **Previous/Next no se deshabilitan**: No hay prop disabled, usa `className="pointer-events-none opacity-50"` y previene click en handler
639
+ **Active no se ve**: Verifica `isActive` prop y que solo una página lo tenga
640
+ **Texto Previous/Next no se ve en mobile**: Comportamiento esperado, usa `hidden sm:block`
641
+ **Ellipsis clickeable**: Ellipsis no debe ser clickeable, es `<span>` no link
642
+ **Spacing inconsistente**: PaginationContent tiene `gap-1`, ajusta con className
643
+ **No centrado**: Root tiene `justify-center`, override con `className="justify-start"` si necesario
644
+ **Links no funcionan**: PaginationLink usa `<a>`, asegúrate de pasar `href` o `onClick`
645
+ **Too many pages**: Usa ellipsis y lógica de generación de páginas para mostrar subset
646
+
647
+ ## Referencias
648
+
649
+ - **shadcn/ui Pagination**: <https://ui.shadcn.com/docs/components/pagination>
650
+ - **WAI-ARIA Pagination**: <https://www.w3.org/WAI/ARIA/apg/patterns/pagination/>