forty-cdk 0.2.0 → 0.3.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.
Files changed (220) hide show
  1. package/accordion/README.md +122 -0
  2. package/aspect-ratio/README.md +76 -0
  3. package/avatar/README.md +100 -0
  4. package/breadcrumbs/README.md +49 -0
  5. package/breakpoints/README.md +81 -0
  6. package/button/README.md +49 -0
  7. package/calendar/README.md +458 -0
  8. package/carousel/README.md +358 -0
  9. package/checkbox/README.md +146 -0
  10. package/combobox/README.md +535 -0
  11. package/context-menu/README.md +139 -0
  12. package/date-field/README.md +184 -0
  13. package/date-picker/README.md +338 -0
  14. package/dialog/README.md +388 -0
  15. package/disclosure/README.md +114 -0
  16. package/drag-drop/README.md +359 -0
  17. package/drawer/README.md +560 -0
  18. package/dropdown-menu/README.md +176 -0
  19. package/fesm2022/forty-cdk-accordion.mjs +348 -0
  20. package/fesm2022/forty-cdk-accordion.mjs.map +1 -0
  21. package/fesm2022/forty-cdk-aspect-ratio.mjs +74 -0
  22. package/fesm2022/forty-cdk-aspect-ratio.mjs.map +1 -0
  23. package/fesm2022/forty-cdk-avatar.mjs +308 -0
  24. package/fesm2022/forty-cdk-avatar.mjs.map +1 -0
  25. package/fesm2022/forty-cdk-breadcrumbs.mjs +125 -0
  26. package/fesm2022/forty-cdk-breadcrumbs.mjs.map +1 -0
  27. package/fesm2022/forty-cdk-breakpoints.mjs +117 -0
  28. package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -0
  29. package/fesm2022/forty-cdk-button.mjs +134 -0
  30. package/fesm2022/forty-cdk-button.mjs.map +1 -0
  31. package/fesm2022/forty-cdk-calendar.mjs +2034 -0
  32. package/fesm2022/forty-cdk-calendar.mjs.map +1 -0
  33. package/fesm2022/forty-cdk-carousel.mjs +968 -0
  34. package/fesm2022/forty-cdk-carousel.mjs.map +1 -0
  35. package/fesm2022/forty-cdk-checkbox.mjs +226 -0
  36. package/fesm2022/forty-cdk-checkbox.mjs.map +1 -0
  37. package/fesm2022/forty-cdk-combobox.mjs +2596 -0
  38. package/fesm2022/forty-cdk-combobox.mjs.map +1 -0
  39. package/fesm2022/forty-cdk-context-menu.mjs +413 -0
  40. package/fesm2022/forty-cdk-context-menu.mjs.map +1 -0
  41. package/fesm2022/forty-cdk-core.mjs +9022 -0
  42. package/fesm2022/forty-cdk-core.mjs.map +1 -0
  43. package/fesm2022/forty-cdk-date-field.mjs +744 -0
  44. package/fesm2022/forty-cdk-date-field.mjs.map +1 -0
  45. package/fesm2022/forty-cdk-date-picker.mjs +1011 -0
  46. package/fesm2022/forty-cdk-date-picker.mjs.map +1 -0
  47. package/fesm2022/forty-cdk-dialog.mjs +707 -0
  48. package/fesm2022/forty-cdk-dialog.mjs.map +1 -0
  49. package/fesm2022/forty-cdk-disclosure.mjs +190 -0
  50. package/fesm2022/forty-cdk-disclosure.mjs.map +1 -0
  51. package/fesm2022/forty-cdk-drag-drop.mjs +1180 -0
  52. package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -0
  53. package/fesm2022/forty-cdk-drawer.mjs +1641 -0
  54. package/fesm2022/forty-cdk-drawer.mjs.map +1 -0
  55. package/fesm2022/forty-cdk-dropdown-menu.mjs +350 -0
  56. package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -0
  57. package/fesm2022/forty-cdk-field.mjs +425 -0
  58. package/fesm2022/forty-cdk-field.mjs.map +1 -0
  59. package/fesm2022/forty-cdk-fieldset.mjs +164 -0
  60. package/fesm2022/forty-cdk-fieldset.mjs.map +1 -0
  61. package/fesm2022/forty-cdk-file-upload.mjs +221 -0
  62. package/fesm2022/forty-cdk-file-upload.mjs.map +1 -0
  63. package/fesm2022/forty-cdk-hover-card.mjs +496 -0
  64. package/fesm2022/forty-cdk-hover-card.mjs.map +1 -0
  65. package/fesm2022/forty-cdk-input.mjs +274 -0
  66. package/fesm2022/forty-cdk-input.mjs.map +1 -0
  67. package/fesm2022/forty-cdk-internationalized-date.mjs +1 -1
  68. package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
  69. package/fesm2022/forty-cdk-listbox.mjs +1279 -0
  70. package/fesm2022/forty-cdk-listbox.mjs.map +1 -0
  71. package/fesm2022/forty-cdk-menu.mjs +1439 -0
  72. package/fesm2022/forty-cdk-menu.mjs.map +1 -0
  73. package/fesm2022/forty-cdk-menubar.mjs +787 -0
  74. package/fesm2022/forty-cdk-menubar.mjs.map +1 -0
  75. package/fesm2022/forty-cdk-meter.mjs +211 -0
  76. package/fesm2022/forty-cdk-meter.mjs.map +1 -0
  77. package/fesm2022/forty-cdk-navigation-menu.mjs +1145 -0
  78. package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -0
  79. package/fesm2022/forty-cdk-number-input.mjs +559 -0
  80. package/fesm2022/forty-cdk-number-input.mjs.map +1 -0
  81. package/fesm2022/forty-cdk-otp-input.mjs +527 -0
  82. package/fesm2022/forty-cdk-otp-input.mjs.map +1 -0
  83. package/fesm2022/forty-cdk-pagination.mjs +323 -0
  84. package/fesm2022/forty-cdk-pagination.mjs.map +1 -0
  85. package/fesm2022/forty-cdk-pane-resizer.mjs +297 -0
  86. package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -0
  87. package/fesm2022/forty-cdk-popover.mjs +698 -0
  88. package/fesm2022/forty-cdk-popover.mjs.map +1 -0
  89. package/fesm2022/forty-cdk-progress.mjs +226 -0
  90. package/fesm2022/forty-cdk-progress.mjs.map +1 -0
  91. package/fesm2022/forty-cdk-radio-group.mjs +378 -0
  92. package/fesm2022/forty-cdk-radio-group.mjs.map +1 -0
  93. package/fesm2022/forty-cdk-scroll-area.mjs +640 -0
  94. package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -0
  95. package/fesm2022/forty-cdk-search.mjs +205 -0
  96. package/fesm2022/forty-cdk-search.mjs.map +1 -0
  97. package/fesm2022/forty-cdk-select.mjs +1661 -0
  98. package/fesm2022/forty-cdk-select.mjs.map +1 -0
  99. package/fesm2022/forty-cdk-separator.mjs +82 -0
  100. package/fesm2022/forty-cdk-separator.mjs.map +1 -0
  101. package/fesm2022/forty-cdk-signal-forms.mjs +97 -0
  102. package/fesm2022/forty-cdk-signal-forms.mjs.map +1 -0
  103. package/fesm2022/forty-cdk-slider.mjs +803 -0
  104. package/fesm2022/forty-cdk-slider.mjs.map +1 -0
  105. package/fesm2022/forty-cdk-stepper.mjs +886 -0
  106. package/fesm2022/forty-cdk-stepper.mjs.map +1 -0
  107. package/fesm2022/forty-cdk-switch.mjs +137 -0
  108. package/fesm2022/forty-cdk-switch.mjs.map +1 -0
  109. package/fesm2022/forty-cdk-table.mjs +1518 -0
  110. package/fesm2022/forty-cdk-table.mjs.map +1 -0
  111. package/fesm2022/forty-cdk-tabs.mjs +400 -0
  112. package/fesm2022/forty-cdk-tabs.mjs.map +1 -0
  113. package/fesm2022/forty-cdk-time-field.mjs +593 -0
  114. package/fesm2022/forty-cdk-time-field.mjs.map +1 -0
  115. package/fesm2022/forty-cdk-time-picker.mjs +1013 -0
  116. package/fesm2022/forty-cdk-time-picker.mjs.map +1 -0
  117. package/fesm2022/forty-cdk-toast.mjs +1153 -0
  118. package/fesm2022/forty-cdk-toast.mjs.map +1 -0
  119. package/fesm2022/forty-cdk-toggle.mjs +516 -0
  120. package/fesm2022/forty-cdk-toggle.mjs.map +1 -0
  121. package/fesm2022/forty-cdk-toolbar.mjs +374 -0
  122. package/fesm2022/forty-cdk-toolbar.mjs.map +1 -0
  123. package/fesm2022/forty-cdk-tooltip.mjs +672 -0
  124. package/fesm2022/forty-cdk-tooltip.mjs.map +1 -0
  125. package/fesm2022/forty-cdk-tree.mjs +2007 -0
  126. package/fesm2022/forty-cdk-tree.mjs.map +1 -0
  127. package/fesm2022/forty-cdk-virtualization.mjs +1 -1
  128. package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
  129. package/fesm2022/forty-cdk.mjs +0 -43310
  130. package/fesm2022/forty-cdk.mjs.map +1 -1
  131. package/field/README.md +97 -0
  132. package/fieldset/README.md +86 -0
  133. package/file-upload/README.md +73 -0
  134. package/hover-card/README.md +171 -0
  135. package/input/README.md +156 -0
  136. package/listbox/README.md +424 -0
  137. package/menu/README.md +181 -0
  138. package/menubar/README.md +140 -0
  139. package/meter/README.md +128 -0
  140. package/navigation-menu/README.md +253 -0
  141. package/number-input/README.md +171 -0
  142. package/otp-input/README.md +198 -0
  143. package/package.json +213 -1
  144. package/pagination/README.md +61 -0
  145. package/pane-resizer/README.md +136 -0
  146. package/popover/README.md +262 -0
  147. package/progress/README.md +115 -0
  148. package/radio-group/README.md +129 -0
  149. package/scroll-area/README.md +184 -0
  150. package/search/README.md +42 -0
  151. package/select/README.md +488 -0
  152. package/separator/README.md +84 -0
  153. package/signal-forms/README.md +72 -0
  154. package/slider/README.md +152 -0
  155. package/stepper/README.md +292 -0
  156. package/switch/README.md +116 -0
  157. package/table/README.md +769 -0
  158. package/tabs/README.md +130 -0
  159. package/time-field/README.md +157 -0
  160. package/time-picker/README.md +172 -0
  161. package/toast/README.md +398 -0
  162. package/toggle/README.md +224 -0
  163. package/toolbar/README.md +109 -0
  164. package/tooltip/README.md +274 -0
  165. package/tree/README.md +708 -0
  166. package/types/forty-cdk-accordion.d.ts +242 -0
  167. package/types/forty-cdk-aspect-ratio.d.ts +59 -0
  168. package/types/forty-cdk-avatar.d.ts +133 -0
  169. package/types/forty-cdk-breadcrumbs.d.ts +92 -0
  170. package/types/forty-cdk-breakpoints.d.ts +141 -0
  171. package/types/forty-cdk-button.d.ts +80 -0
  172. package/types/forty-cdk-calendar.d.ts +914 -0
  173. package/types/forty-cdk-carousel.d.ts +530 -0
  174. package/types/forty-cdk-checkbox.d.ts +141 -0
  175. package/types/forty-cdk-combobox.d.ts +1259 -0
  176. package/types/forty-cdk-context-menu.d.ts +313 -0
  177. package/types/forty-cdk-core.d.ts +5774 -0
  178. package/types/forty-cdk-date-field.d.ts +307 -0
  179. package/types/forty-cdk-date-picker.d.ts +622 -0
  180. package/types/forty-cdk-dialog.d.ts +546 -0
  181. package/types/forty-cdk-disclosure.d.ts +127 -0
  182. package/types/forty-cdk-drag-drop.d.ts +456 -0
  183. package/types/forty-cdk-drawer.d.ts +871 -0
  184. package/types/forty-cdk-dropdown-menu.d.ts +242 -0
  185. package/types/forty-cdk-field.d.ts +236 -0
  186. package/types/forty-cdk-fieldset.d.ts +119 -0
  187. package/types/forty-cdk-file-upload.d.ts +124 -0
  188. package/types/forty-cdk-hover-card.d.ts +320 -0
  189. package/types/forty-cdk-input.d.ts +169 -0
  190. package/types/forty-cdk-internationalized-date.d.ts +1 -1
  191. package/types/forty-cdk-listbox.d.ts +513 -0
  192. package/types/forty-cdk-menu.d.ts +629 -0
  193. package/types/forty-cdk-menubar.d.ts +451 -0
  194. package/types/forty-cdk-meter.d.ts +122 -0
  195. package/types/forty-cdk-navigation-menu.d.ts +514 -0
  196. package/types/forty-cdk-number-input.d.ts +319 -0
  197. package/types/forty-cdk-otp-input.d.ts +248 -0
  198. package/types/forty-cdk-pagination.d.ts +214 -0
  199. package/types/forty-cdk-pane-resizer.d.ts +145 -0
  200. package/types/forty-cdk-popover.d.ts +509 -0
  201. package/types/forty-cdk-progress.d.ts +143 -0
  202. package/types/forty-cdk-radio-group.d.ts +222 -0
  203. package/types/forty-cdk-scroll-area.d.ts +258 -0
  204. package/types/forty-cdk-search.d.ts +142 -0
  205. package/types/forty-cdk-select.d.ts +899 -0
  206. package/types/forty-cdk-separator.d.ts +59 -0
  207. package/types/forty-cdk-signal-forms.d.ts +58 -0
  208. package/types/forty-cdk-slider.d.ts +379 -0
  209. package/types/forty-cdk-stepper.d.ts +650 -0
  210. package/types/forty-cdk-switch.d.ts +87 -0
  211. package/types/forty-cdk-table.d.ts +723 -0
  212. package/types/forty-cdk-tabs.d.ts +235 -0
  213. package/types/forty-cdk-time-field.d.ts +307 -0
  214. package/types/forty-cdk-time-picker.d.ts +578 -0
  215. package/types/forty-cdk-toast.d.ts +598 -0
  216. package/types/forty-cdk-toggle.d.ts +310 -0
  217. package/types/forty-cdk-toolbar.d.ts +217 -0
  218. package/types/forty-cdk-tooltip.d.ts +436 -0
  219. package/types/forty-cdk-tree.d.ts +688 -0
  220. package/types/forty-cdk.d.ts +1 -19743
