@reliability-design/web 1.4.6 → 1.4.7

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 (146) hide show
  1. package/CHANGELOG.md +211 -49
  2. package/dist/components/rel-accordion/README.md +132 -132
  3. package/dist/components/rel-alert/README.md +145 -141
  4. package/dist/components/rel-autocomplete/README.md +156 -61
  5. package/dist/components/rel-avatar/README.md +116 -130
  6. package/dist/components/rel-badge/README.md +98 -93
  7. package/dist/components/rel-breadcrumb/README.md +96 -102
  8. package/dist/components/rel-button/README.md +160 -130
  9. package/dist/components/rel-calendar/README.md +109 -109
  10. package/dist/components/rel-card/README.md +75 -94
  11. package/dist/components/rel-cardmedia/README.md +100 -127
  12. package/dist/components/rel-carousel/README.md +184 -166
  13. package/dist/components/rel-checkbox/README.md +93 -75
  14. package/dist/components/rel-chip/README.md +132 -121
  15. package/dist/components/rel-container/README.md +107 -99
  16. package/dist/components/rel-date-picker/README.md +200 -289
  17. package/dist/components/rel-divider/README.md +78 -100
  18. package/dist/components/rel-drawer/README.md +187 -200
  19. package/dist/components/rel-kbd/README.md +141 -151
  20. package/dist/components/rel-menu/README.md +178 -151
  21. package/dist/components/rel-menubar/README.md +218 -329
  22. package/dist/components/rel-otp/README.md +170 -440
  23. package/dist/components/rel-pagination/README.md +100 -424
  24. package/dist/components/rel-popover/README.md +203 -568
  25. package/dist/components/rel-progress/README.md +88 -110
  26. package/dist/components/rel-radio/README.md +131 -138
  27. package/dist/components/rel-range-picker/README.md +162 -0
  28. package/dist/components/rel-resizable/README.md +199 -140
  29. package/dist/components/rel-segmented-button/README.md +155 -141
  30. package/dist/components/rel-select/README.md +154 -93
  31. package/dist/components/rel-sheet/README.md +168 -224
  32. package/dist/components/rel-skeleton/README.md +103 -0
  33. package/dist/components/rel-slider/README.md +130 -135
  34. package/dist/components/rel-snackbar/README.md +162 -134
  35. package/dist/components/rel-stepper/README.md +158 -160
  36. package/dist/components/rel-switch/README.md +108 -102
  37. package/dist/components/rel-tab/README.md +171 -163
  38. package/dist/components/rel-textfield/README.md +159 -69
  39. package/dist/components/rel-time-picker/README.md +122 -157
  40. package/dist/components/rel-toast/README.md +157 -148
  41. package/dist/components/rel-tooltip/README.md +108 -111
  42. package/dist/components/rel-upload/README.md +220 -0
  43. package/dist/index.d.mts +1147 -340
  44. package/dist/index.d.ts +1147 -340
  45. package/dist/index.js +3451 -3163
  46. package/dist/index.js.map +1 -1
  47. package/dist/index.mjs +3416 -3118
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/styles/vars.css +877 -866
  50. package/dist/{vars-XNMTSRVN.css → vars-JHTUGNRG.css} +877 -866
  51. package/package.json +3 -2
  52. package/dist/components/rel-accordion/rel-accordion.ts +0 -336
  53. package/dist/components/rel-alert/rel-alert.ts +0 -305
  54. package/dist/components/rel-autocomplete/rel-autocomplete.ts +0 -720
  55. package/dist/components/rel-avatar/rel-avatar.ts +0 -142
  56. package/dist/components/rel-badge/rel-badge.ts +0 -175
  57. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +0 -106
  58. package/dist/components/rel-button/rel-button.ts +0 -560
  59. package/dist/components/rel-calendar/index.ts +0 -1
  60. package/dist/components/rel-calendar/rel-calendar.ts +0 -565
  61. package/dist/components/rel-card/rel-card.ts +0 -88
  62. package/dist/components/rel-cardmedia/rel-cardmedia.ts +0 -88
  63. package/dist/components/rel-carousel/index.ts +0 -1
  64. package/dist/components/rel-carousel/rel-carousel.ts +0 -723
  65. package/dist/components/rel-chart/README.md +0 -286
  66. package/dist/components/rel-chart/index.ts +0 -1
  67. package/dist/components/rel-chart/rel-chart.ts +0 -754
  68. package/dist/components/rel-checkbox/rel-checkbox.ts +0 -382
  69. package/dist/components/rel-chip/rel-chip.ts +0 -483
  70. package/dist/components/rel-container/rel-container.ts +0 -95
  71. package/dist/components/rel-date-picker/date-format.test.ts +0 -43
  72. package/dist/components/rel-date-picker/date-format.ts +0 -47
  73. package/dist/components/rel-date-picker/date-parse.test.ts +0 -116
  74. package/dist/components/rel-date-picker/date-parse.ts +0 -178
  75. package/dist/components/rel-date-picker/index.ts +0 -1
  76. package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1676
  77. package/dist/components/rel-divider/rel-divider.ts +0 -54
  78. package/dist/components/rel-drawer/index.ts +0 -1
  79. package/dist/components/rel-drawer/rel-drawer-footer.ts +0 -27
  80. package/dist/components/rel-drawer/rel-drawer.ts +0 -607
  81. package/dist/components/rel-kbd/rel-kbd.ts +0 -188
  82. package/dist/components/rel-layout/rel-layout.ts +0 -49
  83. package/dist/components/rel-menu/rel-menu.ts +0 -541
  84. package/dist/components/rel-menubar/index.ts +0 -2
  85. package/dist/components/rel-menubar/rel-menubar-menu.css +0 -3
  86. package/dist/components/rel-menubar/rel-menubar-menu.ts +0 -17
  87. package/dist/components/rel-menubar/rel-menubar.ts +0 -777
  88. package/dist/components/rel-nav-menu/README.md +0 -289
  89. package/dist/components/rel-nav-menu/index.ts +0 -3
  90. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +0 -243
  91. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +0 -72
  92. package/dist/components/rel-nav-menu/rel-nav-menu.ts +0 -270
  93. package/dist/components/rel-navbar/README.md +0 -126
  94. package/dist/components/rel-navbar/rel-navbar.ts +0 -105
  95. package/dist/components/rel-otp/index.ts +0 -1
  96. package/dist/components/rel-otp/rel-otp.ts +0 -527
  97. package/dist/components/rel-pagination/index.ts +0 -1
  98. package/dist/components/rel-pagination/rel-pagination.ts +0 -522
  99. package/dist/components/rel-popover/index.ts +0 -2
  100. package/dist/components/rel-popover/rel-popover-content.ts +0 -81
  101. package/dist/components/rel-popover/rel-popover.ts +0 -475
  102. package/dist/components/rel-progress/rel-progress.ts +0 -234
  103. package/dist/components/rel-radio/rel-radio.ts +0 -481
  104. package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1688
  105. package/dist/components/rel-resizable/index.ts +0 -3
  106. package/dist/components/rel-resizable/rel-resizable-group.ts +0 -405
  107. package/dist/components/rel-resizable/rel-resizable-handle.ts +0 -150
  108. package/dist/components/rel-resizable/rel-resizable-panel.ts +0 -58
  109. package/dist/components/rel-segmented-button/rel-segmented-button.ts +0 -217
  110. package/dist/components/rel-select/rel-select.ts +0 -1416
  111. package/dist/components/rel-sheet/rel-sheet.ts +0 -610
  112. package/dist/components/rel-sidebar/README.md +0 -209
  113. package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1191
  114. package/dist/components/rel-skeleton/rel-skeleton.ts +0 -143
  115. package/dist/components/rel-slider/rel-slider.ts +0 -673
  116. package/dist/components/rel-snackbar/rel-snackbar.ts +0 -329
  117. package/dist/components/rel-stepper/rel-stepper.ts +0 -567
  118. package/dist/components/rel-switch/rel-switch.ts +0 -199
  119. package/dist/components/rel-tab/rel-tab.ts +0 -264
  120. package/dist/components/rel-table/README.md +0 -178
  121. package/dist/components/rel-table/rel-table-body.ts +0 -22
  122. package/dist/components/rel-table/rel-table-caption.ts +0 -30
  123. package/dist/components/rel-table/rel-table-cell.ts +0 -43
  124. package/dist/components/rel-table/rel-table-footer.ts +0 -24
  125. package/dist/components/rel-table/rel-table-head.ts +0 -47
  126. package/dist/components/rel-table/rel-table-header.ts +0 -22
  127. package/dist/components/rel-table/rel-table-row.ts +0 -37
  128. package/dist/components/rel-table/rel-table.ts +0 -62
  129. package/dist/components/rel-textfield/rel-textfield.ts +0 -1054
  130. package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1482
  131. package/dist/components/rel-time-picker/time-parse.test.ts +0 -67
  132. package/dist/components/rel-time-picker/time-parse.ts +0 -85
  133. package/dist/components/rel-toast/rel-toast.ts +0 -206
  134. package/dist/components/rel-tooltip/rel-tooltip.ts +0 -193
  135. package/dist/components/rel-topbar/rel-topbar-actions.ts +0 -27
  136. package/dist/components/rel-topbar/rel-topbar-brand.ts +0 -54
  137. package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +0 -69
  138. package/dist/components/rel-topbar/rel-topbar-dropdown.ts +0 -31
  139. package/dist/components/rel-topbar/rel-topbar-item.ts +0 -324
  140. package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +0 -27
  141. package/dist/components/rel-topbar/rel-topbar-profile.ts +0 -243
  142. package/dist/components/rel-topbar/rel-topbar-utilities.ts +0 -27
  143. package/dist/components/rel-topbar/rel-topbar.ts +0 -446
  144. package/dist/components/rel-upload/UPLOAD-DESIGN-CHANGES.md +0 -134
  145. package/dist/components/rel-upload/rel-upload-actions.ts +0 -163
  146. package/dist/components/rel-upload/rel-upload.ts +0 -968
