ngx-com 0.0.1 → 0.0.4
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/fesm2022/ngx-com-components-avatar.mjs +772 -0
- package/fesm2022/ngx-com-components-avatar.mjs.map +1 -0
- package/fesm2022/ngx-com-components-badge.mjs +138 -0
- package/fesm2022/ngx-com-components-badge.mjs.map +1 -0
- package/fesm2022/ngx-com-components-button.mjs +146 -0
- package/fesm2022/ngx-com-components-button.mjs.map +1 -0
- package/fesm2022/ngx-com-components-calendar.mjs +5046 -0
- package/fesm2022/ngx-com-components-calendar.mjs.map +1 -0
- package/fesm2022/ngx-com-components-card.mjs +590 -0
- package/fesm2022/ngx-com-components-card.mjs.map +1 -0
- package/fesm2022/ngx-com-components-checkbox.mjs +344 -0
- package/fesm2022/ngx-com-components-checkbox.mjs.map +1 -0
- package/fesm2022/ngx-com-components-collapsible.mjs +612 -0
- package/fesm2022/ngx-com-components-collapsible.mjs.map +1 -0
- package/fesm2022/ngx-com-components-confirm.mjs +562 -0
- package/fesm2022/ngx-com-components-confirm.mjs.map +1 -0
- package/fesm2022/ngx-com-components-dropdown-testing.mjs +255 -0
- package/fesm2022/ngx-com-components-dropdown-testing.mjs.map +1 -0
- package/fesm2022/ngx-com-components-dropdown.mjs +2692 -0
- package/fesm2022/ngx-com-components-dropdown.mjs.map +1 -0
- package/fesm2022/ngx-com-components-empty-state.mjs +382 -0
- package/fesm2022/ngx-com-components-empty-state.mjs.map +1 -0
- package/fesm2022/ngx-com-components-form-field.mjs +924 -0
- package/fesm2022/ngx-com-components-form-field.mjs.map +1 -0
- package/fesm2022/ngx-com-components-icon.mjs +183 -0
- package/fesm2022/ngx-com-components-icon.mjs.map +1 -0
- package/fesm2022/ngx-com-components-item.mjs +578 -0
- package/fesm2022/ngx-com-components-item.mjs.map +1 -0
- package/fesm2022/ngx-com-components-menu.mjs +1200 -0
- package/fesm2022/ngx-com-components-menu.mjs.map +1 -0
- package/fesm2022/ngx-com-components-paginator.mjs +823 -0
- package/fesm2022/ngx-com-components-paginator.mjs.map +1 -0
- package/fesm2022/ngx-com-components-popover.mjs +901 -0
- package/fesm2022/ngx-com-components-popover.mjs.map +1 -0
- package/fesm2022/ngx-com-components-radio.mjs +621 -0
- package/fesm2022/ngx-com-components-radio.mjs.map +1 -0
- package/fesm2022/ngx-com-components-segmented-control.mjs +538 -0
- package/fesm2022/ngx-com-components-segmented-control.mjs.map +1 -0
- package/fesm2022/ngx-com-components-sort.mjs +368 -0
- package/fesm2022/ngx-com-components-sort.mjs.map +1 -0
- package/fesm2022/ngx-com-components-spinner.mjs +189 -0
- package/fesm2022/ngx-com-components-spinner.mjs.map +1 -0
- package/fesm2022/ngx-com-components-tabs.mjs +1522 -0
- package/fesm2022/ngx-com-components-tabs.mjs.map +1 -0
- package/fesm2022/ngx-com-components-tooltip.mjs +625 -0
- package/fesm2022/ngx-com-components-tooltip.mjs.map +1 -0
- package/fesm2022/ngx-com-components.mjs +17 -0
- package/fesm2022/ngx-com-components.mjs.map +1 -0
- package/fesm2022/ngx-com-tokens.mjs +12 -0
- package/fesm2022/ngx-com-tokens.mjs.map +1 -0
- package/fesm2022/ngx-com-utils.mjs +601 -0
- package/fesm2022/ngx-com-utils.mjs.map +1 -0
- package/fesm2022/ngx-com.mjs +9 -23
- package/fesm2022/ngx-com.mjs.map +1 -1
- package/package.json +105 -1
- package/types/ngx-com-components-avatar.d.ts +409 -0
- package/types/ngx-com-components-badge.d.ts +97 -0
- package/types/ngx-com-components-button.d.ts +69 -0
- package/types/ngx-com-components-calendar.d.ts +1665 -0
- package/types/ngx-com-components-card.d.ts +373 -0
- package/types/ngx-com-components-checkbox.d.ts +116 -0
- package/types/ngx-com-components-collapsible.d.ts +379 -0
- package/types/ngx-com-components-confirm.d.ts +160 -0
- package/types/ngx-com-components-dropdown-testing.d.ts +116 -0
- package/types/ngx-com-components-dropdown.d.ts +938 -0
- package/types/ngx-com-components-empty-state.d.ts +269 -0
- package/types/ngx-com-components-form-field.d.ts +531 -0
- package/types/ngx-com-components-icon.d.ts +94 -0
- package/types/ngx-com-components-item.d.ts +336 -0
- package/types/ngx-com-components-menu.d.ts +479 -0
- package/types/ngx-com-components-paginator.d.ts +265 -0
- package/types/ngx-com-components-popover.d.ts +309 -0
- package/types/ngx-com-components-radio.d.ts +258 -0
- package/types/ngx-com-components-segmented-control.d.ts +274 -0
- package/types/ngx-com-components-sort.d.ts +133 -0
- package/types/ngx-com-components-spinner.d.ts +120 -0
- package/types/ngx-com-components-tabs.d.ts +396 -0
- package/types/ngx-com-components-tooltip.d.ts +200 -0
- package/types/ngx-com-components.d.ts +12 -0
- package/types/ngx-com-tokens.d.ts +7 -0
- package/types/ngx-com-utils.d.ts +424 -0
- package/types/ngx-com.d.ts +10 -7
|
@@ -0,0 +1,823 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { viewChildren, input, booleanAttribute, output, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { ComIcon } from 'ngx-com/components/icon';
|
|
4
|
+
import { cva } from 'class-variance-authority';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Default range label function.
|
|
8
|
+
* Produces output like "1 – 10 of 100" or "0 of 0" when empty.
|
|
9
|
+
*/
|
|
10
|
+
function defaultRangeLabel(page, pageSize, length) {
|
|
11
|
+
if (length === 0 || pageSize === 0) {
|
|
12
|
+
return `0 of ${length}`;
|
|
13
|
+
}
|
|
14
|
+
const startIndex = page * pageSize;
|
|
15
|
+
// Ensure end index doesn't exceed length
|
|
16
|
+
const endIndex = Math.min(startIndex + pageSize, length);
|
|
17
|
+
return `${startIndex + 1} – ${endIndex} of ${length}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ─── Container Variants ───
|
|
21
|
+
/**
|
|
22
|
+
* CVA variants for the paginator container.
|
|
23
|
+
* Controls overall layout and spacing.
|
|
24
|
+
*/
|
|
25
|
+
const paginatorContainerVariants = cva([
|
|
26
|
+
'flex items-center',
|
|
27
|
+
'text-foreground',
|
|
28
|
+
'select-none',
|
|
29
|
+
], {
|
|
30
|
+
variants: {
|
|
31
|
+
size: {
|
|
32
|
+
sm: 'gap-3 text-xs',
|
|
33
|
+
md: 'gap-4 text-sm',
|
|
34
|
+
},
|
|
35
|
+
layout: {
|
|
36
|
+
compact: 'justify-end',
|
|
37
|
+
spread: 'justify-between',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
defaultVariants: {
|
|
41
|
+
size: 'md',
|
|
42
|
+
layout: 'compact',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
// ─── Button Variants ───
|
|
46
|
+
/**
|
|
47
|
+
* CVA variants for paginator navigation buttons.
|
|
48
|
+
* Controls button sizing, borders, and interactive states.
|
|
49
|
+
*/
|
|
50
|
+
const paginatorButtonVariants = cva([
|
|
51
|
+
'inline-flex items-center justify-center',
|
|
52
|
+
'rounded-control',
|
|
53
|
+
'border border-border',
|
|
54
|
+
'bg-transparent',
|
|
55
|
+
'transition-colors duration-150',
|
|
56
|
+
'cursor-pointer',
|
|
57
|
+
'hover:bg-muted hover:text-muted-foreground',
|
|
58
|
+
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',
|
|
59
|
+
'disabled:cursor-not-allowed disabled:bg-disabled disabled:text-disabled-foreground disabled:border-disabled',
|
|
60
|
+
], {
|
|
61
|
+
variants: {
|
|
62
|
+
size: {
|
|
63
|
+
sm: 'h-7 w-7',
|
|
64
|
+
md: 'h-9 w-9',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
defaultVariants: {
|
|
68
|
+
size: 'md',
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
// ─── Range Label Variants ───
|
|
72
|
+
/**
|
|
73
|
+
* CVA variants for the range label text.
|
|
74
|
+
* Controls typography and color.
|
|
75
|
+
*/
|
|
76
|
+
const paginatorRangeLabelVariants = cva([
|
|
77
|
+
'text-muted-foreground',
|
|
78
|
+
'whitespace-nowrap',
|
|
79
|
+
], {
|
|
80
|
+
variants: {
|
|
81
|
+
size: {
|
|
82
|
+
sm: 'text-xs',
|
|
83
|
+
md: 'text-sm',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
defaultVariants: {
|
|
87
|
+
size: 'md',
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
// ─── Page Size Selector Variants ───
|
|
91
|
+
/**
|
|
92
|
+
* CVA variants for the page size select element.
|
|
93
|
+
* Controls sizing and styling of the native select.
|
|
94
|
+
*/
|
|
95
|
+
const paginatorSelectVariants = cva([
|
|
96
|
+
'appearance-none',
|
|
97
|
+
'rounded-control',
|
|
98
|
+
'border border-border',
|
|
99
|
+
'bg-transparent',
|
|
100
|
+
'text-foreground',
|
|
101
|
+
'cursor-pointer',
|
|
102
|
+
'transition-colors duration-150',
|
|
103
|
+
'hover:bg-muted',
|
|
104
|
+
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',
|
|
105
|
+
'disabled:cursor-not-allowed disabled:bg-disabled disabled:text-disabled-foreground disabled:border-disabled',
|
|
106
|
+
'pr-6', // Space for custom dropdown arrow
|
|
107
|
+
], {
|
|
108
|
+
variants: {
|
|
109
|
+
size: {
|
|
110
|
+
sm: 'h-7 px-2 text-xs',
|
|
111
|
+
md: 'h-9 px-3 text-sm',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
defaultVariants: {
|
|
115
|
+
size: 'md',
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
// ─── Variant Types ───
|
|
119
|
+
// ─── Page Button Variants ───
|
|
120
|
+
/**
|
|
121
|
+
* CVA variants for numbered page buttons.
|
|
122
|
+
* Controls button sizing, active state, and interactive states.
|
|
123
|
+
*/
|
|
124
|
+
const paginatorPageButtonVariants = cva([
|
|
125
|
+
'inline-flex items-center justify-center',
|
|
126
|
+
'rounded-control',
|
|
127
|
+
'font-medium',
|
|
128
|
+
'transition-colors duration-150',
|
|
129
|
+
'cursor-pointer',
|
|
130
|
+
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',
|
|
131
|
+
'disabled:cursor-not-allowed disabled:bg-disabled disabled:text-disabled-foreground',
|
|
132
|
+
], {
|
|
133
|
+
variants: {
|
|
134
|
+
size: {
|
|
135
|
+
sm: 'h-7 min-w-7 px-1.5 text-xs',
|
|
136
|
+
md: 'h-9 min-w-9 px-2 text-sm',
|
|
137
|
+
},
|
|
138
|
+
active: {
|
|
139
|
+
true: 'bg-primary text-primary-foreground',
|
|
140
|
+
false: 'bg-transparent text-foreground hover:bg-muted hover:text-muted-foreground',
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
defaultVariants: {
|
|
144
|
+
size: 'md',
|
|
145
|
+
active: false,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
// ─── Ellipsis Variants ───
|
|
149
|
+
/**
|
|
150
|
+
* CVA variants for the ellipsis indicator.
|
|
151
|
+
* Controls sizing and styling of the "..." text.
|
|
152
|
+
*/
|
|
153
|
+
const paginatorEllipsisVariants = cva([
|
|
154
|
+
'inline-flex items-center justify-center',
|
|
155
|
+
'text-muted-foreground',
|
|
156
|
+
'select-none',
|
|
157
|
+
], {
|
|
158
|
+
variants: {
|
|
159
|
+
size: {
|
|
160
|
+
sm: 'h-7 w-7 text-xs',
|
|
161
|
+
md: 'h-9 w-9 text-sm',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
defaultVariants: {
|
|
165
|
+
size: 'md',
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Paginator component — provides navigation for paginated content.
|
|
171
|
+
*
|
|
172
|
+
* Displays navigation controls, optional page size selector, and range label
|
|
173
|
+
* showing current position within the data set. Supports numbered page buttons
|
|
174
|
+
* when `showPageNumbers` is enabled.
|
|
175
|
+
*
|
|
176
|
+
* @tokens `--color-foreground`, `--color-muted-foreground`,
|
|
177
|
+
* `--color-border`, `--color-muted`,
|
|
178
|
+
* `--color-disabled`, `--color-disabled-foreground`,
|
|
179
|
+
* `--color-ring`, `--color-primary`, `--color-primary-foreground`
|
|
180
|
+
*
|
|
181
|
+
* @example Basic usage
|
|
182
|
+
* ```html
|
|
183
|
+
* <com-paginator
|
|
184
|
+
* [length]="100"
|
|
185
|
+
* [pageSize]="10"
|
|
186
|
+
* [pageIndex]="0"
|
|
187
|
+
* (page)="onPageChange($event)"
|
|
188
|
+
* />
|
|
189
|
+
* ```
|
|
190
|
+
*
|
|
191
|
+
* @example With page size options
|
|
192
|
+
* ```html
|
|
193
|
+
* <com-paginator
|
|
194
|
+
* [length]="100"
|
|
195
|
+
* [pageSize]="10"
|
|
196
|
+
* [pageIndex]="0"
|
|
197
|
+
* [pageSizeOptions]="[5, 10, 25, 50]"
|
|
198
|
+
* (page)="onPageChange($event)"
|
|
199
|
+
* />
|
|
200
|
+
* ```
|
|
201
|
+
*
|
|
202
|
+
* @example With first/last buttons
|
|
203
|
+
* ```html
|
|
204
|
+
* <com-paginator
|
|
205
|
+
* [length]="100"
|
|
206
|
+
* [pageSize]="10"
|
|
207
|
+
* [pageIndex]="0"
|
|
208
|
+
* [showFirstLastButtons]="true"
|
|
209
|
+
* (page)="onPageChange($event)"
|
|
210
|
+
* />
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @example With numbered page buttons
|
|
214
|
+
* ```html
|
|
215
|
+
* <com-paginator
|
|
216
|
+
* [length]="97"
|
|
217
|
+
* [pageSize]="10"
|
|
218
|
+
* [showPageNumbers]="true"
|
|
219
|
+
* (page)="onPageChange($event)"
|
|
220
|
+
* />
|
|
221
|
+
* ```
|
|
222
|
+
*
|
|
223
|
+
* @example Spread layout (summary left, controls right)
|
|
224
|
+
* ```html
|
|
225
|
+
* <com-paginator
|
|
226
|
+
* [length]="97"
|
|
227
|
+
* [pageSize]="10"
|
|
228
|
+
* [showPageNumbers]="true"
|
|
229
|
+
* layout="spread"
|
|
230
|
+
* (page)="onPageChange($event)"
|
|
231
|
+
* />
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* @example Small size
|
|
235
|
+
* ```html
|
|
236
|
+
* <com-paginator
|
|
237
|
+
* [length]="50"
|
|
238
|
+
* [pageSize]="10"
|
|
239
|
+
* size="sm"
|
|
240
|
+
* (page)="onPageChange($event)"
|
|
241
|
+
* />
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* @example Custom range label (i18n)
|
|
245
|
+
* ```html
|
|
246
|
+
* <com-paginator
|
|
247
|
+
* [length]="100"
|
|
248
|
+
* [pageSize]="10"
|
|
249
|
+
* [rangeLabel]="customLabel"
|
|
250
|
+
* (page)="onPageChange($event)"
|
|
251
|
+
* />
|
|
252
|
+
* ```
|
|
253
|
+
* ```ts
|
|
254
|
+
* customLabel = (page, pageSize, length) => `Seite ${page + 1} von ${Math.ceil(length / pageSize)}`;
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
class ComPaginator {
|
|
258
|
+
// ─── View Queries ───
|
|
259
|
+
/** Page number buttons for keyboard navigation. */
|
|
260
|
+
pageButtons = viewChildren('pageBtn', ...(ngDevMode ? [{ debugName: "pageButtons" }] : []));
|
|
261
|
+
// ─── Inputs ───
|
|
262
|
+
/** Total number of items being paged. */
|
|
263
|
+
length = input(0, ...(ngDevMode ? [{ debugName: "length" }] : []));
|
|
264
|
+
/** Number of items to display per page. */
|
|
265
|
+
pageSize = input(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
266
|
+
/** Current zero-based page index. */
|
|
267
|
+
pageIndex = input(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : []));
|
|
268
|
+
/** Available page size options. Hides selector if empty. */
|
|
269
|
+
pageSizeOptions = input([], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : []));
|
|
270
|
+
/** Whether to show first/last navigation buttons. */
|
|
271
|
+
showFirstLastButtons = input(false, { ...(ngDevMode ? { debugName: "showFirstLastButtons" } : {}), transform: booleanAttribute });
|
|
272
|
+
/** Whether to show numbered page buttons. */
|
|
273
|
+
showPageNumbers = input(false, { ...(ngDevMode ? { debugName: "showPageNumbers" } : {}), transform: booleanAttribute });
|
|
274
|
+
/** Whether all controls are disabled. */
|
|
275
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), transform: booleanAttribute });
|
|
276
|
+
/** Whether to hide the page size selector. */
|
|
277
|
+
hidePageSize = input(false, { ...(ngDevMode ? { debugName: "hidePageSize" } : {}), transform: booleanAttribute });
|
|
278
|
+
/** Size variant. */
|
|
279
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
280
|
+
/** Layout variant. Only applies when showPageNumbers is true. */
|
|
281
|
+
layout = input('compact', ...(ngDevMode ? [{ debugName: "layout" }] : []));
|
|
282
|
+
/** Number of pages to show on each side of the current page. */
|
|
283
|
+
siblingCount = input(1, ...(ngDevMode ? [{ debugName: "siblingCount" }] : []));
|
|
284
|
+
/** Number of pages to always show at the start and end. */
|
|
285
|
+
boundaryCount = input(1, ...(ngDevMode ? [{ debugName: "boundaryCount" }] : []));
|
|
286
|
+
/** Accessible label for the nav element. */
|
|
287
|
+
ariaLabel = input('Pagination', { ...(ngDevMode ? { debugName: "ariaLabel" } : {}), alias: 'aria-label' });
|
|
288
|
+
/** Custom function for range label formatting. */
|
|
289
|
+
rangeLabel = input(defaultRangeLabel, ...(ngDevMode ? [{ debugName: "rangeLabel" }] : []));
|
|
290
|
+
// ─── Outputs ───
|
|
291
|
+
/** Emits when page index or page size changes. */
|
|
292
|
+
page = output();
|
|
293
|
+
// ─── Computed ───
|
|
294
|
+
/** Total number of pages. */
|
|
295
|
+
numberOfPages = computed(() => {
|
|
296
|
+
const size = this.pageSize();
|
|
297
|
+
const len = this.length();
|
|
298
|
+
if (size === 0 || len === 0) {
|
|
299
|
+
return 0;
|
|
300
|
+
}
|
|
301
|
+
return Math.ceil(len / size);
|
|
302
|
+
}, ...(ngDevMode ? [{ debugName: "numberOfPages" }] : []));
|
|
303
|
+
/** Whether there is a previous page. */
|
|
304
|
+
hasPreviousPage = computed(() => {
|
|
305
|
+
return this.pageIndex() > 0 && this.pageSize() > 0;
|
|
306
|
+
}, ...(ngDevMode ? [{ debugName: "hasPreviousPage" }] : []));
|
|
307
|
+
/** Whether there is a next page. */
|
|
308
|
+
hasNextPage = computed(() => {
|
|
309
|
+
const total = this.numberOfPages();
|
|
310
|
+
return total > 0 && this.pageIndex() < total - 1;
|
|
311
|
+
}, ...(ngDevMode ? [{ debugName: "hasNextPage" }] : []));
|
|
312
|
+
/** The formatted range label text. */
|
|
313
|
+
rangeLabelText = computed(() => {
|
|
314
|
+
const fn = this.rangeLabel();
|
|
315
|
+
return fn(this.pageIndex(), this.pageSize(), this.length());
|
|
316
|
+
}, ...(ngDevMode ? [{ debugName: "rangeLabelText" }] : []));
|
|
317
|
+
/** Icon size based on component size. */
|
|
318
|
+
iconSize = computed(() => {
|
|
319
|
+
return this.size() === 'sm' ? 'xs' : 'sm';
|
|
320
|
+
}, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
|
|
321
|
+
/** Unique ID for page size label. */
|
|
322
|
+
pageSizeLabelId = computed(() => {
|
|
323
|
+
return `com-paginator-page-size-label-${uniqueId++}`;
|
|
324
|
+
}, ...(ngDevMode ? [{ debugName: "pageSizeLabelId" }] : []));
|
|
325
|
+
/** Classes for the container. */
|
|
326
|
+
containerClasses = computed(() => paginatorContainerVariants({
|
|
327
|
+
size: this.size(),
|
|
328
|
+
layout: this.showPageNumbers() ? this.layout() : 'compact',
|
|
329
|
+
}), ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
|
|
330
|
+
/** Classes for navigation buttons. */
|
|
331
|
+
buttonClasses = computed(() => paginatorButtonVariants({ size: this.size() }), ...(ngDevMode ? [{ debugName: "buttonClasses" }] : []));
|
|
332
|
+
/** Classes for the range label. */
|
|
333
|
+
rangeLabelClasses = computed(() => paginatorRangeLabelVariants({ size: this.size() }), ...(ngDevMode ? [{ debugName: "rangeLabelClasses" }] : []));
|
|
334
|
+
/** Classes for the page size select. */
|
|
335
|
+
selectClasses = computed(() => paginatorSelectVariants({ size: this.size() }), ...(ngDevMode ? [{ debugName: "selectClasses" }] : []));
|
|
336
|
+
/** Classes for the ellipsis indicator. */
|
|
337
|
+
ellipsisClasses = computed(() => paginatorEllipsisVariants({ size: this.size() }), ...(ngDevMode ? [{ debugName: "ellipsisClasses" }] : []));
|
|
338
|
+
/** Cached classes for active page button. */
|
|
339
|
+
activePageButtonClasses = computed(() => paginatorPageButtonVariants({ size: this.size(), active: true }), ...(ngDevMode ? [{ debugName: "activePageButtonClasses" }] : []));
|
|
340
|
+
/** Cached classes for inactive page button. */
|
|
341
|
+
inactivePageButtonClasses = computed(() => paginatorPageButtonVariants({ size: this.size(), active: false }), ...(ngDevMode ? [{ debugName: "inactivePageButtonClasses" }] : []));
|
|
342
|
+
/**
|
|
343
|
+
* Computed page range for numbered pagination.
|
|
344
|
+
* Returns array like [0, 'ellipsis', 3, 4, 5, 'ellipsis', 9] (zero-indexed).
|
|
345
|
+
*/
|
|
346
|
+
pageRange = computed(() => {
|
|
347
|
+
const totalPages = this.numberOfPages();
|
|
348
|
+
const current = this.pageIndex();
|
|
349
|
+
const siblings = this.siblingCount();
|
|
350
|
+
const boundaries = this.boundaryCount();
|
|
351
|
+
if (totalPages === 0)
|
|
352
|
+
return [];
|
|
353
|
+
// If all pages fit without ellipses, show them all
|
|
354
|
+
const totalSlots = 2 * boundaries + 2 * siblings + 3;
|
|
355
|
+
if (totalPages <= totalSlots) {
|
|
356
|
+
return this.range(0, totalPages - 1);
|
|
357
|
+
}
|
|
358
|
+
// Collect all page indices that should be visible (Set auto-deduplicates)
|
|
359
|
+
const pages = new Set();
|
|
360
|
+
// Boundary pages (always visible)
|
|
361
|
+
for (let i = 0; i < boundaries; i++)
|
|
362
|
+
pages.add(i);
|
|
363
|
+
for (let i = totalPages - boundaries; i < totalPages; i++)
|
|
364
|
+
pages.add(i);
|
|
365
|
+
// Sibling pages around current (including current)
|
|
366
|
+
const siblingStart = Math.max(0, current - siblings);
|
|
367
|
+
const siblingEnd = Math.min(totalPages - 1, current + siblings);
|
|
368
|
+
for (let i = siblingStart; i <= siblingEnd; i++)
|
|
369
|
+
pages.add(i);
|
|
370
|
+
// Convert to sorted array and insert ellipses at gaps
|
|
371
|
+
const sorted = Array.from(pages).sort((a, b) => a - b);
|
|
372
|
+
const result = [];
|
|
373
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
374
|
+
const page = sorted[i];
|
|
375
|
+
const prevPage = sorted[i - 1];
|
|
376
|
+
if (prevPage !== undefined && page - prevPage > 1) {
|
|
377
|
+
result.push('ellipsis');
|
|
378
|
+
}
|
|
379
|
+
result.push(page);
|
|
380
|
+
}
|
|
381
|
+
return result;
|
|
382
|
+
}, ...(ngDevMode ? [{ debugName: "pageRange" }] : []));
|
|
383
|
+
// ─── Navigation Methods ───
|
|
384
|
+
/** Navigate to the first page. */
|
|
385
|
+
firstPage() {
|
|
386
|
+
if (this.hasPreviousPage()) {
|
|
387
|
+
this.emitPageEvent(0);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/** Navigate to the previous page. */
|
|
391
|
+
previousPage() {
|
|
392
|
+
if (this.hasPreviousPage()) {
|
|
393
|
+
this.emitPageEvent(this.pageIndex() - 1);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/** Navigate to the next page. */
|
|
397
|
+
nextPage() {
|
|
398
|
+
if (this.hasNextPage()) {
|
|
399
|
+
this.emitPageEvent(this.pageIndex() + 1);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/** Navigate to the last page. */
|
|
403
|
+
lastPage() {
|
|
404
|
+
if (this.hasNextPage()) {
|
|
405
|
+
this.emitPageEvent(this.numberOfPages() - 1);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/** Navigate to a specific page by index (zero-based). */
|
|
409
|
+
goToPage(pageIndex) {
|
|
410
|
+
if (pageIndex >= 0 && pageIndex < this.numberOfPages() && pageIndex !== this.pageIndex()) {
|
|
411
|
+
this.emitPageEvent(pageIndex);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/** Handle page size selection change. */
|
|
415
|
+
onPageSizeChange(event) {
|
|
416
|
+
const select = event.target;
|
|
417
|
+
const newPageSize = Number(select.value);
|
|
418
|
+
const previousPageSize = this.pageSize();
|
|
419
|
+
const currentPageIndex = this.pageIndex();
|
|
420
|
+
// Calculate new page index to keep the first item on the current page visible
|
|
421
|
+
const startIndex = currentPageIndex * previousPageSize;
|
|
422
|
+
const newPageIndex = Math.floor(startIndex / newPageSize);
|
|
423
|
+
this.page.emit({
|
|
424
|
+
pageIndex: newPageIndex,
|
|
425
|
+
previousPageIndex: currentPageIndex,
|
|
426
|
+
pageSize: newPageSize,
|
|
427
|
+
length: this.length(),
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
/** Handle keyboard navigation within page buttons (roving tabindex). */
|
|
431
|
+
onPageButtonsKeydown(event) {
|
|
432
|
+
const target = event.target;
|
|
433
|
+
// Get enabled buttons from viewChildren query
|
|
434
|
+
const buttons = this.pageButtons()
|
|
435
|
+
.map((ref) => ref.nativeElement)
|
|
436
|
+
.filter((btn) => !btn.disabled);
|
|
437
|
+
const currentIndex = buttons.indexOf(target);
|
|
438
|
+
if (currentIndex === -1)
|
|
439
|
+
return;
|
|
440
|
+
let newIndex;
|
|
441
|
+
switch (event.key) {
|
|
442
|
+
case 'ArrowLeft':
|
|
443
|
+
newIndex = currentIndex > 0 ? currentIndex - 1 : buttons.length - 1;
|
|
444
|
+
break;
|
|
445
|
+
case 'ArrowRight':
|
|
446
|
+
newIndex = currentIndex < buttons.length - 1 ? currentIndex + 1 : 0;
|
|
447
|
+
break;
|
|
448
|
+
case 'Home':
|
|
449
|
+
newIndex = 0;
|
|
450
|
+
break;
|
|
451
|
+
case 'End':
|
|
452
|
+
newIndex = buttons.length - 1;
|
|
453
|
+
break;
|
|
454
|
+
default:
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
event.preventDefault();
|
|
458
|
+
buttons[newIndex]?.focus();
|
|
459
|
+
}
|
|
460
|
+
/** Track function for page items. */
|
|
461
|
+
trackPageItem(index, item) {
|
|
462
|
+
return item === 'ellipsis' ? `ellipsis-${index}` : `page-${item}`;
|
|
463
|
+
}
|
|
464
|
+
// ─── Private Methods ───
|
|
465
|
+
emitPageEvent(newPageIndex) {
|
|
466
|
+
this.page.emit({
|
|
467
|
+
pageIndex: newPageIndex,
|
|
468
|
+
previousPageIndex: this.pageIndex(),
|
|
469
|
+
pageSize: this.pageSize(),
|
|
470
|
+
length: this.length(),
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
/** Generate a range of numbers from start to end (inclusive). */
|
|
474
|
+
range(start, end) {
|
|
475
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
476
|
+
}
|
|
477
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComPaginator, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
478
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ComPaginator, isStandalone: true, selector: "com-paginator", inputs: { length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showFirstLastButtons: { classPropertyName: "showFirstLastButtons", publicName: "showFirstLastButtons", isSignal: true, isRequired: false, transformFunction: null }, showPageNumbers: { classPropertyName: "showPageNumbers", publicName: "showPageNumbers", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidePageSize: { classPropertyName: "hidePageSize", publicName: "hidePageSize", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, boundaryCount: { classPropertyName: "boundaryCount", publicName: "boundaryCount", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, rangeLabel: { classPropertyName: "rangeLabel", publicName: "rangeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "page" }, host: { classAttribute: "com-paginator" }, viewQueries: [{ propertyName: "pageButtons", predicate: ["pageBtn"], descendants: true, isSignal: true }], exportAs: ["comPaginator"], ngImport: i0, template: `
|
|
479
|
+
<nav
|
|
480
|
+
role="navigation"
|
|
481
|
+
[attr.aria-label]="ariaLabel()"
|
|
482
|
+
[class]="containerClasses()"
|
|
483
|
+
>
|
|
484
|
+
@if (showPageNumbers()) {
|
|
485
|
+
<!-- Spread Layout: Summary on left -->
|
|
486
|
+
@if (layout() === 'spread') {
|
|
487
|
+
<span [class]="rangeLabelClasses()">
|
|
488
|
+
{{ rangeLabelText() }}
|
|
489
|
+
</span>
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
<!-- Navigation Controls -->
|
|
493
|
+
<div
|
|
494
|
+
class="flex items-center gap-1"
|
|
495
|
+
role="group"
|
|
496
|
+
aria-label="Page navigation"
|
|
497
|
+
(keydown)="onPageButtonsKeydown($event)"
|
|
498
|
+
>
|
|
499
|
+
<!-- Previous Page -->
|
|
500
|
+
<button
|
|
501
|
+
type="button"
|
|
502
|
+
[class]="buttonClasses()"
|
|
503
|
+
[disabled]="disabled() || !hasPreviousPage()"
|
|
504
|
+
aria-label="Previous page"
|
|
505
|
+
(click)="previousPage()"
|
|
506
|
+
>
|
|
507
|
+
<com-icon name="chevron-left" [size]="iconSize()" />
|
|
508
|
+
</button>
|
|
509
|
+
|
|
510
|
+
<!-- Page Numbers -->
|
|
511
|
+
@for (item of pageRange(); track trackPageItem($index, item)) {
|
|
512
|
+
@if (item === 'ellipsis') {
|
|
513
|
+
<span
|
|
514
|
+
[class]="ellipsisClasses()"
|
|
515
|
+
aria-hidden="true"
|
|
516
|
+
>…</span>
|
|
517
|
+
} @else {
|
|
518
|
+
<button
|
|
519
|
+
#pageBtn
|
|
520
|
+
type="button"
|
|
521
|
+
[class]="item === pageIndex() ? activePageButtonClasses() : inactivePageButtonClasses()"
|
|
522
|
+
[disabled]="disabled()"
|
|
523
|
+
[attr.aria-label]="'Page ' + (item + 1)"
|
|
524
|
+
[attr.aria-current]="item === pageIndex() ? 'page' : null"
|
|
525
|
+
[tabindex]="item === pageIndex() ? 0 : -1"
|
|
526
|
+
(click)="goToPage(item)"
|
|
527
|
+
>{{ item + 1 }}</button>
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
<!-- Next Page -->
|
|
532
|
+
<button
|
|
533
|
+
type="button"
|
|
534
|
+
[class]="buttonClasses()"
|
|
535
|
+
[disabled]="disabled() || !hasNextPage()"
|
|
536
|
+
aria-label="Next page"
|
|
537
|
+
(click)="nextPage()"
|
|
538
|
+
>
|
|
539
|
+
<com-icon name="chevron-right" [size]="iconSize()" />
|
|
540
|
+
</button>
|
|
541
|
+
</div>
|
|
542
|
+
|
|
543
|
+
<!-- Compact Layout: Summary on right -->
|
|
544
|
+
@if (layout() === 'compact') {
|
|
545
|
+
<span [class]="rangeLabelClasses()">
|
|
546
|
+
{{ rangeLabelText() }}
|
|
547
|
+
</span>
|
|
548
|
+
}
|
|
549
|
+
} @else {
|
|
550
|
+
<!-- Original Layout (no page numbers) -->
|
|
551
|
+
|
|
552
|
+
<!-- Page Size Selector -->
|
|
553
|
+
@if (!hidePageSize() && pageSizeOptions().length > 0) {
|
|
554
|
+
<div class="flex items-center gap-2">
|
|
555
|
+
<label
|
|
556
|
+
[id]="pageSizeLabelId()"
|
|
557
|
+
class="text-muted-foreground"
|
|
558
|
+
[class.text-xs]="size() === 'sm'"
|
|
559
|
+
[class.text-sm]="size() === 'md'"
|
|
560
|
+
>
|
|
561
|
+
Items per page:
|
|
562
|
+
</label>
|
|
563
|
+
<div class="relative">
|
|
564
|
+
<select
|
|
565
|
+
[attr.aria-labelledby]="pageSizeLabelId()"
|
|
566
|
+
[class]="selectClasses()"
|
|
567
|
+
[disabled]="disabled()"
|
|
568
|
+
[value]="pageSize()"
|
|
569
|
+
(change)="onPageSizeChange($event)"
|
|
570
|
+
>
|
|
571
|
+
@for (option of pageSizeOptions(); track option) {
|
|
572
|
+
<option [value]="option">{{ option }}</option>
|
|
573
|
+
}
|
|
574
|
+
</select>
|
|
575
|
+
<com-icon
|
|
576
|
+
name="chevron-down"
|
|
577
|
+
size="xs"
|
|
578
|
+
class="pointer-events-none absolute right-1.5 top-1/2 -translate-y-1/2 text-muted-foreground"
|
|
579
|
+
/>
|
|
580
|
+
</div>
|
|
581
|
+
</div>
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
<!-- Range Label -->
|
|
585
|
+
<span [class]="rangeLabelClasses()">
|
|
586
|
+
{{ rangeLabelText() }}
|
|
587
|
+
</span>
|
|
588
|
+
|
|
589
|
+
<!-- Navigation Buttons -->
|
|
590
|
+
<div class="flex items-center gap-1">
|
|
591
|
+
<!-- First Page -->
|
|
592
|
+
@if (showFirstLastButtons()) {
|
|
593
|
+
<button
|
|
594
|
+
type="button"
|
|
595
|
+
[class]="buttonClasses()"
|
|
596
|
+
[disabled]="disabled() || !hasPreviousPage()"
|
|
597
|
+
aria-label="First page"
|
|
598
|
+
(click)="firstPage()"
|
|
599
|
+
>
|
|
600
|
+
<com-icon name="chevrons-left" [size]="iconSize()" />
|
|
601
|
+
</button>
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
<!-- Previous Page -->
|
|
605
|
+
<button
|
|
606
|
+
type="button"
|
|
607
|
+
[class]="buttonClasses()"
|
|
608
|
+
[disabled]="disabled() || !hasPreviousPage()"
|
|
609
|
+
aria-label="Previous page"
|
|
610
|
+
(click)="previousPage()"
|
|
611
|
+
>
|
|
612
|
+
<com-icon name="chevron-left" [size]="iconSize()" />
|
|
613
|
+
</button>
|
|
614
|
+
|
|
615
|
+
<!-- Next Page -->
|
|
616
|
+
<button
|
|
617
|
+
type="button"
|
|
618
|
+
[class]="buttonClasses()"
|
|
619
|
+
[disabled]="disabled() || !hasNextPage()"
|
|
620
|
+
aria-label="Next page"
|
|
621
|
+
(click)="nextPage()"
|
|
622
|
+
>
|
|
623
|
+
<com-icon name="chevron-right" [size]="iconSize()" />
|
|
624
|
+
</button>
|
|
625
|
+
|
|
626
|
+
<!-- Last Page -->
|
|
627
|
+
@if (showFirstLastButtons()) {
|
|
628
|
+
<button
|
|
629
|
+
type="button"
|
|
630
|
+
[class]="buttonClasses()"
|
|
631
|
+
[disabled]="disabled() || !hasNextPage()"
|
|
632
|
+
aria-label="Last page"
|
|
633
|
+
(click)="lastPage()"
|
|
634
|
+
>
|
|
635
|
+
<com-icon name="chevrons-right" [size]="iconSize()" />
|
|
636
|
+
</button>
|
|
637
|
+
}
|
|
638
|
+
</div>
|
|
639
|
+
}
|
|
640
|
+
</nav>
|
|
641
|
+
`, isInline: true, styles: ["com-paginator{display:block}\n"], dependencies: [{ kind: "component", type: ComIcon, selector: "com-icon", inputs: ["name", "img", "color", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
642
|
+
}
|
|
643
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComPaginator, decorators: [{
|
|
644
|
+
type: Component,
|
|
645
|
+
args: [{ selector: 'com-paginator', exportAs: 'comPaginator', template: `
|
|
646
|
+
<nav
|
|
647
|
+
role="navigation"
|
|
648
|
+
[attr.aria-label]="ariaLabel()"
|
|
649
|
+
[class]="containerClasses()"
|
|
650
|
+
>
|
|
651
|
+
@if (showPageNumbers()) {
|
|
652
|
+
<!-- Spread Layout: Summary on left -->
|
|
653
|
+
@if (layout() === 'spread') {
|
|
654
|
+
<span [class]="rangeLabelClasses()">
|
|
655
|
+
{{ rangeLabelText() }}
|
|
656
|
+
</span>
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
<!-- Navigation Controls -->
|
|
660
|
+
<div
|
|
661
|
+
class="flex items-center gap-1"
|
|
662
|
+
role="group"
|
|
663
|
+
aria-label="Page navigation"
|
|
664
|
+
(keydown)="onPageButtonsKeydown($event)"
|
|
665
|
+
>
|
|
666
|
+
<!-- Previous Page -->
|
|
667
|
+
<button
|
|
668
|
+
type="button"
|
|
669
|
+
[class]="buttonClasses()"
|
|
670
|
+
[disabled]="disabled() || !hasPreviousPage()"
|
|
671
|
+
aria-label="Previous page"
|
|
672
|
+
(click)="previousPage()"
|
|
673
|
+
>
|
|
674
|
+
<com-icon name="chevron-left" [size]="iconSize()" />
|
|
675
|
+
</button>
|
|
676
|
+
|
|
677
|
+
<!-- Page Numbers -->
|
|
678
|
+
@for (item of pageRange(); track trackPageItem($index, item)) {
|
|
679
|
+
@if (item === 'ellipsis') {
|
|
680
|
+
<span
|
|
681
|
+
[class]="ellipsisClasses()"
|
|
682
|
+
aria-hidden="true"
|
|
683
|
+
>…</span>
|
|
684
|
+
} @else {
|
|
685
|
+
<button
|
|
686
|
+
#pageBtn
|
|
687
|
+
type="button"
|
|
688
|
+
[class]="item === pageIndex() ? activePageButtonClasses() : inactivePageButtonClasses()"
|
|
689
|
+
[disabled]="disabled()"
|
|
690
|
+
[attr.aria-label]="'Page ' + (item + 1)"
|
|
691
|
+
[attr.aria-current]="item === pageIndex() ? 'page' : null"
|
|
692
|
+
[tabindex]="item === pageIndex() ? 0 : -1"
|
|
693
|
+
(click)="goToPage(item)"
|
|
694
|
+
>{{ item + 1 }}</button>
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
<!-- Next Page -->
|
|
699
|
+
<button
|
|
700
|
+
type="button"
|
|
701
|
+
[class]="buttonClasses()"
|
|
702
|
+
[disabled]="disabled() || !hasNextPage()"
|
|
703
|
+
aria-label="Next page"
|
|
704
|
+
(click)="nextPage()"
|
|
705
|
+
>
|
|
706
|
+
<com-icon name="chevron-right" [size]="iconSize()" />
|
|
707
|
+
</button>
|
|
708
|
+
</div>
|
|
709
|
+
|
|
710
|
+
<!-- Compact Layout: Summary on right -->
|
|
711
|
+
@if (layout() === 'compact') {
|
|
712
|
+
<span [class]="rangeLabelClasses()">
|
|
713
|
+
{{ rangeLabelText() }}
|
|
714
|
+
</span>
|
|
715
|
+
}
|
|
716
|
+
} @else {
|
|
717
|
+
<!-- Original Layout (no page numbers) -->
|
|
718
|
+
|
|
719
|
+
<!-- Page Size Selector -->
|
|
720
|
+
@if (!hidePageSize() && pageSizeOptions().length > 0) {
|
|
721
|
+
<div class="flex items-center gap-2">
|
|
722
|
+
<label
|
|
723
|
+
[id]="pageSizeLabelId()"
|
|
724
|
+
class="text-muted-foreground"
|
|
725
|
+
[class.text-xs]="size() === 'sm'"
|
|
726
|
+
[class.text-sm]="size() === 'md'"
|
|
727
|
+
>
|
|
728
|
+
Items per page:
|
|
729
|
+
</label>
|
|
730
|
+
<div class="relative">
|
|
731
|
+
<select
|
|
732
|
+
[attr.aria-labelledby]="pageSizeLabelId()"
|
|
733
|
+
[class]="selectClasses()"
|
|
734
|
+
[disabled]="disabled()"
|
|
735
|
+
[value]="pageSize()"
|
|
736
|
+
(change)="onPageSizeChange($event)"
|
|
737
|
+
>
|
|
738
|
+
@for (option of pageSizeOptions(); track option) {
|
|
739
|
+
<option [value]="option">{{ option }}</option>
|
|
740
|
+
}
|
|
741
|
+
</select>
|
|
742
|
+
<com-icon
|
|
743
|
+
name="chevron-down"
|
|
744
|
+
size="xs"
|
|
745
|
+
class="pointer-events-none absolute right-1.5 top-1/2 -translate-y-1/2 text-muted-foreground"
|
|
746
|
+
/>
|
|
747
|
+
</div>
|
|
748
|
+
</div>
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
<!-- Range Label -->
|
|
752
|
+
<span [class]="rangeLabelClasses()">
|
|
753
|
+
{{ rangeLabelText() }}
|
|
754
|
+
</span>
|
|
755
|
+
|
|
756
|
+
<!-- Navigation Buttons -->
|
|
757
|
+
<div class="flex items-center gap-1">
|
|
758
|
+
<!-- First Page -->
|
|
759
|
+
@if (showFirstLastButtons()) {
|
|
760
|
+
<button
|
|
761
|
+
type="button"
|
|
762
|
+
[class]="buttonClasses()"
|
|
763
|
+
[disabled]="disabled() || !hasPreviousPage()"
|
|
764
|
+
aria-label="First page"
|
|
765
|
+
(click)="firstPage()"
|
|
766
|
+
>
|
|
767
|
+
<com-icon name="chevrons-left" [size]="iconSize()" />
|
|
768
|
+
</button>
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
<!-- Previous Page -->
|
|
772
|
+
<button
|
|
773
|
+
type="button"
|
|
774
|
+
[class]="buttonClasses()"
|
|
775
|
+
[disabled]="disabled() || !hasPreviousPage()"
|
|
776
|
+
aria-label="Previous page"
|
|
777
|
+
(click)="previousPage()"
|
|
778
|
+
>
|
|
779
|
+
<com-icon name="chevron-left" [size]="iconSize()" />
|
|
780
|
+
</button>
|
|
781
|
+
|
|
782
|
+
<!-- Next Page -->
|
|
783
|
+
<button
|
|
784
|
+
type="button"
|
|
785
|
+
[class]="buttonClasses()"
|
|
786
|
+
[disabled]="disabled() || !hasNextPage()"
|
|
787
|
+
aria-label="Next page"
|
|
788
|
+
(click)="nextPage()"
|
|
789
|
+
>
|
|
790
|
+
<com-icon name="chevron-right" [size]="iconSize()" />
|
|
791
|
+
</button>
|
|
792
|
+
|
|
793
|
+
<!-- Last Page -->
|
|
794
|
+
@if (showFirstLastButtons()) {
|
|
795
|
+
<button
|
|
796
|
+
type="button"
|
|
797
|
+
[class]="buttonClasses()"
|
|
798
|
+
[disabled]="disabled() || !hasNextPage()"
|
|
799
|
+
aria-label="Last page"
|
|
800
|
+
(click)="lastPage()"
|
|
801
|
+
>
|
|
802
|
+
<com-icon name="chevrons-right" [size]="iconSize()" />
|
|
803
|
+
</button>
|
|
804
|
+
}
|
|
805
|
+
</div>
|
|
806
|
+
}
|
|
807
|
+
</nav>
|
|
808
|
+
`, imports: [ComIcon], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
809
|
+
class: 'com-paginator',
|
|
810
|
+
}, styles: ["com-paginator{display:block}\n"] }]
|
|
811
|
+
}], propDecorators: { pageButtons: [{ type: i0.ViewChildren, args: ['pageBtn', { isSignal: true }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], showFirstLastButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFirstLastButtons", required: false }] }], showPageNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPageNumbers", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hidePageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePageSize", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], boundaryCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundaryCount", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], rangeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeLabel", required: false }] }], page: [{ type: i0.Output, args: ["page"] }] } });
|
|
812
|
+
/** Counter for generating unique IDs. */
|
|
813
|
+
let uniqueId = 0;
|
|
814
|
+
|
|
815
|
+
// Public API for the paginator component
|
|
816
|
+
// Main component
|
|
817
|
+
|
|
818
|
+
/**
|
|
819
|
+
* Generated bundle index. Do not edit.
|
|
820
|
+
*/
|
|
821
|
+
|
|
822
|
+
export { ComPaginator, defaultRangeLabel, paginatorButtonVariants, paginatorContainerVariants, paginatorEllipsisVariants, paginatorPageButtonVariants, paginatorRangeLabelVariants, paginatorSelectVariants };
|
|
823
|
+
//# sourceMappingURL=ngx-com-components-paginator.mjs.map
|