@@ -0,0 +1,323 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, model, input, numberAttribute, booleanAttribute, computed, Directive } from '@angular/core';
3
+ import { createDefaults, injectTextDirection, clamp, reflectDisabled } from 'forty-cdk/core';
4
+
5
+ /** DI token providing the pagination context to descendant pieces. */
6
+ const FOR_PAGINATION_CONTEXT = new InjectionToken('FOR_PAGINATION_CONTEXT');
7
+ function injectPaginationContext(piece) {
8
+ const ctx = inject(FOR_PAGINATION_CONTEXT, { optional: true });
9
+ if (!ctx) {
10
+ throw new Error(`[forty-cdk/pagination] ${piece} must be used inside a [forPagination] element.`);
11
+ }
12
+ return ctx;
13
+ }
14
+
15
+ /**
16
+ * Library fallback for pagination defaults, read at the root injector when no
17
+ * consumer has called `provideForPaginationDefaults`. Exported for the shared
18
+ * defaults-contract spec; not re-exported from the primitive's public entry.
19
+ */
20
+ const FOR_PAGINATION_FALLBACK_DEFAULTS = {
21
+ siblingCount: 1,
22
+ boundaryCount: 1,
23
+ };
24
+ const { token, provideDefaults } = createDefaults('FOR_PAGINATION_DEFAULTS', FOR_PAGINATION_FALLBACK_DEFAULTS);
25
+ /** Token holding the resolved pagination defaults for the current scope. */
26
+ const FOR_PAGINATION_DEFAULTS = token;
27
+ /**
28
+ * Configures forty-cdk pagination defaults for this injector scope. Partial
29
+ * overrides inherit unspecified keys from the parent scope (or library defaults
30
+ * at the root).
31
+ */
32
+ function provideForPaginationDefaults(defaults = {}) {
33
+ return provideDefaults(defaults);
34
+ }
35
+
36
+ function range(start, end) {
37
+ const length = end - start + 1;
38
+ return Array.from({ length }, (_, i) => start + i);
39
+ }
40
+ /**
41
+ * Compute the visible page list (with ellipsis gaps) for the given pagination
42
+ * state, using the standard boundary/sibling algorithm:
43
+ *
44
+ * - `boundaryCount` pages are always shown at each end.
45
+ * - `siblingCount` pages are shown on each side of the current `page`.
46
+ * - Runs of hidden pages collapse to a single `'ellipsis'` entry — except a gap
47
+ * of exactly one page, which is shown as that page rather than an ellipsis.
48
+ *
49
+ * Returns an empty list when `count` is not positive. All page numbers are
50
+ * 1-based. Internal — not re-exported from `public-api.ts`.
51
+ */
52
+ function computePaginationItems(opts) {
53
+ const { page, count, siblingCount, boundaryCount } = opts;
54
+ if (count <= 0) {
55
+ return [];
56
+ }
57
+ const startPages = range(1, Math.min(boundaryCount, count));
58
+ const endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count);
59
+ const siblingsStart = Math.max(Math.min(page - siblingCount, count - boundaryCount - siblingCount * 2 - 1), boundaryCount + 2);
60
+ const siblingsEnd = Math.min(Math.max(page + siblingCount, boundaryCount + siblingCount * 2 + 2), endPages.length > 0 ? endPages[0] - 2 : count - 1);
61
+ const tokens = [
62
+ ...startPages,
63
+ ...(siblingsStart > boundaryCount + 2
64
+ ? ['ellipsis']
65
+ : boundaryCount + 1 < count - boundaryCount
66
+ ? [boundaryCount + 1]
67
+ : []),
68
+ ...range(siblingsStart, siblingsEnd),
69
+ ...(siblingsEnd < count - boundaryCount - 1
70
+ ? ['ellipsis']
71
+ : count - boundaryCount > boundaryCount
72
+ ? [count - boundaryCount]
73
+ : []),
74
+ ...endPages,
75
+ ];
76
+ return tokens.map((t) => (t === 'ellipsis' ? { type: 'ellipsis' } : { type: 'page', value: t }));
77
+ }
78
+
79
+ /**
80
+ * Headless pagination navigation landmark, implementing the
81
+ * [WAI-ARIA `navigation` landmark](https://www.w3.org/WAI/ARIA/apg/patterns/landmarks/examples/navigation.html)
82
+ * with [`aria-current="page"`](https://www.w3.org/TR/wai-aria-1.2/#aria-current) on the active page.
83
+ *
84
+ * Derives the visible page list (with ellipsis gaps) from `page`, `count`,
85
+ * `siblingCount`, and `boundaryCount`. Exposes `items()`, `isFirst()`,
86
+ * `isLast()`, and navigation methods for the consumer template to render.
87
+ *
88
+ * There is no roving tabindex — each page button, previous, and next are their
89
+ * own tab stops. RTL is visual-only: the resolved `dir` reflects on the host
90
+ * for CSS; navigation semantics (previous = decrement, next = increment) never
91
+ * change based on direction.
92
+ *
93
+ * @example
94
+ * ```html
95
+ * <nav forPagination [(page)]="page" [count]="20" ariaLabel="Pagination" #pg="forPagination">
96
+ * <button forPaginationPrevious ariaLabel="Previous page">‹</button>
97
+ * @for (item of pg.items(); track $index) {
98
+ * @if (item.type === 'page') {
99
+ * <button forPaginationItem [page]="item.value!">{{ item.value }}</button>
100
+ * } @else {
101
+ * <span aria-hidden="true">…</span>
102
+ * }
103
+ * }
104
+ * <button forPaginationNext ariaLabel="Next page">›</button>
105
+ * </nav>
106
+ * ```
107
+ */
108
+ class ForPagination {
109
+ #defaults = inject(FOR_PAGINATION_DEFAULTS);
110
+ /**
111
+ * Current 1-based page number. Two-way bindable via `[(page)]`. The implicit
112
+ * `pageChange` output emits whenever the directive updates this value (via
113
+ * clicks, previous, or next). Do not add a separate `pageChange` output.
114
+ */
115
+ page = model(1, /* @ts-ignore */
116
+ ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
117
+ /**
118
+ * Total number of pages. Always bind as `[count]="n"` (a number, not a
119
+ * string). Required.
120
+ */
121
+ count = input.required(/* @ts-ignore */
122
+ ...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
123
+ /**
124
+ * Pages shown on each side of the current page before collapsing to an
125
+ * ellipsis. Default read from `provideForPaginationDefaults` for the
126
+ * surrounding scope (library fallback: `1`).
127
+ */
128
+ siblingCount = input(this.#defaults.siblingCount, { ...(ngDevMode ? { debugName: "siblingCount" } : /* istanbul ignore next */ {}), transform: numberAttribute });
129
+ /**
130
+ * Pages always shown at each end (first and last). Default read from
131
+ * `provideForPaginationDefaults` for the surrounding scope (library
132
+ * fallback: `1`).
133
+ */
134
+ boundaryCount = input(this.#defaults.boundaryCount, { ...(ngDevMode ? { debugName: "boundaryCount" } : /* istanbul ignore next */ {}), transform: numberAttribute });
135
+ /** Whether the entire pagination control is disabled. */
136
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
137
+ /**
138
+ * Writing direction. When unset (default `null`), the inherited ambient
139
+ * direction is resolved from the nearest ancestor carrying a `dir` attribute
140
+ * (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]` always wins.
141
+ * The resolved value is reflected to the host `dir` attribute. RTL affects
142
+ * visual layout only — previous/next semantics do not change.
143
+ */
144
+ _dirInput = input(null, { ...(ngDevMode ? { debugName: "_dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
145
+ dir = injectTextDirection(this._dirInput);
146
+ /**
147
+ * Accessible label for the navigation landmark. Supply this (or point
148
+ * `aria-labelledby` at a visible label element) when the page contains more
149
+ * than one `<nav>`. A `null` or empty value emits no attribute.
150
+ */
151
+ ariaLabel = input(null, /* @ts-ignore */
152
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
153
+ /** The computed visible-page list (page numbers + ellipsis gaps). */
154
+ items = computed(() => computePaginationItems({
155
+ page: this.page(),
156
+ count: this.count(),
157
+ siblingCount: this.siblingCount(),
158
+ boundaryCount: this.boundaryCount(),
159
+ }), /* @ts-ignore */
160
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
161
+ /** Whether the current page is the first (no previous page). */
162
+ isFirst = computed(() => this.page() <= 1, /* @ts-ignore */
163
+ ...(ngDevMode ? [{ debugName: "isFirst" }] : /* istanbul ignore next */ []));
164
+ /** Whether the current page is the last (no next page). */
165
+ isLast = computed(() => this.page() >= this.count(), /* @ts-ignore */
166
+ ...(ngDevMode ? [{ debugName: "isLast" }] : /* istanbul ignore next */ []));
167
+ /**
168
+ * Navigate to `page`, clamped to `[1, count]`. No-op when disabled.
169
+ */
170
+ goToPage(page) {
171
+ if (this.disabled()) {
172
+ return;
173
+ }
174
+ const clamped = clamp(page, 1, Math.max(1, this.count()));
175
+ if (clamped !== this.page()) {
176
+ this.page.set(clamped);
177
+ }
178
+ }
179
+ /** Navigate to the previous page. No-op at the first page or when disabled. */
180
+ previous() {
181
+ this.goToPage(this.page() - 1);
182
+ }
183
+ /** Navigate to the next page. No-op at the last page or when disabled. */
184
+ next() {
185
+ this.goToPage(this.page() + 1);
186
+ }
187
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPagination, deps: [], target: i0.ɵɵFactoryTarget.Directive });
188
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForPagination, isStandalone: true, selector: "[forPagination]", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: true, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, boundaryCount: { classPropertyName: "boundaryCount", publicName: "boundaryCount", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, _dirInput: { classPropertyName: "_dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange" }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel() || null", "attr.data-disabled": "disabled() ? \"\" : null", "attr.dir": "dir()" } }, providers: [{ provide: FOR_PAGINATION_CONTEXT, useExisting: ForPagination }], exportAs: ["forPagination"], ngImport: i0 });
189
+ }
190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPagination, decorators: [{
191
+ type: Directive,
192
+ args: [{
193
+ selector: '[forPagination]',
194
+ exportAs: 'forPagination',
195
+ host: {
196
+ role: 'navigation',
197
+ '[attr.aria-label]': 'ariaLabel() || null',
198
+ '[attr.data-disabled]': 'disabled() ? "" : null',
199
+ '[attr.dir]': 'dir()',
200
+ },
201
+ providers: [{ provide: FOR_PAGINATION_CONTEXT, useExisting: ForPagination }],
202
+ }]
203
+ }], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: true }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], boundaryCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundaryCount", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], _dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
204
+
205
+ /**
206
+ * Page number button. Apply on a `<button>` so Enter/Space activation is
207
+ * native. Reflects `aria-current="page"` when this button represents the
208
+ * currently active page. Clicking calls `ctx.goToPage(page)`.
209
+ */
210
+ class ForPaginationItem {
211
+ ctx = injectPaginationContext('ForPaginationItem');
212
+ /** The 1-based page number this button navigates to. */
213
+ page = input.required(/* @ts-ignore */
214
+ ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
215
+ /** Per-item disabled override (in addition to the root's `disabled`). */
216
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
217
+ /** Whether this item is effectively disabled (own or root disabled). */
218
+ effectiveDisabled = computed(() => this.disabled() || this.ctx.disabled(), /* @ts-ignore */
219
+ ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
220
+ /** Whether this button represents the currently active page. */
221
+ isCurrent = computed(() => this.ctx.page() === this.page(), /* @ts-ignore */
222
+ ...(ngDevMode ? [{ debugName: "isCurrent" }] : /* istanbul ignore next */ []));
223
+ constructor() {
224
+ reflectDisabled(this.effectiveDisabled);
225
+ }
226
+ activate() {
227
+ if (this.effectiveDisabled()) {
228
+ return;
229
+ }
230
+ this.ctx.goToPage(this.page());
231
+ }
232
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPaginationItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
233
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForPaginationItem, isStandalone: true, selector: "[forPaginationItem]", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, listeners: { "click": "activate()" }, properties: { "attr.aria-current": "isCurrent() ? \"page\" : null" } }, exportAs: ["forPaginationItem"], ngImport: i0 });
234
+ }
235
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPaginationItem, decorators: [{
236
+ type: Directive,
237
+ args: [{
238
+ selector: '[forPaginationItem]',
239
+ exportAs: 'forPaginationItem',
240
+ host: {
241
+ type: 'button',
242
+ '[attr.aria-current]': 'isCurrent() ? "page" : null',
243
+ '(click)': 'activate()',
244
+ },
245
+ }]
246
+ }], ctorParameters: () => [], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
247
+
248
+ /**
249
+ * Previous-page button. Apply on a `<button>` so Enter/Space activation is
250
+ * native. Disabled (via the native `disabled` attribute) when the current page
251
+ * is the first page or the root is disabled. Clicking calls `ctx.previous()`.
252
+ */
253
+ class ForPaginationPrevious {
254
+ ctx = injectPaginationContext('ForPaginationPrevious');
255
+ /**
256
+ * Accessible label for this button (e.g. "Previous page"). When `null`
257
+ * (default), no `aria-label` is emitted — the consumer should supply a
258
+ * visible label or set this input.
259
+ */
260
+ ariaLabel = input(null, /* @ts-ignore */
261
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
262
+ isDisabled = computed(() => this.ctx.isFirst() || this.ctx.disabled(), /* @ts-ignore */
263
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
264
+ constructor() {
265
+ reflectDisabled(this.isDisabled);
266
+ }
267
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPaginationPrevious, deps: [], target: i0.ɵɵFactoryTarget.Directive });
268
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForPaginationPrevious, isStandalone: true, selector: "[forPaginationPrevious]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, listeners: { "click": "ctx.previous()" }, properties: { "attr.aria-label": "ariaLabel() || null" } }, exportAs: ["forPaginationPrevious"], ngImport: i0 });
269
+ }
270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPaginationPrevious, decorators: [{
271
+ type: Directive,
272
+ args: [{
273
+ selector: '[forPaginationPrevious]',
274
+ exportAs: 'forPaginationPrevious',
275
+ host: {
276
+ type: 'button',
277
+ '[attr.aria-label]': 'ariaLabel() || null',
278
+ '(click)': 'ctx.previous()',
279
+ },
280
+ }]
281
+ }], ctorParameters: () => [], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
282
+
283
+ /**
284
+ * Next-page button. Apply on a `<button>` so Enter/Space activation is
285
+ * native. Disabled (via the native `disabled` attribute) when the current page
286
+ * is the last page or the root is disabled. Clicking calls `ctx.next()`.
287
+ */
288
+ class ForPaginationNext {
289
+ ctx = injectPaginationContext('ForPaginationNext');
290
+ /**
291
+ * Accessible label for this button (e.g. "Next page"). When `null`
292
+ * (default), no `aria-label` is emitted — the consumer should supply a
293
+ * visible label or set this input.
294
+ */
295
+ ariaLabel = input(null, /* @ts-ignore */
296
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
297
+ isDisabled = computed(() => this.ctx.isLast() || this.ctx.disabled(), /* @ts-ignore */
298
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
299
+ constructor() {
300
+ reflectDisabled(this.isDisabled);
301
+ }
302
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPaginationNext, deps: [], target: i0.ɵɵFactoryTarget.Directive });
303
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: ForPaginationNext, isStandalone: true, selector: "[forPaginationNext]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, listeners: { "click": "ctx.next()" }, properties: { "attr.aria-label": "ariaLabel() || null" } }, exportAs: ["forPaginationNext"], ngImport: i0 });
304
+ }
305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ForPaginationNext, decorators: [{
306
+ type: Directive,
307
+ args: [{
308
+ selector: '[forPaginationNext]',
309
+ exportAs: 'forPaginationNext',
310
+ host: {
311
+ type: 'button',
312
+ '[attr.aria-label]': 'ariaLabel() || null',
313
+ '(click)': 'ctx.next()',
314
+ },
315
+ }]
316
+ }], ctorParameters: () => [], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
317
+
318
+ /**
319
+ * Generated bundle index. Do not edit.
320
+ */
321
+
322
+ export { FOR_PAGINATION_CONTEXT, FOR_PAGINATION_DEFAULTS, ForPagination, ForPaginationItem, ForPaginationNext, ForPaginationPrevious, provideForPaginationDefaults };
323
+ //# sourceMappingURL=forty-cdk-pagination.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forty-cdk-pagination.mjs","sources":["../../../projects/forty-cdk/pagination/src/pagination-context.ts","../../../projects/forty-cdk/pagination/src/pagination-defaults.ts","../../../projects/forty-cdk/pagination/src/pagination-range.ts","../../../projects/forty-cdk/pagination/src/pagination.ts","../../../projects/forty-cdk/pagination/src/pagination-item.ts","../../../projects/forty-cdk/pagination/src/pagination-previous.ts","../../../projects/forty-cdk/pagination/src/pagination-next.ts","../../../projects/forty-cdk/pagination/src/forty-cdk-pagination.ts"],"sourcesContent":["import { inject, InjectionToken, type Signal } from '@angular/core';\n\nimport type { PaginationItem } from './pagination-range';\n\n/**\n * Coordination contract owned by `ForPagination`. Page buttons, previous, and\n * next pieces inject it to read the current page / derived list and drive\n * navigation from a single source of truth.\n */\nexport interface ForPaginationContext {\n /** Current 1-based page. */\n readonly page: Signal<number>;\n /** Total number of pages. */\n readonly count: Signal<number>;\n /** Whether the whole control is disabled. */\n readonly disabled: Signal<boolean>;\n /** The computed visible-page list (page numbers + ellipsis gaps). */\n readonly items: Signal<readonly PaginationItem[]>;\n /** Whether the current page is the first (no previous page). */\n readonly isFirst: Signal<boolean>;\n /** Whether the current page is the last (no next page). */\n readonly isLast: Signal<boolean>;\n\n /** Navigate to `page`, clamped to `[1, count]`. No-op when disabled. */\n goToPage(page: number): void;\n /** Navigate to the previous page. No-op at the first page or when disabled. */\n previous(): void;\n /** Navigate to the next page. No-op at the last page or when disabled. */\n next(): void;\n}\n\n/** DI token providing the pagination context to descendant pieces. */\nexport const FOR_PAGINATION_CONTEXT = new InjectionToken<ForPaginationContext>(\n 'FOR_PAGINATION_CONTEXT',\n);\n\nexport function injectPaginationContext(piece: string): ForPaginationContext {\n const ctx = inject(FOR_PAGINATION_CONTEXT, { optional: true });\n if (!ctx) {\n throw new Error(\n `[forty-cdk/pagination] ${piece} must be used inside a [forPagination] element.`,\n );\n }\n return ctx;\n}\n","import { type Provider } from '@angular/core';\n\nimport { createDefaults } from 'forty-cdk/core';\n\n/**\n * Defaults inherited by descendant paginations in the surrounding injector\n * scope. Configure with `provideForPaginationDefaults` at the application root\n * or in any component's `providers`; partial overrides merge with the parent.\n */\nexport interface ForPaginationDefaults {\n /** Pages shown on each side of the current page before collapsing to an ellipsis. */\n siblingCount: number;\n /** Pages always shown at each end (first/last). */\n boundaryCount: number;\n}\n\n/**\n * Library fallback for pagination defaults, read at the root injector when no\n * consumer has called `provideForPaginationDefaults`. Exported for the shared\n * defaults-contract spec; not re-exported from the primitive's public entry.\n */\nexport const FOR_PAGINATION_FALLBACK_DEFAULTS: ForPaginationDefaults = {\n siblingCount: 1,\n boundaryCount: 1,\n};\n\nconst { token, provideDefaults } = createDefaults<ForPaginationDefaults>(\n 'FOR_PAGINATION_DEFAULTS',\n FOR_PAGINATION_FALLBACK_DEFAULTS,\n);\n\n/** Token holding the resolved pagination defaults for the current scope. */\nexport const FOR_PAGINATION_DEFAULTS = token;\n\n/**\n * Configures forty-cdk pagination defaults for this injector scope. Partial\n * overrides inherit unspecified keys from the parent scope (or library defaults\n * at the root).\n */\nexport function provideForPaginationDefaults(\n defaults: Partial<ForPaginationDefaults> = {},\n): Provider[] {\n return provideDefaults(defaults);\n}\n","/**\n * One entry in the computed visible-page list: either a clickable page number\n * or an ellipsis gap standing in for a collapsed run of pages.\n */\nexport interface PaginationItem {\n /** Discriminator: a real page button, or a non-interactive ellipsis gap. */\n readonly type: 'page' | 'ellipsis';\n /** 1-based page number. Present only when `type` is `'page'`. */\n readonly value?: number;\n}\n\nfunction range(start: number, end: number): number[] {\n const length = end - start + 1;\n return Array.from({ length }, (_, i) => start + i);\n}\n\n/**\n * Compute the visible page list (with ellipsis gaps) for the given pagination\n * state, using the standard boundary/sibling algorithm:\n *\n * - `boundaryCount` pages are always shown at each end.\n * - `siblingCount` pages are shown on each side of the current `page`.\n * - Runs of hidden pages collapse to a single `'ellipsis'` entry — except a gap\n * of exactly one page, which is shown as that page rather than an ellipsis.\n *\n * Returns an empty list when `count` is not positive. All page numbers are\n * 1-based. Internal — not re-exported from `public-api.ts`.\n */\nexport function computePaginationItems(opts: {\n page: number;\n count: number;\n siblingCount: number;\n boundaryCount: number;\n}): PaginationItem[] {\n const { page, count, siblingCount, boundaryCount } = opts;\n if (count <= 0) {\n return [];\n }\n\n const startPages = range(1, Math.min(boundaryCount, count));\n const endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count);\n\n const siblingsStart = Math.max(\n Math.min(page - siblingCount, count - boundaryCount - siblingCount * 2 - 1),\n boundaryCount + 2,\n );\n\n const siblingsEnd = Math.min(\n Math.max(page + siblingCount, boundaryCount + siblingCount * 2 + 2),\n endPages.length > 0 ? endPages[0]! - 2 : count - 1,\n );\n\n const tokens: (number | 'ellipsis')[] = [\n ...startPages,\n ...(siblingsStart > boundaryCount + 2\n ? ['ellipsis' as const]\n : boundaryCount + 1 < count - boundaryCount\n ? [boundaryCount + 1]\n : []),\n ...range(siblingsStart, siblingsEnd),\n ...(siblingsEnd < count - boundaryCount - 1\n ? ['ellipsis' as const]\n : count - boundaryCount > boundaryCount\n ? [count - boundaryCount]\n : []),\n ...endPages,\n ];\n\n return tokens.map((t) => (t === 'ellipsis' ? { type: 'ellipsis' } : { type: 'page', value: t }));\n}\n","import {\n booleanAttribute,\n computed,\n Directive,\n inject,\n input,\n model,\n numberAttribute,\n} from '@angular/core';\n\nimport { type WritingDirection, clamp, injectTextDirection } from 'forty-cdk/core';\nimport { FOR_PAGINATION_CONTEXT, type ForPaginationContext } from './pagination-context';\nimport { FOR_PAGINATION_DEFAULTS } from './pagination-defaults';\nimport { computePaginationItems, type PaginationItem } from './pagination-range';\n\n/**\n * Headless pagination navigation landmark, implementing the\n * [WAI-ARIA `navigation` landmark](https://www.w3.org/WAI/ARIA/apg/patterns/landmarks/examples/navigation.html)\n * with [`aria-current=\"page\"`](https://www.w3.org/TR/wai-aria-1.2/#aria-current) on the active page.\n *\n * Derives the visible page list (with ellipsis gaps) from `page`, `count`,\n * `siblingCount`, and `boundaryCount`. Exposes `items()`, `isFirst()`,\n * `isLast()`, and navigation methods for the consumer template to render.\n *\n * There is no roving tabindex — each page button, previous, and next are their\n * own tab stops. RTL is visual-only: the resolved `dir` reflects on the host\n * for CSS; navigation semantics (previous = decrement, next = increment) never\n * change based on direction.\n *\n * @example\n * ```html\n * <nav forPagination [(page)]=\"page\" [count]=\"20\" ariaLabel=\"Pagination\" #pg=\"forPagination\">\n * <button forPaginationPrevious ariaLabel=\"Previous page\">‹</button>\n * @for (item of pg.items(); track $index) {\n * @if (item.type === 'page') {\n * <button forPaginationItem [page]=\"item.value!\">{{ item.value }}</button>\n * } @else {\n * <span aria-hidden=\"true\">…</span>\n * }\n * }\n * <button forPaginationNext ariaLabel=\"Next page\">›</button>\n * </nav>\n * ```\n */\n@Directive({\n selector: '[forPagination]',\n exportAs: 'forPagination',\n host: {\n role: 'navigation',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.data-disabled]': 'disabled() ? \"\" : null',\n '[attr.dir]': 'dir()',\n },\n providers: [{ provide: FOR_PAGINATION_CONTEXT, useExisting: ForPagination }],\n})\nexport class ForPagination implements ForPaginationContext {\n readonly #defaults = inject(FOR_PAGINATION_DEFAULTS);\n\n /**\n * Current 1-based page number. Two-way bindable via `[(page)]`. The implicit\n * `pageChange` output emits whenever the directive updates this value (via\n * clicks, previous, or next). Do not add a separate `pageChange` output.\n */\n readonly page = model<number>(1);\n\n /**\n * Total number of pages. Always bind as `[count]=\"n\"` (a number, not a\n * string). Required.\n */\n readonly count = input.required<number>();\n\n /**\n * Pages shown on each side of the current page before collapsing to an\n * ellipsis. Default read from `provideForPaginationDefaults` for the\n * surrounding scope (library fallback: `1`).\n */\n readonly siblingCount = input(this.#defaults.siblingCount, { transform: numberAttribute });\n\n /**\n * Pages always shown at each end (first and last). Default read from\n * `provideForPaginationDefaults` for the surrounding scope (library\n * fallback: `1`).\n */\n readonly boundaryCount = input(this.#defaults.boundaryCount, { transform: numberAttribute });\n\n /** Whether the entire pagination control is disabled. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /**\n * Writing direction. When unset (default `null`), the inherited ambient\n * direction is resolved from the nearest ancestor carrying a `dir` attribute\n * (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]` always wins.\n * The resolved value is reflected to the host `dir` attribute. RTL affects\n * visual layout only — previous/next semantics do not change.\n */\n readonly _dirInput = input<WritingDirection | null>(null, { alias: 'dir' });\n readonly dir = injectTextDirection(this._dirInput);\n\n /**\n * Accessible label for the navigation landmark. Supply this (or point\n * `aria-labelledby` at a visible label element) when the page contains more\n * than one `<nav>`. A `null` or empty value emits no attribute.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /** The computed visible-page list (page numbers + ellipsis gaps). */\n readonly items = computed<readonly PaginationItem[]>(() =>\n computePaginationItems({\n page: this.page(),\n count: this.count(),\n siblingCount: this.siblingCount(),\n boundaryCount: this.boundaryCount(),\n }),\n );\n\n /** Whether the current page is the first (no previous page). */\n readonly isFirst = computed(() => this.page() <= 1);\n\n /** Whether the current page is the last (no next page). */\n readonly isLast = computed(() => this.page() >= this.count());\n\n /**\n * Navigate to `page`, clamped to `[1, count]`. No-op when disabled.\n */\n goToPage(page: number): void {\n if (this.disabled()) {\n return;\n }\n const clamped = clamp(page, 1, Math.max(1, this.count()));\n if (clamped !== this.page()) {\n this.page.set(clamped);\n }\n }\n\n /** Navigate to the previous page. No-op at the first page or when disabled. */\n previous(): void {\n this.goToPage(this.page() - 1);\n }\n\n /** Navigate to the next page. No-op at the last page or when disabled. */\n next(): void {\n this.goToPage(this.page() + 1);\n }\n}\n","import { booleanAttribute, computed, Directive, input } from '@angular/core';\n\nimport { reflectDisabled } from 'forty-cdk/core';\nimport { injectPaginationContext } from './pagination-context';\n\n/**\n * Page number button. Apply on a `<button>` so Enter/Space activation is\n * native. Reflects `aria-current=\"page\"` when this button represents the\n * currently active page. Clicking calls `ctx.goToPage(page)`.\n */\n@Directive({\n selector: '[forPaginationItem]',\n exportAs: 'forPaginationItem',\n host: {\n type: 'button',\n '[attr.aria-current]': 'isCurrent() ? \"page\" : null',\n '(click)': 'activate()',\n },\n})\nexport class ForPaginationItem {\n protected readonly ctx = injectPaginationContext('ForPaginationItem');\n\n /** The 1-based page number this button navigates to. */\n readonly page = input.required<number>();\n\n /** Per-item disabled override (in addition to the root's `disabled`). */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** Whether this item is effectively disabled (own or root disabled). */\n readonly effectiveDisabled = computed(() => this.disabled() || this.ctx.disabled());\n\n /** Whether this button represents the currently active page. */\n readonly isCurrent = computed(() => this.ctx.page() === this.page());\n\n constructor() {\n reflectDisabled(this.effectiveDisabled);\n }\n\n protected activate(): void {\n if (this.effectiveDisabled()) {\n return;\n }\n this.ctx.goToPage(this.page());\n }\n}\n","import { computed, Directive, input } from '@angular/core';\n\nimport { reflectDisabled } from 'forty-cdk/core';\nimport { injectPaginationContext } from './pagination-context';\n\n/**\n * Previous-page button. Apply on a `<button>` so Enter/Space activation is\n * native. Disabled (via the native `disabled` attribute) when the current page\n * is the first page or the root is disabled. Clicking calls `ctx.previous()`.\n */\n@Directive({\n selector: '[forPaginationPrevious]',\n exportAs: 'forPaginationPrevious',\n host: {\n type: 'button',\n '[attr.aria-label]': 'ariaLabel() || null',\n '(click)': 'ctx.previous()',\n },\n})\nexport class ForPaginationPrevious {\n protected readonly ctx = injectPaginationContext('ForPaginationPrevious');\n\n /**\n * Accessible label for this button (e.g. \"Previous page\"). When `null`\n * (default), no `aria-label` is emitted — the consumer should supply a\n * visible label or set this input.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly isDisabled = computed(() => this.ctx.isFirst() || this.ctx.disabled());\n\n constructor() {\n reflectDisabled(this.isDisabled);\n }\n}\n","import { computed, Directive, input } from '@angular/core';\n\nimport { reflectDisabled } from 'forty-cdk/core';\nimport { injectPaginationContext } from './pagination-context';\n\n/**\n * Next-page button. Apply on a `<button>` so Enter/Space activation is\n * native. Disabled (via the native `disabled` attribute) when the current page\n * is the last page or the root is disabled. Clicking calls `ctx.next()`.\n */\n@Directive({\n selector: '[forPaginationNext]',\n exportAs: 'forPaginationNext',\n host: {\n type: 'button',\n '[attr.aria-label]': 'ariaLabel() || null',\n '(click)': 'ctx.next()',\n },\n})\nexport class ForPaginationNext {\n protected readonly ctx = injectPaginationContext('ForPaginationNext');\n\n /**\n * Accessible label for this button (e.g. \"Next page\"). When `null`\n * (default), no `aria-label` is emitted — the consumer should supply a\n * visible label or set this input.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly isDisabled = computed(() => this.ctx.isLast() || this.ctx.disabled());\n\n constructor() {\n reflectDisabled(this.isDisabled);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}