@@ -1,424 +1,100 @@
1
- # rel-pagination
2
-
3
- A flexible pagination component with smart ellipsis rendering, keyboard navigation, and support for both controlled and uncontrolled modes.
4
-
5
- ## What It Is
6
-
7
- The pagination component provides navigation through multiple pages of content. It intelligently renders page numbers with ellipsis to handle large page counts, supports Previous/Next controls, and can render either as buttons or links.
8
-
9
- ## Basic Usage
10
-
11
- ```html
12
- <!-- Uncontrolled mode (manages its own state) -->
13
- <rel-pagination totalPages="10" defaultPage="1"></rel-pagination>
14
-
15
- <!-- Controlled mode (external state management) -->
16
- <rel-pagination totalPages="10" page="5"></rel-pagination>
17
- ```
18
-
19
- ## API Reference
20
-
21
- ### Attributes / Properties
22
-
23
- | Attribute | Type | Default | Description |
24
- |-----------|------|---------|-------------|
25
- | `page` | number | undefined | Current page (1-based). When set, enables controlled mode |
26
- | `defaultPage` | number | 1 | Initial page for uncontrolled mode |
27
- | `totalPages` | number | required | Total number of pages |
28
- | `siblingCount` | number | 1 | Number of pages to show around current page |
29
- | `boundaryCount` | number | 1 | Number of pages to show at start/end |
30
- | `disabled` | boolean | false | Disables all interactions |
31
- | `density` | "comfortable" \| "compact" | "comfortable" | Spacing density |
32
- | `variant` | "default" \| "icons" | "default" | Controls visual style |
33
- | `hrefTemplate` | string | "" | Template for href links (e.g., "/page/{page}") |
34
- | `ariaLabel` | string | "Pagination" | ARIA label for the nav element |
35
-
36
- ### Events
37
-
38
- **rel-change**
39
-
40
- Emitted when user selects a new page.
41
-
42
- ```typescript
43
- detail: { page: number }
44
- ```
45
-
46
- **Example:**
47
- ```javascript
48
- const pagination = document.querySelector('rel-pagination');
49
- pagination.addEventListener('rel-change', (e) => {
50
- console.log('New page:', e.detail.page);
51
- });
52
- ```
53
-
54
- ## Controlled vs Uncontrolled
55
-
56
- ### Uncontrolled Mode
57
-
58
- Component manages its own internal state. Use `defaultPage` to set initial page.
59
-
60
- ```html
61
- <rel-pagination totalPages="10" defaultPage="2"></rel-pagination>
62
- ```
63
-
64
- ```javascript
65
- pagination.addEventListener('rel-change', (e) => {
66
- // Component has already updated its internal page
67
- console.log('Changed to page:', e.detail.page);
68
- });
69
- ```
70
-
71
- ### Controlled Mode
72
-
73
- External code manages the page state. Set the `page` attribute.
74
-
75
- ```html
76
- <rel-pagination id="controlled-pagination" totalPages="10" page="5"></rel-pagination>
77
- ```
78
-
79
- ```javascript
80
- let currentPage = 5;
81
- const pagination = document.getElementById('controlled-pagination');
82
-
83
- pagination.addEventListener('rel-change', (e) => {
84
- // Update your external state
85
- currentPage = e.detail.page;
86
- // Update the component
87
- pagination.page = currentPage;
88
-
89
- // Fetch new data, etc.
90
- fetchData(currentPage);
91
- });
92
- ```
93
-
94
- ## Ellipsis Logic
95
-
96
- The component intelligently renders page numbers with ellipsis based on `siblingCount` and `boundaryCount`:
97
-
98
- ### Examples
99
-
100
- **totalPages=10, page=5, siblingCount=1, boundaryCount=1:**
101
- ```
102
- 1 … 4 5 6 … 10
103
- ```
104
-
105
- **totalPages=10, page=2, siblingCount=1, boundaryCount=1:**
106
- ```
107
- 1 2 3 … 10
108
- ```
109
-
110
- **totalPages=10, page=9, siblingCount=1, boundaryCount=1:**
111
- ```
112
- 1 … 8 9 10
113
- ```
114
-
115
- **totalPages=5, page=3 (no ellipsis needed):**
116
- ```
117
- 1 2 3 4 5
118
- ```
119
-
120
- ### How It Works
121
-
122
- 1. **Boundary Pages**: Always shows `boundaryCount` pages at start and end
123
- 2. **Sibling Pages**: Shows `siblingCount` pages on each side of current page
124
- 3. **Ellipsis**: Inserted when there's a gap between visible page ranges
125
-
126
- ## Variants
127
-
128
- ### Default Variant
129
-
130
- Shows text labels for Previous/Next buttons.
131
-
132
- ```html
133
- <rel-pagination totalPages="10" variant="default"></rel-pagination>
134
- <!-- Renders: [Previous] [1] [2] ... [10] [Next] -->
135
- ```
136
-
137
- ### Icons Variant
138
-
139
- Shows chevron icons instead of text labels.
140
-
141
- ```html
142
- <rel-pagination totalPages="10" variant="icons"></rel-pagination>
143
- <!-- Renders: [<] [1] [2] ... [10] [>] -->
144
- ```
145
-
146
- ## Density
147
-
148
- ### Comfortable (Default)
149
-
150
- Standard spacing with larger touch targets.
151
-
152
- ```html
153
- <rel-pagination totalPages="10" density="comfortable"></rel-pagination>
154
- ```
155
-
156
- - Height: 40px
157
- - Font size: sm
158
- - Padding: sm
159
-
160
- ### Compact
161
-
162
- Tighter spacing for dense layouts.
163
-
164
- ```html
165
- <rel-pagination totalPages="10" density="compact"></rel-pagination>
166
- ```
167
-
168
- - Height: 32px
169
- - Font size: xs
170
- - Padding: xs
171
-
172
- ## Link Mode
173
-
174
- Instead of buttons, render page items as links by providing an `hrefTemplate`.
175
-
176
- ```html
177
- <rel-pagination
178
- totalPages="10"
179
- page="3"
180
- hrefTemplate="/docs?page={page}">
181
- </rel-pagination>
182
- ```
183
-
184
- The `{page}` placeholder is replaced with the page number:
185
- - Page 1 → `/docs?page=1`
186
- - Page 5 → `/docs?page=5`
187
-
188
- **Note**: Click events still emit `rel-change` events and prevent default navigation, allowing you to handle routing in JavaScript.
189
-
190
- ## Keyboard Navigation
191
-
192
- Full keyboard accessibility:
193
-
194
- | Key | Action |
195
- |-----|--------|
196
- | `Tab` / `Shift+Tab` | Navigate through page buttons and controls |
197
- | `Enter` | Activate focused button/link |
198
- | `Space` | Activate focused button/link |
199
-
200
- ## Accessibility
201
-
202
- The component follows ARIA best practices:
203
-
204
- ### Semantic HTML
205
- - Wrapped in `<nav>` with `role="navigation"`
206
- - Configurable `aria-label` (default: "Pagination")
207
-
208
- ### Page Buttons
209
- - Current page has `aria-current="page"`
210
- - Each button has descriptive `aria-label`:
211
- - "Go to page 1"
212
- - "Go to page 2"
213
- - etc.
214
-
215
- ### Controls
216
- - Previous button: `aria-label="Go to previous page"`
217
- - Next button: `aria-label="Go to next page"`
218
- - Disabled state reflected with `disabled` attribute or `aria-disabled`
219
-
220
- ### Focus Management
221
- - Visible focus indicators using focus-visible
222
- - Proper tab order through page numbers
223
-
224
- ## Styling Tokens
225
-
226
- The component uses design tokens from the Reliability Design System:
227
-
228
- ### Colors
229
- - `--rel-bg-surface` - Button/link background
230
- - `--rel-text-label` - Text color and active page background
231
- - `--rel-border-default` - Border color
232
- - `--rel-text-default` - Hover border color
233
- - `--rel-bg-neutral-elevated-1` - Hover background
234
- - `--rel-text-placeholder` - Ellipsis color
235
- - `--rel-bg-info` - Focus outline
236
-
237
- ### Typography
238
- - `--rel-fonts-font-family` - Font family (Poppins)
239
- - `--rel-fonts-weight-body-medium` - Default text weight
240
- - `--rel-fonts-weight-body-semibold` - Active page weight
241
- - `--rel-body-sm-regular-font-size` - Comfortable mode font size
242
- - `--rel-body-xs-regular-font-size` - Compact mode font size
243
-
244
- ### Spacing
245
- - `--rel-spacing-3xs` (2px) - Compact gap
246
- - `--rel-spacing-2xs` (4px) - Comfortable gap
247
- - `--rel-spacing-xs` (8px) - Compact padding
248
- - `--rel-spacing-sm` (12px) - Comfortable padding
249
-
250
- ### Borders
251
- - `--rel-stroke-sm` (1px) - Border width
252
- - `--rel-border-radius-sm` (8px) - Border radius
253
-
254
- ## Complete Examples
255
-
256
- ### Simple Pagination
257
-
258
- ```html
259
- <rel-pagination totalPages="10" defaultPage="1"></rel-pagination>
260
- ```
261
-
262
- ### With Event Handling
263
-
264
- ```html
265
- <rel-pagination id="my-pagination" totalPages="50" defaultPage="1"></rel-pagination>
266
-
267
- <script>
268
- const pagination = document.getElementById('my-pagination');
269
-
270
- pagination.addEventListener('rel-change', (e) => {
271
- console.log('Loading page:', e.detail.page);
272
- fetchPageData(e.detail.page);
273
- });
274
-
275
- function fetchPageData(page) {
276
- // Your data fetching logic
277
- }
278
- </script>
279
- ```
280
-
281
- ### Controlled with More Siblings
282
-
283
- ```html
284
- <rel-pagination
285
- id="controlled"
286
- totalPages="100"
287
- page="50"
288
- siblingCount="2"
289
- boundaryCount="2">
290
- </rel-pagination>
291
-
292
- <script>
293
- let currentPage = 50;
294
- const pagination = document.getElementById('controlled');
295
-
296
- pagination.addEventListener('rel-change', (e) => {
297
- currentPage = e.detail.page;
298
- pagination.page = currentPage;
299
- updateContent(currentPage);
300
- });
301
- </script>
302
- ```
303
-
304
- ### Compact with Icons
305
-
306
- ```html
307
- <rel-pagination
308
- totalPages="25"
309
- defaultPage="1"
310
- density="compact"
311
- variant="icons"
312
- siblingCount="1"
313
- boundaryCount="1">
314
- </rel-pagination>
315
- ```
316
-
317
- ### Link Mode for SEO
318
-
319
- ```html
320
- <rel-pagination
321
- totalPages="20"
322
- page="5"
323
- hrefTemplate="/products?page={page}"
324
- siblingCount="1">
325
- </rel-pagination>
326
-
327
- <script>
328
- const pagination = document.querySelector('rel-pagination');
329
-
330
- pagination.addEventListener('rel-change', (e) => {
331
- // Handle client-side navigation
332
- navigateToPage(e.detail.page);
333
- });
334
-
335
- function navigateToPage(page) {
336
- // Your routing logic (e.g., History API)
337
- history.pushState({}, '', `/products?page=${page}`);
338
- loadPageData(page);
339
- }
340
- </script>
341
- ```
342
-
343
- ## Edge Cases
344
-
345
- ### Few Pages (No Ellipsis)
346
-
347
- When total pages is small, all pages are shown:
348
-
349
- ```html
350
- <rel-pagination totalPages="5" page="3"></rel-pagination>
351
- <!-- Renders: [Previous] [1] [2] [3] [4] [5] [Next] -->
352
- ```
353
-
354
- ### First Page
355
-
356
- Previous button is disabled:
357
-
358
- ```html
359
- <rel-pagination totalPages="10" page="1"></rel-pagination>
360
- <!-- [Previous - disabled] [1] [2] [3] ... [10] [Next] -->
361
- ```
362
-
363
- ### Last Page
364
-
365
- Next button is disabled:
366
-
367
- ```html
368
- <rel-pagination totalPages="10" page="10"></rel-pagination>
369
- <!-- [Previous] [1] ... [8] [9] [10] [Next - disabled] -->
370
- ```
371
-
372
- ### Disabled State
373
-
374
- All interactions disabled:
375
-
376
- ```html
377
- <rel-pagination totalPages="10" page="5" disabled></rel-pagination>
378
- ```
379
-
380
- ### Very Large Page Counts
381
-
382
- Page buttons auto-widen to fit their number (min-width 40px). Far first/last
383
- buttons with numbers ≥ 10,000 are abbreviated so the control stays compact:
384
- `10000` → `10k`, `368178` → `368k`, `1234567` → `1.2M`. The exact page number
385
- is preserved in the button's `aria-label` and `title` (hover tooltip). The
386
- current page and its immediate neighbors always render exact — abbreviating
387
- them would make adjacent pages indistinguishable.
388
-
389
- ```html
390
- <rel-pagination totalPages="368178" page="7"></rel-pagination>
391
- <!-- [<] [1] ... [6] [7] [8] ... [368k] [>] -->
392
- ```
393
-
394
- ## Browser Support
395
-
396
- Compatible with all modern browsers supporting:
397
- - Web Components (Custom Elements v1)
398
- - Shadow DOM
399
- - ES2020+ features
400
-
401
- ## Framework Integration
402
-
403
- Works seamlessly with:
404
- - Vanilla JavaScript
405
- - Angular
406
- - React (via wrapper)
407
- - Vue
408
- - Any framework supporting Web Components
409
-
410
- ## Best Practices
411
-
412
- 1. **Use controlled mode** for complex state management (Redux, Vuex, etc.)
413
- 2. **Use uncontrolled mode** for simple cases where component can manage its own state
414
- 3. **Adjust siblingCount** based on available space (mobile: 0-1, desktop: 1-2)
415
- 4. **Use compact density** on mobile or in sidebars
416
- 5. **Use link mode** when SEO matters (server-rendered pagination)
417
- 6. **Always handle rel-change events** to update your data/UI
418
-
419
- ## Performance Notes
420
-
421
- - Ellipsis calculation is optimized and runs only when page/total changes
422
- - No unnecessary re-renders in controlled mode
423
- - Minimal DOM elements (only visible pages + controls)
424
- - Efficient event handling with no memory leaks
1
+ # rel-pagination
2
+
3
+ Page navigation implementing the Figma "Pagination" component in its three **Type** layouts: `extended` (prev/next ghost buttons around numbered page chips, with a windowed ellipsis for long ranges), `compact` (prev/next around a "Page X of Y" readout) and `count-text` (a "1–10 of 50" item range with the nav on the right). Use it under tables, lists and search results that load one page at a time. It never fetches data or reads the URL: listen for `rel-change` and load the requested page yourself.
4
+
5
+ ## Usage
6
+
7
+ ```html
8
+ <!-- Extended (default): numbered pages, uncontrolled -->
9
+ <rel-pagination totalPages="12" defaultPage="3"></rel-pagination>
10
+
11
+ <!-- Extended with the "Viewing page X of Y" caption -->
12
+ <rel-pagination totalPages="20" showLabel></rel-pagination>
13
+
14
+ <!-- Compact: prev / "Page X of Y" / next -->
15
+ <rel-pagination type="compact" totalPages="8"></rel-pagination>
16
+
17
+ <!-- Count-text: item range computed from totalItems and perPage -->
18
+ <rel-pagination type="count-text" totalItems="137" perPage="25"></rel-pagination>
19
+
20
+ <!-- Controlled: the parent owns the page -->
21
+ <rel-pagination id="results" page="1" totalPages="40" ariaLabel="Search results pagination"></rel-pagination>
22
+ <script>
23
+ const pager = document.getElementById('results');
24
+ pager.addEventListener('rel-change', (e) => {
25
+ loadResults(e.detail.page).then(() => {
26
+ pager.page = e.detail.page; // commit once the data is in
27
+ });
28
+ });
29
+ </script>
30
+
31
+ <!-- Disabled while loading -->
32
+ <rel-pagination totalPages="12" disabled></rel-pagination>
33
+ ```
34
+
35
+ <!-- readme-gen:start -->
36
+
37
+ <!-- Generated from rel-pagination.ts — do not edit; run readme-generate.mjs -->
38
+
39
+ ## API
40
+
41
+ ### Attributes / Properties
42
+
43
+ | Property | Attribute | Type | Default | Description |
44
+ | --- | --- | --- | --- | --- |
45
+ | `type` | `type` | `"extended" \| "compact" \| "count-text"` | `"extended"` | Figma "Type": `extended` = prev/next + numbered page buttons (auto-collapses to compact under 480px container width), `compact` = prev/next + "Page X of Y", `count-text` = "start–end of total" item range + prev/next around the current page number. Reflected. |
46
+ | `page` | `page` | `number` | `undefined` | Controlled current page (1-based). When set, the element only emits `rel-change` and waits for the parent to update `page`; leave unset for uncontrolled behaviour. |
47
+ | `defaultPage` | `defaultpage` | `number` | `1` | Starting page for uncontrolled use (ignored when `page` is set). Attribute `defaultPage`, also read once as `default-page` on connect. |
48
+ | `totalPages` | `totalpages` | `number` | `0` | Total number of pages. `0` (the default) lets `totalItems` / `perPage` compute the page count instead. Attribute `totalPages`, also read once as `total-pages` on connect. |
49
+ | `totalItems` | `totalitems` | `number` | `0` | Total item count; with `perPage` it computes the page count when `totalPages` is `0` and is the "of N" figure in the count-text readout. Attribute `totalItems`, also read once as `total-items` on connect. |
50
+ | `perPage` | `perpage` | `number` | `10` | Items per page, used to compute the page count from `totalItems` and the "start–end" range in the count-text readout. Attribute `perPage`, also read once as `per-page` on connect. |
51
+ | `showLabel` | `showlabel` | `boolean` | `false` | Shows a "Viewing page X of Y" caption under the extended layout (ignored by the other types). |
52
+ | `disabled` | `disabled` | `boolean` | `false` | Dims the whole control to 50% opacity, shows a `not-allowed` cursor and ignores every page change. Reflected. |
53
+ | `hrefTemplate` | `hreftemplate` | `string` | `""` | Reserved for link-mode pagination. Currently accepted but not rendered: every page control is a `<button>`, so navigate in your `rel-change` handler instead. |
54
+ | `ariaLabel` | `arialabel` | `string` | `"Pagination"` | Accessible name of the `role="navigation"` landmark (attribute `ariaLabel`). Set it when a page contains more than one pagination control. |
55
+
56
+ ## Events
57
+
58
+ | Event | Detail | Bubbles / composed | Description |
59
+ | --- | --- | --- | --- |
60
+ | `rel-change` | `{ page: newPage }` | bubbles / composed | Fired when the user picks another page (prev/next or a page number). Detail: `{ page: number }` (1-based). In controlled mode the parent must then set `page`. |
61
+
62
+ ## Slots
63
+
64
+ | Slot | Description |
65
+ | --- | --- |
66
+ | — | This element has no slots. |
67
+
68
+ ## CSS Parts
69
+
70
+ | Part | Description |
71
+ | --- | --- |
72
+ | `base` | The `role="navigation"` root of the extended layout (page buttons plus the optional "Viewing page" label). |
73
+ | `label` | The `role="navigation"` root row of the count-text layout (item-range text plus prev/next nav). |
74
+
75
+ <!-- readme-gen:end -->
76
+
77
+ ## Accessibility
78
+
79
+ - The control is a `role="navigation"` landmark named by `ariaLabel` (default "Pagination"); give each pager on a page a distinct name.
80
+ - Prev/next are native buttons labelled "Previous page" / "Next page"; they are disabled (not hidden) on the first / last page.
81
+ - Each page chip is a native button labelled "Page N" with `aria-current="page"` on the current one. Abbreviated first/last chips (e.g. "368k") keep the exact number in their `title`.
82
+ - Every page change is announced to screen readers as "Page N of M" via the shared live region.
83
+ - If a prev/next button becomes disabled while it has focus (you reached the first/last page), focus moves to the other nav button instead of being lost.
84
+
85
+ | Key | Action |
86
+ | --- | --- |
87
+ | `Tab` / `Shift+Tab` | Move between the prev button, page chips and next button |
88
+ | `Enter` / `Space` | Activate the focused button (native behaviour) |
89
+
90
+ No arrow-key navigation is implemented; all controls are regular tab stops.
91
+
92
+ ## Notes / Edge Cases
93
+
94
+ - **Attribute names.** The Lit attributes are the lowercase property names (`totalPages`, `defaultPage`, `totalItems`, `perPage`, `showLabel`, `hrefTemplate`, `ariaLabel` — HTML attributes are case-insensitive). The kebab-case forms `total-pages`, `default-page`, `total-items`, `per-page` and `page` are additionally read **once** when the element connects, so they work in static markup but not for later updates; set the property in code.
95
+ - **Page count.** `totalPages` wins when greater than `0`; otherwise the count is `ceil(totalItems / perPage)`. With neither set the element renders no page chips and both nav buttons disabled.
96
+ - **Controlled vs uncontrolled.** With `page` unset the element tracks the current page itself starting at `defaultPage`. Once `page` is set it stays on that page until the parent changes it — clicking only emits `rel-change`.
97
+ - **Ellipsis window.** Up to 7 pages render in full. Beyond that: the first 5 + last near the start, first + last 5 near the end, otherwise first, current ±1 and last, with `…` between. Far first/last chips abbreviate large numbers (`10000` → `10k`, `2500000` → `2.5M`); chips inside the window are never abbreviated.
98
+ - **Responsive.** `extended` uses a container query on the host: between 480px and 768px only first, last and current ±1 stay visible; under 480px the whole control swaps to the compact layout (media-query fallback for browsers without container queries). The `label` part belongs to the `count-text` layout, not to the "Viewing page" caption.
99
+ - **`hrefTemplate`** is accepted but currently unused — chips are always buttons, not links. Perform navigation in the `rel-change` handler.
100
+ - **`rel-change` is not fired** for the current page, out-of-range pages, or while `disabled`.