@ds-mo/ui 14.2.1 → 14.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.package-ready.json +1 -1
- package/dist/agent-patterns.json +1 -1
- package/dist/agent.json +174 -19
- package/dist/angular/ds-pagination.d.ts +19 -0
- package/dist/angular/ds-pagination.js +42 -0
- package/dist/angular/ds-select.d.ts +1 -1
- package/dist/angular/ds-select.js +3 -3
- package/dist/angular/ds-table.d.ts +4 -1
- package/dist/angular/ds-table.js +7 -4
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +1 -0
- package/dist/angular/proxies.d.ts +1 -0
- package/dist/angular/proxies.js +1 -0
- package/dist/components/ds-agent-questionnaire.js +1 -1
- package/dist/components/ds-agent-response.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-title.js +1 -1
- package/dist/components/ds-bar-workflow.js +1 -1
- package/dist/components/ds-bar-workflow.js.map +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-filter-menu.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-mobile-header.js +1 -1
- package/dist/components/ds-mobile-section-switcher.js +1 -1
- package/dist/components/ds-pagination.d.ts +11 -0
- package/dist/components/ds-pagination.js +2 -0
- package/dist/components/ds-pagination.js.map +1 -0
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-tool-header.js +1 -1
- package/dist/components/ds-panel-tool-search.js +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-radio.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-app.js +1 -1
- package/dist/components/ds-shell-page.js +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-swatch-picker.js +1 -1
- package/dist/components/ds-switch.js +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-table.js.map +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/index.d.ts +7 -0
- package/dist/components/{p-D2xWcVv6.js → p-B8q-6a03.js} +2 -2
- package/dist/components/{p-BXEiYoDE.js → p-BDXMXH_i.js} +2 -2
- package/dist/components/{p-DYzjeIAT.js → p-BHjw0x3L.js} +2 -2
- package/dist/components/{p-BOCrvs-v.js → p-Btxwp4lJ.js} +2 -2
- package/dist/components/{p-DD5OCVXx.js → p-C5TrNd31.js} +2 -2
- package/dist/components/{p-BDCrM8-1.js → p-CDF_nP74.js} +2 -2
- package/dist/components/{p-DJ_FsLCc.js → p-CKfdvOZ2.js} +2 -2
- package/dist/components/p-CRLRjtsc.js +2 -0
- package/dist/components/p-CRLRjtsc.js.map +1 -0
- package/dist/components/{p-CRjpqqAI.js → p-CW7ML-3h.js} +2 -2
- package/dist/components/{p-DZcFkqXw.js → p-CbqdWBAC.js} +2 -2
- package/dist/components/p-Cc5xgR17.js +2 -0
- package/dist/components/p-Cc5xgR17.js.map +1 -0
- package/dist/components/{p-ChlRsQYY.js → p-ChWnbdFS.js} +2 -2
- package/dist/components/{p-I8WGqoyC.js → p-DF52Grw1.js} +2 -2
- package/dist/components/{p-DXFtmZ8p.js → p-DhDWmMxD.js} +2 -2
- package/dist/components/{p-BpRKUpDT.js → p-DkPNCBA8.js} +2 -2
- package/dist/components/{p-DmZupC1-.js → p-O3OuOaj3.js} +2 -2
- package/dist/components/{p-C-GNvCk0.js → p-RLiackRN.js} +2 -2
- package/dist/components/{p-bR6Ltz4s.js → p-b-Dlg3y_.js} +2 -2
- package/dist/docs/components.json +757 -91
- package/dist/mcp-data/registry/pagination.json +401 -0
- package/dist/mcp-data/registry/registry.json +176 -18
- package/dist/mcp-data/registry/select.json +20 -2
- package/dist/mcp-data/registry/table.json +79 -39
- package/dist/react/components.d.ts +1 -0
- package/dist/react/components.js +1 -0
- package/dist/react/ds-pagination.d.ts +12 -0
- package/dist/react/ds-pagination.js +12 -0
- package/dist/react/ds-table.d.ts +2 -1
- package/dist/react/ds-table.js +1 -0
- package/dist/styles/table.css +11 -0
- package/dist/types/components/Pagination/Pagination.d.ts +42 -0
- package/dist/types/components/Pagination/index.d.ts +3 -0
- package/dist/types/components/Pagination/pagination-model.d.ts +14 -0
- package/dist/types/components/Pagination/pagination-types.d.ts +37 -0
- package/dist/types/components/Select/Select.d.ts +3 -0
- package/dist/types/components/Select/index.d.ts +1 -1
- package/dist/types/components/Table/Table.d.ts +22 -3
- package/dist/types/components/Table/index.d.ts +1 -1
- package/dist/types/components/Table/table-pagination-fit.d.ts +8 -0
- package/dist/types/components/Table/table-types.d.ts +33 -0
- package/dist/types/components.d.ts +227 -17
- package/package.json +1 -1
- /package/dist/components/{p-D2xWcVv6.js.map → p-B8q-6a03.js.map} +0 -0
- /package/dist/components/{p-BXEiYoDE.js.map → p-BDXMXH_i.js.map} +0 -0
- /package/dist/components/{p-DYzjeIAT.js.map → p-BHjw0x3L.js.map} +0 -0
- /package/dist/components/{p-BOCrvs-v.js.map → p-Btxwp4lJ.js.map} +0 -0
- /package/dist/components/{p-DD5OCVXx.js.map → p-C5TrNd31.js.map} +0 -0
- /package/dist/components/{p-BDCrM8-1.js.map → p-CDF_nP74.js.map} +0 -0
- /package/dist/components/{p-DJ_FsLCc.js.map → p-CKfdvOZ2.js.map} +0 -0
- /package/dist/components/{p-CRjpqqAI.js.map → p-CW7ML-3h.js.map} +0 -0
- /package/dist/components/{p-DZcFkqXw.js.map → p-CbqdWBAC.js.map} +0 -0
- /package/dist/components/{p-ChlRsQYY.js.map → p-ChWnbdFS.js.map} +0 -0
- /package/dist/components/{p-I8WGqoyC.js.map → p-DF52Grw1.js.map} +0 -0
- /package/dist/components/{p-DXFtmZ8p.js.map → p-DhDWmMxD.js.map} +0 -0
- /package/dist/components/{p-BpRKUpDT.js.map → p-DkPNCBA8.js.map} +0 -0
- /package/dist/components/{p-DmZupC1-.js.map → p-O3OuOaj3.js.map} +0 -0
- /package/dist/components/{p-C-GNvCk0.js.map → p-RLiackRN.js.map} +0 -0
- /package/dist/components/{p-bR6Ltz4s.js.map → p-b-Dlg3y_.js.map} +0 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "pagination",
|
|
4
|
+
"title": "Pagination",
|
|
5
|
+
"description": "Controlled fixed or fitted page-size, compact range, and first/previous/next/last navigation for application-owned data windows.",
|
|
6
|
+
"type": "registry:ui",
|
|
7
|
+
"meta": {
|
|
8
|
+
"library": "@ds-mo/ui",
|
|
9
|
+
"distribution": "npm",
|
|
10
|
+
"storybook": "https://zainadeel.github.io/compomo/?path=/story/pagination",
|
|
11
|
+
"source": "src/wc/components/Pagination/Pagination.tsx",
|
|
12
|
+
"intentStatus": "complete",
|
|
13
|
+
"intent": {
|
|
14
|
+
"audience": "general",
|
|
15
|
+
"status": "stable",
|
|
16
|
+
"summary": "Controlled fixed or fitted page-size, compact range, and first/previous/next/last navigation for application-owned data windows.",
|
|
17
|
+
"useWhen": [
|
|
18
|
+
"A result set is divided into discrete pages and the application owns fetching or slicing each page.",
|
|
19
|
+
"A table or list needs a compact page-size selector, result range, and boundary-aware navigation."
|
|
20
|
+
],
|
|
21
|
+
"avoidWhen": [
|
|
22
|
+
"More results append to one continuous list; use the owning component's incremental-loading behavior instead.",
|
|
23
|
+
"Only previous and next navigation is meaningful and the total result count is unknown."
|
|
24
|
+
],
|
|
25
|
+
"commonlyComposedWith": [
|
|
26
|
+
"component:ds-table",
|
|
27
|
+
"component:ds-select",
|
|
28
|
+
"component:ds-button-unfilled"
|
|
29
|
+
],
|
|
30
|
+
"accessibility": [
|
|
31
|
+
"The component renders a named navigation region, gives its compact page-size noun a complete accessible label, and gives every icon-only boundary control an explicit page action name.",
|
|
32
|
+
"The visible range and page position use compact slash notation with tabular numerals. A polite atomic status update retains complete ‘of’ and ‘Page’ phrasing with the localized item noun.",
|
|
33
|
+
"Left and Right Arrow request the adjacent page while focus is within pagination navigation controls. The page-size combobox retains its own arrow-key behavior.",
|
|
34
|
+
"Inactive boundary controls and every control during loading remain non-interactive while retaining their accessible names."
|
|
35
|
+
],
|
|
36
|
+
"states": [
|
|
37
|
+
"pageIndex, numeric effective pageSize, pageSizeMode, totalItems, and pageSizeOptions are controlled inputs. dsChange reports the complete next pagination state, previous index, size, and mode, and whether the request changed the page, page size, or fitted capacity; it never mutates controlled inputs.",
|
|
38
|
+
"Page-size changes request the first page. Out-of-range page indexes and invalid numeric inputs normalize only for presentation; the owner remains authoritative.",
|
|
39
|
+
"Zero results display 0–0 of 0 and Page 1 of 1. A partial final page caps the visible range at totalItems.",
|
|
40
|
+
"loading preserves the full pagination surface, applies aria-busy to the navigation region, and prevents page or page-size requests.",
|
|
41
|
+
"fitToPage appends a Fit to page choice. fitPageSize supplies its effective whole-item capacity; the closed trigger says Fit while the range continues to expose the resulting count. Pagination does not measure layouts itself."
|
|
42
|
+
],
|
|
43
|
+
"responsiveBehavior": [
|
|
44
|
+
"The compact controls remain on one line with noun, range, and page slash notation. When inline space is still insufficient, the pagination surface scrolls horizontally rather than wrapping labels away from their controls."
|
|
45
|
+
],
|
|
46
|
+
"frameworkCaveats": {
|
|
47
|
+
"customElements": [
|
|
48
|
+
"Assign pageSizeOptions through the JavaScript property and replace controlled values in response to dsChange."
|
|
49
|
+
],
|
|
50
|
+
"react": [
|
|
51
|
+
"Replace pageIndex and pageSize from the emitted detail before supplying the requested data window."
|
|
52
|
+
],
|
|
53
|
+
"angular": [
|
|
54
|
+
"Bind numeric inputs as properties and update the owning signals from the dsChange output."
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"references": [
|
|
58
|
+
{
|
|
59
|
+
"label": "Storybook review states",
|
|
60
|
+
"path": "src/wc/components/Pagination/Pagination.stories.ts"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"api": {
|
|
65
|
+
"props": {
|
|
66
|
+
"fitPageSize": {
|
|
67
|
+
"type": "number | undefined",
|
|
68
|
+
"resolvedType": "number | undefined",
|
|
69
|
+
"attribute": "fit-page-size",
|
|
70
|
+
"required": false,
|
|
71
|
+
"mutable": false,
|
|
72
|
+
"description": "Effective whole-item capacity to request when Fit is selected."
|
|
73
|
+
},
|
|
74
|
+
"fitPageSizeLabel": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"resolvedType": "string",
|
|
77
|
+
"attribute": "fit-page-size-label",
|
|
78
|
+
"default": "'Fit to page'",
|
|
79
|
+
"required": false,
|
|
80
|
+
"mutable": false,
|
|
81
|
+
"description": "Full choice-list label for Fit."
|
|
82
|
+
},
|
|
83
|
+
"fitPageSizeTriggerLabel": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"resolvedType": "string",
|
|
86
|
+
"attribute": "fit-page-size-trigger-label",
|
|
87
|
+
"default": "'Fit'",
|
|
88
|
+
"required": false,
|
|
89
|
+
"mutable": false,
|
|
90
|
+
"description": "Compact closed-trigger label while Fit is selected."
|
|
91
|
+
},
|
|
92
|
+
"fitToPage": {
|
|
93
|
+
"type": "boolean",
|
|
94
|
+
"resolvedType": "boolean",
|
|
95
|
+
"attribute": "fit-to-page",
|
|
96
|
+
"default": "false",
|
|
97
|
+
"required": false,
|
|
98
|
+
"mutable": false,
|
|
99
|
+
"description": "Include the Fit to page choice."
|
|
100
|
+
},
|
|
101
|
+
"itemLabel": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"resolvedType": "string",
|
|
104
|
+
"attribute": "item-label",
|
|
105
|
+
"default": "'items'",
|
|
106
|
+
"required": false,
|
|
107
|
+
"mutable": false,
|
|
108
|
+
"description": "Localized plural noun used by assistive range announcements."
|
|
109
|
+
},
|
|
110
|
+
"label": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"resolvedType": "string",
|
|
113
|
+
"attribute": "label",
|
|
114
|
+
"default": "'Pagination'",
|
|
115
|
+
"required": false,
|
|
116
|
+
"mutable": false,
|
|
117
|
+
"description": "Accessible name for the pagination navigation region."
|
|
118
|
+
},
|
|
119
|
+
"loading": {
|
|
120
|
+
"type": "boolean",
|
|
121
|
+
"resolvedType": "boolean",
|
|
122
|
+
"attribute": "loading",
|
|
123
|
+
"default": "false",
|
|
124
|
+
"required": false,
|
|
125
|
+
"mutable": false,
|
|
126
|
+
"description": "Prevent interaction while the owner replaces the current data page."
|
|
127
|
+
},
|
|
128
|
+
"pageIndex": {
|
|
129
|
+
"type": "number",
|
|
130
|
+
"resolvedType": "number",
|
|
131
|
+
"attribute": "page-index",
|
|
132
|
+
"default": "0",
|
|
133
|
+
"required": false,
|
|
134
|
+
"mutable": false,
|
|
135
|
+
"description": "Controlled zero-based page index."
|
|
136
|
+
},
|
|
137
|
+
"pageSize": {
|
|
138
|
+
"type": "number",
|
|
139
|
+
"resolvedType": "number",
|
|
140
|
+
"attribute": "page-size",
|
|
141
|
+
"default": "25",
|
|
142
|
+
"required": false,
|
|
143
|
+
"mutable": false,
|
|
144
|
+
"description": "Controlled number of top-level items on a full page."
|
|
145
|
+
},
|
|
146
|
+
"pageSizeAriaLabel": {
|
|
147
|
+
"type": "string | undefined",
|
|
148
|
+
"resolvedType": "string | undefined",
|
|
149
|
+
"attribute": "page-size-aria-label",
|
|
150
|
+
"required": false,
|
|
151
|
+
"mutable": false,
|
|
152
|
+
"description": "Accessible page-size control label. Defaults to “{pageSizeLabel} per page”."
|
|
153
|
+
},
|
|
154
|
+
"pageSizeLabel": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"resolvedType": "string",
|
|
157
|
+
"attribute": "page-size-label",
|
|
158
|
+
"default": "'Items'",
|
|
159
|
+
"required": false,
|
|
160
|
+
"mutable": false,
|
|
161
|
+
"description": "Visible page-size control label."
|
|
162
|
+
},
|
|
163
|
+
"pageSizeMode": {
|
|
164
|
+
"type": "PaginationPageSizeMode",
|
|
165
|
+
"resolvedType": "\"fit\" | \"fixed\"",
|
|
166
|
+
"attribute": "page-size-mode",
|
|
167
|
+
"default": "'fixed'",
|
|
168
|
+
"required": false,
|
|
169
|
+
"mutable": false,
|
|
170
|
+
"description": "Whether pageSize is a fixed choice or a measured Fit snapshot."
|
|
171
|
+
},
|
|
172
|
+
"pageSizeOptions": {
|
|
173
|
+
"type": "number[]",
|
|
174
|
+
"resolvedType": "number[]",
|
|
175
|
+
"default": "[25, 50, 100, 200]",
|
|
176
|
+
"required": false,
|
|
177
|
+
"mutable": false,
|
|
178
|
+
"description": "Available page sizes. Assign arrays through JavaScript."
|
|
179
|
+
},
|
|
180
|
+
"totalItems": {
|
|
181
|
+
"type": "number",
|
|
182
|
+
"resolvedType": "number",
|
|
183
|
+
"attribute": "total-items",
|
|
184
|
+
"default": "0",
|
|
185
|
+
"required": false,
|
|
186
|
+
"mutable": false,
|
|
187
|
+
"description": "Controlled total number of top-level items across every page."
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"events": [
|
|
191
|
+
{
|
|
192
|
+
"name": "dsChange",
|
|
193
|
+
"detail": "PaginationChangeDetail",
|
|
194
|
+
"bubbles": true,
|
|
195
|
+
"cancelable": true,
|
|
196
|
+
"composed": true,
|
|
197
|
+
"description": "Emits the complete next controlled state after a page or page-size request."
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"methods": [],
|
|
201
|
+
"slots": []
|
|
202
|
+
},
|
|
203
|
+
"props": {
|
|
204
|
+
"fitPageSize": {
|
|
205
|
+
"type": "number | undefined",
|
|
206
|
+
"resolvedType": "number | undefined",
|
|
207
|
+
"attribute": "fit-page-size",
|
|
208
|
+
"required": false,
|
|
209
|
+
"mutable": false,
|
|
210
|
+
"description": "Effective whole-item capacity to request when Fit is selected."
|
|
211
|
+
},
|
|
212
|
+
"fitPageSizeLabel": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"resolvedType": "string",
|
|
215
|
+
"attribute": "fit-page-size-label",
|
|
216
|
+
"default": "'Fit to page'",
|
|
217
|
+
"required": false,
|
|
218
|
+
"mutable": false,
|
|
219
|
+
"description": "Full choice-list label for Fit."
|
|
220
|
+
},
|
|
221
|
+
"fitPageSizeTriggerLabel": {
|
|
222
|
+
"type": "string",
|
|
223
|
+
"resolvedType": "string",
|
|
224
|
+
"attribute": "fit-page-size-trigger-label",
|
|
225
|
+
"default": "'Fit'",
|
|
226
|
+
"required": false,
|
|
227
|
+
"mutable": false,
|
|
228
|
+
"description": "Compact closed-trigger label while Fit is selected."
|
|
229
|
+
},
|
|
230
|
+
"fitToPage": {
|
|
231
|
+
"type": "boolean",
|
|
232
|
+
"resolvedType": "boolean",
|
|
233
|
+
"attribute": "fit-to-page",
|
|
234
|
+
"default": "false",
|
|
235
|
+
"required": false,
|
|
236
|
+
"mutable": false,
|
|
237
|
+
"description": "Include the Fit to page choice."
|
|
238
|
+
},
|
|
239
|
+
"itemLabel": {
|
|
240
|
+
"type": "string",
|
|
241
|
+
"resolvedType": "string",
|
|
242
|
+
"attribute": "item-label",
|
|
243
|
+
"default": "'items'",
|
|
244
|
+
"required": false,
|
|
245
|
+
"mutable": false,
|
|
246
|
+
"description": "Localized plural noun used by assistive range announcements."
|
|
247
|
+
},
|
|
248
|
+
"label": {
|
|
249
|
+
"type": "string",
|
|
250
|
+
"resolvedType": "string",
|
|
251
|
+
"attribute": "label",
|
|
252
|
+
"default": "'Pagination'",
|
|
253
|
+
"required": false,
|
|
254
|
+
"mutable": false,
|
|
255
|
+
"description": "Accessible name for the pagination navigation region."
|
|
256
|
+
},
|
|
257
|
+
"loading": {
|
|
258
|
+
"type": "boolean",
|
|
259
|
+
"resolvedType": "boolean",
|
|
260
|
+
"attribute": "loading",
|
|
261
|
+
"default": "false",
|
|
262
|
+
"required": false,
|
|
263
|
+
"mutable": false,
|
|
264
|
+
"description": "Prevent interaction while the owner replaces the current data page."
|
|
265
|
+
},
|
|
266
|
+
"pageIndex": {
|
|
267
|
+
"type": "number",
|
|
268
|
+
"resolvedType": "number",
|
|
269
|
+
"attribute": "page-index",
|
|
270
|
+
"default": "0",
|
|
271
|
+
"required": false,
|
|
272
|
+
"mutable": false,
|
|
273
|
+
"description": "Controlled zero-based page index."
|
|
274
|
+
},
|
|
275
|
+
"pageSize": {
|
|
276
|
+
"type": "number",
|
|
277
|
+
"resolvedType": "number",
|
|
278
|
+
"attribute": "page-size",
|
|
279
|
+
"default": "25",
|
|
280
|
+
"required": false,
|
|
281
|
+
"mutable": false,
|
|
282
|
+
"description": "Controlled number of top-level items on a full page."
|
|
283
|
+
},
|
|
284
|
+
"pageSizeAriaLabel": {
|
|
285
|
+
"type": "string | undefined",
|
|
286
|
+
"resolvedType": "string | undefined",
|
|
287
|
+
"attribute": "page-size-aria-label",
|
|
288
|
+
"required": false,
|
|
289
|
+
"mutable": false,
|
|
290
|
+
"description": "Accessible page-size control label. Defaults to “{pageSizeLabel} per page”."
|
|
291
|
+
},
|
|
292
|
+
"pageSizeLabel": {
|
|
293
|
+
"type": "string",
|
|
294
|
+
"resolvedType": "string",
|
|
295
|
+
"attribute": "page-size-label",
|
|
296
|
+
"default": "'Items'",
|
|
297
|
+
"required": false,
|
|
298
|
+
"mutable": false,
|
|
299
|
+
"description": "Visible page-size control label."
|
|
300
|
+
},
|
|
301
|
+
"pageSizeMode": {
|
|
302
|
+
"type": "PaginationPageSizeMode",
|
|
303
|
+
"resolvedType": "\"fit\" | \"fixed\"",
|
|
304
|
+
"attribute": "page-size-mode",
|
|
305
|
+
"default": "'fixed'",
|
|
306
|
+
"required": false,
|
|
307
|
+
"mutable": false,
|
|
308
|
+
"description": "Whether pageSize is a fixed choice or a measured Fit snapshot."
|
|
309
|
+
},
|
|
310
|
+
"pageSizeOptions": {
|
|
311
|
+
"type": "number[]",
|
|
312
|
+
"resolvedType": "number[]",
|
|
313
|
+
"default": "[25, 50, 100, 200]",
|
|
314
|
+
"required": false,
|
|
315
|
+
"mutable": false,
|
|
316
|
+
"description": "Available page sizes. Assign arrays through JavaScript."
|
|
317
|
+
},
|
|
318
|
+
"totalItems": {
|
|
319
|
+
"type": "number",
|
|
320
|
+
"resolvedType": "number",
|
|
321
|
+
"attribute": "total-items",
|
|
322
|
+
"default": "0",
|
|
323
|
+
"required": false,
|
|
324
|
+
"mutable": false,
|
|
325
|
+
"description": "Controlled total number of top-level items across every page."
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
"events": [
|
|
329
|
+
{
|
|
330
|
+
"name": "dsChange",
|
|
331
|
+
"detail": "PaginationChangeDetail",
|
|
332
|
+
"bubbles": true,
|
|
333
|
+
"cancelable": true,
|
|
334
|
+
"composed": true,
|
|
335
|
+
"description": "Emits the complete next controlled state after a page or page-size request."
|
|
336
|
+
}
|
|
337
|
+
],
|
|
338
|
+
"methods": [],
|
|
339
|
+
"slots": [],
|
|
340
|
+
"exports": {
|
|
341
|
+
"customElement": "ds-pagination",
|
|
342
|
+
"react": "DsPagination",
|
|
343
|
+
"angular": "DsPagination"
|
|
344
|
+
},
|
|
345
|
+
"consumption": {
|
|
346
|
+
"install": "npm install @ds-mo/ui @ds-mo/tokens @ds-mo/icons",
|
|
347
|
+
"cssSetup": "import '@ds-mo/tokens';\nimport '@ds-mo/tokens/reset';\nimport '@ds-mo/tokens/globals';",
|
|
348
|
+
"customElements": {
|
|
349
|
+
"import": "import '@ds-mo/ui/dist/components/ds-pagination.js';",
|
|
350
|
+
"example": "<ds-pagination></ds-pagination>"
|
|
351
|
+
},
|
|
352
|
+
"react": {
|
|
353
|
+
"import": "import { DsPagination } from '@ds-mo/ui/react';",
|
|
354
|
+
"example": "<DsPagination />"
|
|
355
|
+
},
|
|
356
|
+
"angular": {
|
|
357
|
+
"import": "import { DsPagination } from '@ds-mo/ui/angular/ds-pagination';",
|
|
358
|
+
"example": "<ds-pagination></ds-pagination>"
|
|
359
|
+
},
|
|
360
|
+
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: pageSizeOptions.",
|
|
361
|
+
"peerDependencies": {
|
|
362
|
+
"required": [
|
|
363
|
+
"@ds-mo/tokens ^6.2.2",
|
|
364
|
+
"@ds-mo/icons ^7.0.0"
|
|
365
|
+
],
|
|
366
|
+
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
"dependencies": [
|
|
371
|
+
"@ds-mo/ui",
|
|
372
|
+
"@ds-mo/tokens"
|
|
373
|
+
],
|
|
374
|
+
"registryDependencies": [
|
|
375
|
+
"button-unfilled",
|
|
376
|
+
"select",
|
|
377
|
+
"text"
|
|
378
|
+
],
|
|
379
|
+
"files": [
|
|
380
|
+
{
|
|
381
|
+
"path": "src/wc/components/Pagination/Pagination.css",
|
|
382
|
+
"content": "@import '../../utils/visually-hidden.css';\n\n:host {\n display: block;\n box-sizing: border-box;\n min-width: 0;\n max-width: 100%;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n:host::-webkit-scrollbar {\n display: none;\n}\n\n.pagination,\n.pagination__page-size,\n.pagination__navigation {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n}\n\n.pagination {\n width: max-content;\n min-width: 100%;\n gap: var(--dimension-space-200);\n}\n\n.pagination__page-size,\n.pagination__navigation {\n flex: 0 0 auto;\n}\n\n.pagination__page-size {\n gap: var(--dimension-space-100);\n}\n\n.pagination__navigation {\n gap: var(--dimension-space-050);\n}\n\n.pagination__range,\n.pagination__page,\n.pagination__label {\n display: inline-flex;\n align-items: center;\n flex: 0 0 auto;\n white-space: nowrap;\n}\n\n.pagination__page {\n justify-content: center;\n min-inline-size: calc(var(--dimension-size-800) + var(--dimension-space-200));\n padding-inline: var(--dimension-space-050);\n}\n",
|
|
383
|
+
"type": "registry:ui"
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
"path": "src/wc/components/Pagination/Pagination.tsx",
|
|
387
|
+
"content": "import { Component, Event, EventEmitter, h, Host, Prop } from '@stencil/core';\nimport { resolvePaginationState } from './pagination-model';\nimport type {\n PaginationChangeDetail,\n PaginationPageSizeMode,\n} from './pagination-types';\n\nlet paginationId = 0;\n\n@Component({\n tag: 'ds-pagination',\n styleUrl: 'Pagination.css',\n scoped: true,\n})\nexport class Pagination {\n /** Controlled zero-based page index. */\n @Prop() pageIndex: number = 0;\n /** Controlled number of top-level items on a full page. */\n @Prop() pageSize: number = 25;\n /** Whether pageSize is a fixed choice or a measured Fit snapshot. */\n @Prop() pageSizeMode: PaginationPageSizeMode = 'fixed';\n /** Controlled total number of top-level items across every page. */\n @Prop() totalItems: number = 0;\n /** Available page sizes. Assign arrays through JavaScript. */\n @Prop() pageSizeOptions: number[] = [25, 50, 100, 200];\n /** Include the Fit to page choice. */\n @Prop() fitToPage: boolean = false;\n /** Effective whole-item capacity to request when Fit is selected. */\n @Prop() fitPageSize: number | undefined;\n /** Full choice-list label for Fit. */\n @Prop() fitPageSizeLabel: string = 'Fit to page';\n /** Compact closed-trigger label while Fit is selected. */\n @Prop() fitPageSizeTriggerLabel: string = 'Fit';\n /** Localized plural noun used by assistive range announcements. */\n @Prop() itemLabel: string = 'items';\n /** Visible page-size control label. */\n @Prop() pageSizeLabel: string = 'Items';\n /** Accessible page-size control label. Defaults to “{pageSizeLabel} per page”. */\n @Prop() pageSizeAriaLabel: string | undefined;\n /** Accessible name for the pagination navigation region. */\n @Prop() label: string = 'Pagination';\n /** Prevent interaction while the owner replaces the current data page. */\n @Prop() loading: boolean = false;\n\n /** Emits the complete next controlled state after a page or page-size request. */\n @Event() dsChange!: EventEmitter<PaginationChangeDetail>;\n\n private readonly pageSizeControlId = `ds-pagination-${++paginationId}-page-size`;\n\n private requestPage(pageIndex: number): void {\n const state = this.resolvedState;\n if (this.loading || pageIndex === state.pageIndex || pageIndex < 0 || pageIndex >= state.totalPages) {\n return;\n }\n this.dsChange.emit({\n pageIndex,\n pageSize: state.pageSize,\n pageSizeMode: state.pageSizeMode,\n totalItems: state.totalItems,\n pageSizeOptions: state.pageSizeOptions,\n fitToPage: this.fitToPage,\n fitPageSize: this.resolvedFitPageSize,\n fitPageSizeLabel: this.fitPageSizeLabel,\n fitPageSizeTriggerLabel: this.fitPageSizeTriggerLabel,\n itemLabel: this.itemLabel,\n pageSizeLabel: this.pageSizeLabel,\n ariaLabel: this.label,\n previousPageIndex: state.pageIndex,\n previousPageSize: state.pageSize,\n previousPageSizeMode: state.pageSizeMode,\n reason: 'page',\n });\n }\n\n private requestPageSize(value: string | string[]): void {\n if (this.loading || typeof value !== 'string') return;\n const state = this.resolvedState;\n const nextMode: PaginationPageSizeMode = value === 'fit' ? 'fit' : 'fixed';\n const pageSize = nextMode === 'fit' ? this.resolvedFitPageSize : Number(value);\n if (!pageSize || (pageSize === state.pageSize && nextMode === state.pageSizeMode)) return;\n this.dsChange.emit({\n pageIndex: 0,\n pageSize: Math.trunc(pageSize),\n pageSizeMode: nextMode,\n totalItems: state.totalItems,\n pageSizeOptions: state.pageSizeOptions,\n fitToPage: this.fitToPage,\n fitPageSize: this.resolvedFitPageSize,\n fitPageSizeLabel: this.fitPageSizeLabel,\n fitPageSizeTriggerLabel: this.fitPageSizeTriggerLabel,\n itemLabel: this.itemLabel,\n pageSizeLabel: this.pageSizeLabel,\n ariaLabel: this.label,\n previousPageIndex: state.pageIndex,\n previousPageSize: state.pageSize,\n previousPageSizeMode: state.pageSizeMode,\n reason: 'page-size',\n });\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n return;\n }\n const fromChoiceControl = event.composedPath().some(node =>\n node instanceof HTMLElement &&\n (node.tagName === 'DS-SELECT' || ['INPUT', 'SELECT', 'TEXTAREA'].includes(node.tagName)),\n );\n if (fromChoiceControl || (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight')) return;\n const state = this.resolvedState;\n const pageIndex = event.key === 'ArrowLeft' ? state.pageIndex - 1 : state.pageIndex + 1;\n if (this.loading || pageIndex < 0 || pageIndex >= state.totalPages) return;\n event.preventDefault();\n this.requestPage(pageIndex);\n }\n\n private get resolvedFitPageSize(): number | undefined {\n return Number.isFinite(this.fitPageSize) && Number(this.fitPageSize) > 0\n ? Math.trunc(Number(this.fitPageSize))\n : undefined;\n }\n\n private get resolvedState() {\n return resolvePaginationState({\n pageIndex: this.pageIndex,\n pageSize: this.pageSize,\n pageSizeMode: this.pageSizeMode,\n totalItems: this.totalItems,\n pageSizeOptions: this.pageSizeOptions,\n });\n }\n\n render() {\n const state = this.resolvedState;\n const atStart = state.pageIndex === 0;\n const atEnd = state.pageIndex === state.totalPages - 1;\n const range = `${state.firstItem}–${state.lastItem} / ${state.totalItems}`;\n const page = `${state.pageIndex + 1} / ${state.totalPages}`;\n const announcedRange = `${state.firstItem}–${state.lastItem} of ${state.totalItems}`;\n const announcedPage = `Page ${state.pageIndex + 1} of ${state.totalPages}`;\n const pageSizeAriaLabel = this.pageSizeAriaLabel ?? `${this.pageSizeLabel} per page`;\n const options: Array<{ label: string; value: string; isInactive?: boolean }> =\n state.pageSizeOptions.map(value => ({ label: String(value), value: String(value) }));\n if (this.fitToPage) {\n options.push({\n label: this.fitPageSizeLabel,\n value: 'fit',\n isInactive: this.resolvedFitPageSize === undefined,\n });\n }\n\n return (\n <Host>\n <nav\n class=\"pagination\"\n aria-label={this.label}\n aria-busy={this.loading ? 'true' : undefined}\n onKeyDown={event => this.handleKeyDown(event)}\n >\n <div class=\"pagination__page-size\">\n <ds-text\n class=\"pagination__label\"\n as=\"span\"\n variant=\"text-body-medium\"\n color=\"secondary\"\n aria-hidden=\"true\"\n >\n {this.pageSizeLabel}:\n </ds-text>\n <span id={`${this.pageSizeControlId}-label`} class=\"ds-visually-hidden\">\n {pageSizeAriaLabel}\n </span>\n <ds-select\n size=\"md\"\n inputId={this.pageSizeControlId}\n ariaLabelledby={`${this.pageSizeControlId}-label`}\n options={options}\n value={state.pageSizeMode === 'fit' ? 'fit' : String(state.pageSize)}\n triggerLabel={state.pageSizeMode === 'fit' ? this.fitPageSizeTriggerLabel : undefined}\n indicator=\"up-down\"\n allowClear={false}\n activeFill={false}\n isInactive={this.loading}\n onDsChange={event => {\n event.stopPropagation();\n this.requestPageSize(event.detail);\n }}\n />\n </div>\n <ds-text\n class=\"pagination__range\"\n as=\"span\"\n variant=\"text-body-medium\"\n color=\"secondary\"\n fontFeature=\"tabular-nums\"\n >\n {range}\n </ds-text>\n <div class=\"pagination__navigation\">\n <ds-button-unfilled\n variant=\"icon\"\n size=\"md\"\n icon=\"ChevronLeftDouble\"\n ariaLabel=\"First page\"\n hasBorder={false}\n isInactive={this.loading || atStart}\n onDsClick={() => this.requestPage(0)}\n />\n <ds-button-unfilled\n variant=\"icon\"\n size=\"md\"\n icon=\"ChevronLeft\"\n ariaLabel=\"Previous page\"\n hasBorder={false}\n isInactive={this.loading || atStart}\n onDsClick={() => this.requestPage(state.pageIndex - 1)}\n />\n <ds-text\n class=\"pagination__page\"\n as=\"span\"\n variant=\"text-body-medium\"\n color=\"secondary\"\n fontFeature=\"tabular-nums\"\n >\n {page}\n </ds-text>\n <ds-button-unfilled\n variant=\"icon\"\n size=\"md\"\n icon=\"ChevronRight\"\n ariaLabel=\"Next page\"\n hasBorder={false}\n isInactive={this.loading || atEnd}\n onDsClick={() => this.requestPage(state.pageIndex + 1)}\n />\n <ds-button-unfilled\n variant=\"icon\"\n size=\"md\"\n icon=\"ChevronRightDouble\"\n ariaLabel=\"Last page\"\n hasBorder={false}\n isInactive={this.loading || atEnd}\n onDsClick={() => this.requestPage(state.totalPages - 1)}\n />\n </div>\n <span class=\"ds-visually-hidden\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {announcedRange} {this.itemLabel}. {announcedPage}.\n </span>\n </nav>\n </Host>\n );\n }\n}\n",
|
|
388
|
+
"type": "registry:ui"
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
"path": "src/wc/components/Pagination/pagination-model.ts",
|
|
392
|
+
"content": "import type { PaginationPageSizeMode, PaginationState } from './pagination-types';\n\nexport const DEFAULT_PAGE_SIZE_OPTIONS = [25, 50, 100, 200] as const;\n\nexport interface ResolvedPaginationState {\n pageIndex: number;\n pageSize: number;\n pageSizeMode: PaginationPageSizeMode;\n totalItems: number;\n totalPages: number;\n firstItem: number;\n lastItem: number;\n pageSizeOptions: number[];\n}\n\nfunction nonNegativeInteger(value: number): number {\n return Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;\n}\n\nfunction positiveInteger(value: number, fallback: number): number {\n return Number.isFinite(value) && value > 0 ? Math.trunc(value) : fallback;\n}\n\nexport function resolvePaginationState(\n state: Pick<\n PaginationState,\n 'pageIndex' | 'pageSize' | 'pageSizeMode' | 'totalItems' | 'pageSizeOptions'\n >,\n): ResolvedPaginationState {\n const pageSize = positiveInteger(state.pageSize, DEFAULT_PAGE_SIZE_OPTIONS[0]);\n const pageSizeMode = state.pageSizeMode === 'fit' ? 'fit' : 'fixed';\n const totalItems = nonNegativeInteger(state.totalItems);\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\n const pageIndex = Math.min(nonNegativeInteger(state.pageIndex), totalPages - 1);\n const options = (state.pageSizeOptions?.length\n ? state.pageSizeOptions\n : DEFAULT_PAGE_SIZE_OPTIONS\n )\n .map(value => positiveInteger(value, 0))\n .filter(value => value > 0);\n const pageSizeOptions = [\n ...new Set(pageSizeMode === 'fixed' ? [...options, pageSize] : options),\n ].sort((left, right) => left - right);\n const firstItem = totalItems === 0 ? 0 : pageIndex * pageSize + 1;\n const lastItem = totalItems === 0 ? 0 : Math.min(totalItems, firstItem + pageSize - 1);\n\n return {\n pageIndex,\n pageSize,\n pageSizeMode,\n totalItems,\n totalPages,\n firstItem,\n lastItem,\n pageSizeOptions,\n };\n}\n",
|
|
393
|
+
"type": "registry:ui"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"path": "src/wc/components/Pagination/pagination-types.ts",
|
|
397
|
+
"content": "export type PaginationChangeReason = 'page' | 'page-size' | 'fit';\nexport type PaginationPageSizeMode = 'fixed' | 'fit';\n\n/** Controlled pagination state shared by Pagination and pagination-aware consumers. */\nexport interface PaginationState {\n /** Zero-based page index. */\n pageIndex: number;\n /** Number of top-level items on a full page. */\n pageSize: number;\n /** Whether pageSize is a chosen fixed value or a measured Fit snapshot. */\n pageSizeMode?: PaginationPageSizeMode;\n /** Total number of top-level items across every page. */\n totalItems: number;\n /** Available page sizes. Defaults to 25, 50, 100, and 200. */\n pageSizeOptions?: number[];\n /** Include a Fit to page option. The owner supplies the effective fitted size. */\n fitToPage?: boolean;\n /** Effective page size proposed when Fit to page is selected. */\n fitPageSize?: number;\n /** Full option label for Fit in the open choice list. */\n fitPageSizeLabel?: string;\n /** Compact trigger label while Fit is selected. */\n fitPageSizeTriggerLabel?: string;\n /** Localized plural noun used by assistive range announcements. */\n itemLabel?: string;\n /** Visible label for the page-size selector. */\n pageSizeLabel?: string;\n /** Accessible name for the pagination navigation region. */\n ariaLabel?: string;\n}\n\n/** Complete next controlled state emitted for a page or page-size request. */\nexport interface PaginationChangeDetail extends PaginationState {\n previousPageIndex: number;\n previousPageSize: number;\n previousPageSizeMode: PaginationPageSizeMode;\n reason: PaginationChangeReason;\n}\n",
|
|
398
|
+
"type": "registry:ui"
|
|
399
|
+
}
|
|
400
|
+
]
|
|
401
|
+
}
|