@ngneers/controls 0.0.1-next.0 → 0.0.1-next.2

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 (119) hide show
  1. package/fesm2022/ngneers-controls-api-ng.mjs +11 -18
  2. package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -1
  3. package/fesm2022/ngneers-controls-api-resize.mjs +7 -0
  4. package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -1
  5. package/fesm2022/ngneers-controls-badge.mjs +160 -0
  6. package/fesm2022/ngneers-controls-badge.mjs.map +1 -0
  7. package/fesm2022/ngneers-controls-base.mjs +85 -8
  8. package/fesm2022/ngneers-controls-base.mjs.map +1 -1
  9. package/fesm2022/{ngneers-controls-calendar-time-CJT5AFlA.mjs → ngneers-controls-calendar-time-paM6WVpV.mjs} +2 -2
  10. package/fesm2022/{ngneers-controls-calendar-time-CJT5AFlA.mjs.map → ngneers-controls-calendar-time-paM6WVpV.mjs.map} +1 -1
  11. package/fesm2022/ngneers-controls-calendar.mjs +13 -6
  12. package/fesm2022/ngneers-controls-calendar.mjs.map +1 -1
  13. package/fesm2022/ngneers-controls-checkbox.mjs +3 -3
  14. package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -1
  15. package/fesm2022/ngneers-controls-color-picker.mjs +336 -0
  16. package/fesm2022/ngneers-controls-color-picker.mjs.map +1 -0
  17. package/fesm2022/ngneers-controls-default-icons.mjs +5 -0
  18. package/fesm2022/ngneers-controls-default-icons.mjs.map +1 -1
  19. package/fesm2022/ngneers-controls-directives.mjs +64 -7
  20. package/fesm2022/ngneers-controls-directives.mjs.map +1 -1
  21. package/fesm2022/ngneers-controls-edit-inplace.mjs +15 -5
  22. package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -1
  23. package/fesm2022/ngneers-controls-errors.mjs +203 -148
  24. package/fesm2022/ngneers-controls-errors.mjs.map +1 -1
  25. package/fesm2022/ngneers-controls-filter.mjs +2 -2
  26. package/fesm2022/ngneers-controls-filter.mjs.map +1 -1
  27. package/fesm2022/ngneers-controls-hint.mjs +18 -1
  28. package/fesm2022/ngneers-controls-hint.mjs.map +1 -1
  29. package/fesm2022/ngneers-controls-i18n-translations-de.mjs +17 -0
  30. package/fesm2022/ngneers-controls-i18n-translations-de.mjs.map +1 -1
  31. package/fesm2022/ngneers-controls-i18n-translations-en.mjs +19 -0
  32. package/fesm2022/ngneers-controls-i18n-translations-en.mjs.map +1 -1
  33. package/fesm2022/ngneers-controls-icon.mjs +23 -6
  34. package/fesm2022/ngneers-controls-icon.mjs.map +1 -1
  35. package/fesm2022/ngneers-controls-input-field.mjs +18 -2
  36. package/fesm2022/ngneers-controls-input-field.mjs.map +1 -1
  37. package/fesm2022/ngneers-controls-input.mjs +49 -9
  38. package/fesm2022/ngneers-controls-input.mjs.map +1 -1
  39. package/fesm2022/ngneers-controls-list-box.mjs +2 -2
  40. package/fesm2022/ngneers-controls-list-box.mjs.map +1 -1
  41. package/fesm2022/ngneers-controls-mask-input.mjs +4 -1
  42. package/fesm2022/ngneers-controls-mask-input.mjs.map +1 -1
  43. package/fesm2022/ngneers-controls-number-input.mjs +4 -4
  44. package/fesm2022/ngneers-controls-number-input.mjs.map +1 -1
  45. package/fesm2022/ngneers-controls-otp.mjs +263 -0
  46. package/fesm2022/ngneers-controls-otp.mjs.map +1 -0
  47. package/fesm2022/ngneers-controls-paginator.mjs +36 -9
  48. package/fesm2022/ngneers-controls-paginator.mjs.map +1 -1
  49. package/fesm2022/ngneers-controls-radio.mjs +4 -4
  50. package/fesm2022/ngneers-controls-radio.mjs.map +1 -1
  51. package/fesm2022/ngneers-controls-rating.mjs +180 -0
  52. package/fesm2022/ngneers-controls-rating.mjs.map +1 -0
  53. package/fesm2022/ngneers-controls-scroll-shadow.mjs +33 -7
  54. package/fesm2022/ngneers-controls-scroll-shadow.mjs.map +1 -1
  55. package/fesm2022/ngneers-controls-scroller.mjs +4 -2
  56. package/fesm2022/ngneers-controls-scroller.mjs.map +1 -1
  57. package/fesm2022/ngneers-controls-select-button.mjs +2 -1
  58. package/fesm2022/ngneers-controls-select-button.mjs.map +1 -1
  59. package/fesm2022/ngneers-controls-select.mjs +24 -4
  60. package/fesm2022/ngneers-controls-select.mjs.map +1 -1
  61. package/fesm2022/ngneers-controls-slider.mjs +3 -3
  62. package/fesm2022/ngneers-controls-slider.mjs.map +1 -1
  63. package/fesm2022/ngneers-controls-splitter.mjs +43 -12
  64. package/fesm2022/ngneers-controls-splitter.mjs.map +1 -1
  65. package/fesm2022/ngneers-controls-stepper.mjs +142 -0
  66. package/fesm2022/ngneers-controls-stepper.mjs.map +1 -0
  67. package/fesm2022/ngneers-controls-switch.mjs +3 -3
  68. package/fesm2022/ngneers-controls-switch.mjs.map +1 -1
  69. package/fesm2022/ngneers-controls-table.mjs +282 -15
  70. package/fesm2022/ngneers-controls-table.mjs.map +1 -1
  71. package/fesm2022/ngneers-controls-tabs.mjs +2 -2
  72. package/fesm2022/ngneers-controls-tabs.mjs.map +1 -1
  73. package/fesm2022/ngneers-controls-toggle-button.mjs +3 -3
  74. package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -1
  75. package/fesm2022/ngneers-controls-tooltip.mjs +16 -28
  76. package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -1
  77. package/fesm2022/ngneers-controls-tree.mjs +2 -2
  78. package/fesm2022/ngneers-controls-tree.mjs.map +1 -1
  79. package/fesm2022/ngneers-controls-utils.mjs +138 -1
  80. package/fesm2022/ngneers-controls-utils.mjs.map +1 -1
  81. package/package.json +22 -2
  82. package/types/ngneers-controls-api-ng.d.ts +12 -9
  83. package/types/ngneers-controls-badge.d.ts +67 -0
  84. package/types/ngneers-controls-base.d.ts +61 -4
  85. package/types/ngneers-controls-breadcrumb.d.ts +17 -0
  86. package/types/ngneers-controls-calendar.d.ts +24 -6
  87. package/types/ngneers-controls-chip.d.ts +17 -0
  88. package/types/ngneers-controls-color-picker.d.ts +119 -0
  89. package/types/ngneers-controls-dialog.d.ts +17 -0
  90. package/types/ngneers-controls-directives.d.ts +31 -2
  91. package/types/ngneers-controls-drawer.d.ts +17 -0
  92. package/types/ngneers-controls-edit-inplace.d.ts +23 -0
  93. package/types/ngneers-controls-errors.d.ts +105 -16
  94. package/types/ngneers-controls-filter.d.ts +30 -13
  95. package/types/ngneers-controls-hint.d.ts +8 -1
  96. package/types/ngneers-controls-i18n-translations-de.d.ts +17 -0
  97. package/types/ngneers-controls-i18n-translations-en.d.ts +17 -0
  98. package/types/ngneers-controls-i18n.d.ts +17 -0
  99. package/types/ngneers-controls-icon.d.ts +2 -2
  100. package/types/ngneers-controls-input-field.d.ts +28 -2
  101. package/types/ngneers-controls-input.d.ts +35 -3
  102. package/types/ngneers-controls-list-box.d.ts +17 -0
  103. package/types/ngneers-controls-mask-input.d.ts +17 -0
  104. package/types/ngneers-controls-otp.d.ts +262 -0
  105. package/types/ngneers-controls-paginator.d.ts +34 -3
  106. package/types/ngneers-controls-rating.d.ts +69 -0
  107. package/types/ngneers-controls-scroll-shadow.d.ts +11 -2
  108. package/types/ngneers-controls-scroller.d.ts +3 -1
  109. package/types/ngneers-controls-select.d.ts +30 -3
  110. package/types/ngneers-controls-snackbar.d.ts +17 -0
  111. package/types/ngneers-controls-splitter.d.ts +26 -2
  112. package/types/ngneers-controls-state.d.ts +2 -2
  113. package/types/ngneers-controls-stepper.d.ts +68 -0
  114. package/types/ngneers-controls-table.d.ts +276 -169
  115. package/types/ngneers-controls-toast.d.ts +17 -0
  116. package/types/ngneers-controls-tooltip.d.ts +0 -1
  117. package/types/ngneers-controls-tree.d.ts +17 -0
  118. package/types/ngneers-controls-upload.d.ts +17 -0
  119. package/types/ngneers-controls-utils.d.ts +27 -2
@@ -2,7 +2,7 @@ import * as _angular_core from '@angular/core';
2
2
  import { AfterViewInit } from '@angular/core';
3
3
  import * as _ngneers_controls_api_ng from '@ngneers/controls/api/ng';
4
4
  import * as _ngneers_controls_themes from '@ngneers/controls-themes';
5
- import { NgnBase } from '@ngneers/controls/base';
5
+ import { NgnBase, NgnInvalidTrigger } from '@ngneers/controls/base';
6
6
 
7
7
  /**
8
8
  * @category control
@@ -10,21 +10,53 @@ import { NgnBase } from '@ngneers/controls/base';
10
10
  declare class NgnInput extends NgnBase<'input'> implements AfterViewInit {
11
11
  readonly isFieldControl = true;
12
12
  protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"input", ["root", "invalid", "empty"], readonly []>>;
13
+ readonly empty: _angular_core.Signal<boolean>;
13
14
  /**
14
- * Explicitly apply invalid state styling
15
+ * The raw invalid flag (bound from a signal-forms field's validity, or set
16
+ * explicitly). Whether it *shows* is gated by {@link invalidOn} — read
17
+ * {@link invalidState}.
15
18
  * @default false
16
19
  */
17
20
  readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
21
+ /**
22
+ * When the input surfaces its invalid styling.
23
+ * @default touched
24
+ */
25
+ readonly invalidOn: _angular_core.InputSignal<NgnInvalidTrigger>;
26
+ /**
27
+ * Touched state. A bound signal-forms field writes it in (`FormUiControl`
28
+ * `touched` input); the input also sets it on blur, and reports blur out
29
+ * through {@link touch}.
30
+ */
31
+ readonly touched: _angular_core.ModelSignal<boolean>;
32
+ /**
33
+ * The invalid state the theme renders: {@link invalid} gated by
34
+ * {@link invalidOn}. (Dirty tracking isn't wired for the bare directive, so the
35
+ * `dirty` trigger behaves like `immediate` here.)
36
+ */
37
+ protected readonly invalidState: _angular_core.Signal<boolean>;
18
38
  /**
19
39
  * The current value of the input, kept in sync with the native element in both directions.
20
40
  * @default ''
21
41
  */
22
42
  readonly value: _angular_core.ModelSignal<string | null>;
43
+ /**
44
+ * Emits on blur so a bound signal-forms field is marked touched (the
45
+ * `FormUiControl` `touch` contract) — enables `ngnErrorsShowOn="touched"`.
46
+ */
47
+ readonly touch: _angular_core.OutputEmitterRef<void>;
23
48
  private readonly _input;
24
49
  ngAfterViewInit(): void;
25
50
  constructor();
51
+ /**
52
+ * Marks the input touched on blur: flips {@link touched} for local consumers
53
+ * (e.g. `ngnErrors`) and emits {@link touch} so a bound signal-forms field is
54
+ * marked too. Mirrors `ValueControlBase.markTouched`, which this directive
55
+ * can't inherit (it extends {@link NgnBase} as a native-element directive).
56
+ */
57
+ private markTouched;
26
58
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgnInput, never>;
27
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgnInput, "input[ngnInput], textarea[ngnInput]", ["ngnInput"], { "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
59
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgnInput, "input[ngnInput], textarea[ngnInput]", ["ngnInput"], { "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "invalidOn": { "alias": "invalidOn"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "touched": "touchedChange"; "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
28
60
  }
29
61
 
30
62
  export { NgnInput };
@@ -177,6 +177,9 @@ declare class NgnListBox<Items extends readonly NgnItem[], Multiple extends bool
177
177
  segmentRange: string;
178
178
  optionSeparator: string;
179
179
  };
180
+ otp: {
181
+ cellLabel: string;
182
+ };
180
183
  drawer: {
181
184
  close: string;
182
185
  };
@@ -234,6 +237,8 @@ declare class NgnListBox<Items extends readonly NgnItem[], Multiple extends bool
234
237
  selectedCount: string;
235
238
  page: string;
236
239
  resultCount: string;
240
+ retry: string;
241
+ loadError: string;
237
242
  };
238
243
  state: {
239
244
  loading: string;
@@ -242,6 +247,18 @@ declare class NgnListBox<Items extends readonly NgnItem[], Multiple extends bool
242
247
  error: string;
243
248
  cancelled: string;
244
249
  };
250
+ errors: {
251
+ pending: string;
252
+ required: string;
253
+ email: string;
254
+ minlength: string;
255
+ maxlength: string;
256
+ minLength: string;
257
+ maxLength: string;
258
+ min: string;
259
+ max: string;
260
+ pattern: string;
261
+ };
245
262
  }, "_">;
246
263
  protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"list-box", ["root", "empty", "invalid", "item", "group", "default-item", "default-group", "item-selected", "item-highlighted", "item-disabled"], readonly [{
247
264
  readonly class: "checkbox";
@@ -161,6 +161,9 @@ declare class NgnMaskInput extends ValueControlBase<'maskInput', string | null>
161
161
  segmentRange: string;
162
162
  optionSeparator: string;
163
163
  };
164
+ otp: {
165
+ cellLabel: string;
166
+ };
164
167
  drawer: {
165
168
  close: string;
166
169
  };
@@ -218,6 +221,8 @@ declare class NgnMaskInput extends ValueControlBase<'maskInput', string | null>
218
221
  selectedCount: string;
219
222
  page: string;
220
223
  resultCount: string;
224
+ retry: string;
225
+ loadError: string;
221
226
  };
222
227
  state: {
223
228
  loading: string;
@@ -226,6 +231,18 @@ declare class NgnMaskInput extends ValueControlBase<'maskInput', string | null>
226
231
  error: string;
227
232
  cancelled: string;
228
233
  };
234
+ errors: {
235
+ pending: string;
236
+ required: string;
237
+ email: string;
238
+ minlength: string;
239
+ maxlength: string;
240
+ minLength: string;
241
+ maxLength: string;
242
+ min: string;
243
+ max: string;
244
+ pattern: string;
245
+ };
229
246
  }, "_">;
230
247
  /**
231
248
  * The mask to apply to the input. Can be a predefined mask key or a custom mask configuration.
@@ -0,0 +1,262 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import * as _ngneers_signal_translate from '@ngneers/signal-translate';
3
+ import * as _ngneers_controls_api_ng from '@ngneers/controls/api/ng';
4
+ import * as _ngneers_controls_themes from '@ngneers/controls-themes';
5
+ import { ValueControlBase } from '@ngneers/controls/base';
6
+
7
+ /**
8
+ * A one-time-password / verification-code input that splits a short code across
9
+ * a row of single-character cells (like the PrimeNG `InputOtp`).
10
+ *
11
+ * - Typing a character fills the active cell and advances focus to the next.
12
+ * - **Backspace** clears the active cell, or steps back and clears the previous
13
+ * one when the active cell is already empty.
14
+ * - **←/→** move between cells, **Home/End** jump to the first/last.
15
+ * - Pasting a code distributes its characters across the cells.
16
+ *
17
+ * It is a self-contained value control — bind `[value]`/`(valueChange)` (or
18
+ * `[(value)]`) directly on `<ngn-otp>`. The value is the composed string
19
+ * (`null` while every cell is empty); {@link completed} fires once the whole
20
+ * code is filled.
21
+ *
22
+ * @category control
23
+ */
24
+ declare class NgnOtp extends ValueControlBase<'otp', string | null> {
25
+ protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"otp", ["root", "box", "invalid"], readonly []>>;
26
+ protected readonly i18n: _ngneers_signal_translate.TranslationsSignal<{
27
+ calendar: {
28
+ today: string;
29
+ input: string;
30
+ selectYear: string;
31
+ selectMonth: string;
32
+ previousMonth: string;
33
+ nextMonth: string;
34
+ weekdays: {
35
+ monday: string;
36
+ tuesday: string;
37
+ wednesday: string;
38
+ thursday: string;
39
+ friday: string;
40
+ saturday: string;
41
+ sunday: string;
42
+ };
43
+ weekdaysShort: {
44
+ monday: string;
45
+ tuesday: string;
46
+ wednesday: string;
47
+ thursday: string;
48
+ friday: string;
49
+ saturday: string;
50
+ sunday: string;
51
+ };
52
+ months: {
53
+ january: string;
54
+ february: string;
55
+ march: string;
56
+ april: string;
57
+ may: string;
58
+ june: string;
59
+ july: string;
60
+ august: string;
61
+ september: string;
62
+ october: string;
63
+ november: string;
64
+ december: string;
65
+ };
66
+ };
67
+ editInplace: {
68
+ placeholder: string;
69
+ confirm: string;
70
+ };
71
+ filter: {
72
+ noFilter: string;
73
+ addCondition: string;
74
+ removeCondition: string;
75
+ operator: string;
76
+ value: string;
77
+ clear: string;
78
+ apply: string;
79
+ cancel: string;
80
+ matchModeLabel: string;
81
+ match: {
82
+ all: string;
83
+ any: string;
84
+ and: string;
85
+ or: string;
86
+ };
87
+ selected: string;
88
+ conditions: string;
89
+ operators: {
90
+ isEqual: string;
91
+ isNotEqual: string;
92
+ contains: string;
93
+ startsWith: string;
94
+ endsWith: string;
95
+ in: string;
96
+ isEmpty: string;
97
+ isNotEmpty: string;
98
+ greaterThan: string;
99
+ greaterThanOrEqual: string;
100
+ lessThan: string;
101
+ lessThanOrEqual: string;
102
+ after: string;
103
+ onOrAfter: string;
104
+ before: string;
105
+ onOrBefore: string;
106
+ isTrue: string;
107
+ isFalse: string;
108
+ custom: string;
109
+ };
110
+ };
111
+ splitter: {
112
+ handleLabel: string;
113
+ };
114
+ inputField: {
115
+ clearInput: string;
116
+ };
117
+ maskInput: {
118
+ roleDescription: string;
119
+ segmentRange: string;
120
+ optionSeparator: string;
121
+ };
122
+ otp: {
123
+ cellLabel: string;
124
+ };
125
+ drawer: {
126
+ close: string;
127
+ };
128
+ dialog: {
129
+ close: string;
130
+ };
131
+ chip: {
132
+ close: string;
133
+ };
134
+ breadcrumb: {
135
+ overflow: string;
136
+ };
137
+ toast: {
138
+ close: string;
139
+ region: string;
140
+ };
141
+ snackbar: {
142
+ close: string;
143
+ region: string;
144
+ severity: {
145
+ error: string;
146
+ warning: string;
147
+ success: string;
148
+ info: string;
149
+ };
150
+ };
151
+ upload: {
152
+ upload: string;
153
+ uploadNamed: string;
154
+ retryNamed: string;
155
+ cancelNamed: string;
156
+ removeNamed: string;
157
+ progressNamed: string;
158
+ };
159
+ select: {
160
+ filterOptions: string;
161
+ };
162
+ paginator: {
163
+ previousPage: string;
164
+ nextPage: string;
165
+ };
166
+ listBox: {
167
+ noItemsFound: string;
168
+ };
169
+ tree: {
170
+ noItemsFound: string;
171
+ };
172
+ table: {
173
+ selectAllRows: string;
174
+ selectRow: string;
175
+ sortedBy: string;
176
+ sortAscending: string;
177
+ sortDescending: string;
178
+ sortCleared: string;
179
+ selectedCount: string;
180
+ page: string;
181
+ resultCount: string;
182
+ retry: string;
183
+ loadError: string;
184
+ };
185
+ state: {
186
+ loading: string;
187
+ success: string;
188
+ warning: string;
189
+ error: string;
190
+ cancelled: string;
191
+ };
192
+ errors: {
193
+ pending: string;
194
+ required: string;
195
+ email: string;
196
+ minlength: string;
197
+ maxlength: string;
198
+ minLength: string;
199
+ maxLength: string;
200
+ min: string;
201
+ max: string;
202
+ pattern: string;
203
+ };
204
+ }, "_">;
205
+ /**
206
+ * The number of character cells the code is split across.
207
+ * @default 6
208
+ */
209
+ readonly length: _angular_core.InputSignalWithTransform<number, unknown>;
210
+ /**
211
+ * Render each entered character as a masked dot instead of the character
212
+ * itself (like a password field).
213
+ * @default false
214
+ */
215
+ readonly mask: _angular_core.InputSignalWithTransform<boolean, unknown>;
216
+ /**
217
+ * Restrict entry to digits (`0`–`9`) only. Also switches the on-screen
218
+ * keyboard to numeric on touch devices.
219
+ * @default false
220
+ */
221
+ readonly integerOnly: _angular_core.InputSignalWithTransform<boolean, unknown>;
222
+ /** Emits the fully composed code once every cell holds a character. */
223
+ readonly completed: _angular_core.OutputEmitterRef<string>;
224
+ /** Per-cell characters — the source of truth the composed value derives from. */
225
+ protected readonly cells: _angular_core.WritableSignal<string[]>;
226
+ /** Effective, sanitized cell count. */
227
+ protected readonly appliedLength: _angular_core.Signal<number>;
228
+ /** Cell indices for the template `@for` loop. */
229
+ protected readonly indices: _angular_core.Signal<number[]>;
230
+ protected readonly boxType: _angular_core.Signal<"text" | "password">;
231
+ protected readonly boxInputMode: _angular_core.Signal<"text" | "numeric">;
232
+ private readonly _boxes;
233
+ constructor();
234
+ /** Accessible name for a cell — its 1-based position within the code. */
235
+ protected cellLabel(index: number): string;
236
+ /**
237
+ * The control fully owns each cell's value: every text mutation is cancelled
238
+ * and the character is written to the {@link cells} signal instead, which the
239
+ * `[value]` binding reflects back. This makes overtype work from any caret
240
+ * position (no `maxlength`/selection tricks) and lets a single multi-character
241
+ * insert — e.g. SMS one-time-code autofill — spread across the cells.
242
+ */
243
+ protected onBeforeInput(index: number, event: InputEvent): void;
244
+ protected onKeyDown(index: number, event: KeyboardEvent): void;
245
+ protected onPaste(event: ClipboardEvent): void;
246
+ /**
247
+ * Mark touched once focus leaves the whole group — moving between cells keeps
248
+ * the host focused, so those intra-cell hops don't count as a blur.
249
+ */
250
+ protected onFocusOut(event: FocusEvent): void;
251
+ /** Clears every cell (also serves a surrounding field's clear button). */
252
+ clearValue(): boolean;
253
+ private _setCell;
254
+ /** Writes `text` into consecutive cells starting at `start`, then focuses the
255
+ * next empty cell (or the last one). Used by typing and autofill. */
256
+ private _fillFrom;
257
+ private _focusCell;
258
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgnOtp, never>;
259
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgnOtp, "ngn-otp", never, { "length": { "alias": "length"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "integerOnly": { "alias": "integerOnly"; "required": false; "isSignal": true; }; }, { "completed": "completed"; }, never, never, true, never>;
260
+ }
261
+
262
+ export { NgnOtp };
@@ -142,6 +142,9 @@ declare class NgnPaginator extends NgnBase<'paginator'> {
142
142
  segmentRange: string;
143
143
  optionSeparator: string;
144
144
  };
145
+ otp: {
146
+ cellLabel: string;
147
+ };
145
148
  drawer: {
146
149
  close: string;
147
150
  };
@@ -199,6 +202,8 @@ declare class NgnPaginator extends NgnBase<'paginator'> {
199
202
  selectedCount: string;
200
203
  page: string;
201
204
  resultCount: string;
205
+ retry: string;
206
+ loadError: string;
202
207
  };
203
208
  state: {
204
209
  loading: string;
@@ -207,15 +212,41 @@ declare class NgnPaginator extends NgnBase<'paginator'> {
207
212
  error: string;
208
213
  cancelled: string;
209
214
  };
215
+ errors: {
216
+ pending: string;
217
+ required: string;
218
+ email: string;
219
+ minlength: string;
220
+ maxlength: string;
221
+ minLength: string;
222
+ maxLength: string;
223
+ min: string;
224
+ max: string;
225
+ pattern: string;
226
+ };
210
227
  }, "_">;
211
228
  /**
212
- * Total number of items to paginate.
229
+ * Total number of items to paginate. Required in `'pages'` mode (drives the
230
+ * page count); ignored in `'compact'` mode.
213
231
  */
214
- readonly totalItems: _angular_core.InputSignal<number>;
232
+ readonly totalItems: _angular_core.InputSignal<number | undefined>;
215
233
  /**
216
234
  * Number of items per page. If not set, the first value from {@link possiblePageSizes} is used.
217
235
  */
218
236
  readonly pageSize: _angular_core.ModelSignal<number | undefined>;
237
+ /**
238
+ * Layout mode.
239
+ * - `'pages'`: full paginator with numbered page buttons (needs {@link totalItems}).
240
+ * - `'compact'`: prev/next buttons only, no page indicators, no total required.
241
+ * @default 'pages'
242
+ */
243
+ readonly mode: _angular_core.InputSignal<"pages" | "compact">;
244
+ /**
245
+ * `'compact'` mode only: whether a next page exists. Disables the "next" button
246
+ * when `false`. Bind to a lazy data source's `hasMore`.
247
+ * @default true
248
+ */
249
+ readonly hasNext: _angular_core.InputSignalWithTransform<boolean, unknown>;
219
250
  /**
220
251
  * Possible page sizes to choose from.
221
252
  * @default [5, 10, 25, 50]
@@ -248,7 +279,7 @@ declare class NgnPaginator extends NgnBase<'paginator'> {
248
279
  [klass: string]: string;
249
280
  };
250
281
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgnPaginator, never>;
251
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgnPaginator, "ngn-paginator", never, { "totalItems": { "alias": "totalItems"; "required": true; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "possiblePageSizes": { "alias": "possiblePageSizes"; "required": false; "isSignal": true; }; "fixedPageSize": { "alias": "fixedPageSize"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; }, { "pageSize": "pageSizeChange"; "value": "value"; "page": "pageChange"; }, never, never, true, never>;
282
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgnPaginator, "ngn-paginator", never, { "totalItems": { "alias": "totalItems"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "hasNext": { "alias": "hasNext"; "required": false; "isSignal": true; }; "possiblePageSizes": { "alias": "possiblePageSizes"; "required": false; "isSignal": true; }; "fixedPageSize": { "alias": "fixedPageSize"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; }, { "pageSize": "pageSizeChange"; "value": "value"; "page": "pageChange"; }, never, never, true, never>;
252
283
  }
253
284
 
254
285
  export { NgnPaginator };
@@ -0,0 +1,69 @@
1
+ import * as _ngneers_controls_custom_types from '@ngneers/controls-custom-types';
2
+ import * as _iconify_types from '@iconify/types';
3
+ import * as _angular_core from '@angular/core';
4
+ import { TemplateRef } from '@angular/core';
5
+ import * as _ngneers_controls_api_ng from '@ngneers/controls/api/ng';
6
+ import * as _ngneers_controls_themes from '@ngneers/controls-themes';
7
+ import { ValueControlBase } from '@ngneers/controls/base';
8
+
9
+ /** Context for a custom {@link NgnRating} symbol template. */
10
+ interface RatingIndicatorContext {
11
+ /** Fill ratio for this symbol, 0..1. */
12
+ $implicit: number;
13
+ /** Zero-based symbol index. */
14
+ index: number;
15
+ }
16
+ declare abstract class RatingTemplates extends ValueControlBase<'rating', number | null> {
17
+ private readonly _userIndicatorTemplate;
18
+ /**
19
+ * Custom template for a single symbol. Receives the fill ratio (`$implicit`,
20
+ * 0..1) and `index`. Can also be set with an `<ng-template #indicator>`.
21
+ * When set, it replaces the default full/empty icon rendering per symbol.
22
+ */
23
+ readonly indicatorTemplate: _angular_core.InputSignal<TemplateRef<RatingIndicatorContext> | null>;
24
+ protected readonly resolvedIndicatorTemplate: _angular_core.Signal<TemplateRef<RatingIndicatorContext> | null>;
25
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RatingTemplates, never>;
26
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RatingTemplates, never, never, { "indicatorTemplate": { "alias": "indicatorTemplate"; "required": false; "isSignal": true; }; }, {}, ["_userIndicatorTemplate"], never, true, never>;
27
+ }
28
+
29
+ /**
30
+ * @category control
31
+ */
32
+ declare class NgnRating extends RatingTemplates {
33
+ protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"rating", ["root", "symbol", "full", "empty", "invalid", "readonly", "disabled"], readonly []>>;
34
+ private readonly _hover;
35
+ /** Number of symbols. @default 5 */
36
+ readonly count: _angular_core.InputSignal<number>;
37
+ /** The value increment; supports fractions (e.g. 0.5). @default 1 */
38
+ readonly step: _angular_core.InputSignal<number>;
39
+ /** The filled symbol icon. Falls back to a filled star ({@link https://tabler.io/icons}). */
40
+ readonly iconFull: _angular_core.InputSignal<_iconify_types.IconifyIcon | _ngneers_controls_custom_types.NgnIconEntry | undefined>;
41
+ /** The empty symbol icon. Falls back to an outline star. */
42
+ readonly iconEmpty: _angular_core.InputSignal<_iconify_types.IconifyIcon | _ngneers_controls_custom_types.NgnIconEntry | undefined>;
43
+ /** Clicking the current value clears the rating back to `null`. @default true */
44
+ readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
45
+ /** Accessible value text; overrides the numeric readout. */
46
+ readonly valueText: _angular_core.InputSignal<string | undefined>;
47
+ /** Function producing accessible value text from the value. */
48
+ readonly valueTextFn: _angular_core.InputSignal<((value: number) => string) | undefined>;
49
+ /** The value the UI should paint: hover preview when hovering, else the model value. */
50
+ protected readonly displayValue: _angular_core.Signal<number>;
51
+ /** Zero-based indices for the symbols. */
52
+ protected readonly symbols: _angular_core.Signal<number[]>;
53
+ protected readonly valueTextValue: _angular_core.Signal<string | null>;
54
+ /** Fill ratio 0..1 for symbol `index` given the current display value (hover ?? value). */
55
+ protected fillRatio(index: number): number;
56
+ protected onKeyDown(event: KeyboardEvent): void;
57
+ /** Pointer moved over symbol `index` at fractional `offset` (0..1 within the symbol). */
58
+ protected onPointerMove(event: PointerEvent, index: number): void;
59
+ protected clearHover(): void;
60
+ protected onClick(event: PointerEvent, index: number): void;
61
+ /** Resolve the stepped value for a pointer position within symbol `index`. */
62
+ private valueAt;
63
+ private clamp;
64
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgnRating, never>;
65
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgnRating, "ngn-rating", never, { "count": { "alias": "count"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "iconFull": { "alias": "iconFull"; "required": false; "isSignal": true; }; "iconEmpty": { "alias": "iconEmpty"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; "valueTextFn": { "alias": "valueTextFn"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
66
+ }
67
+
68
+ export { NgnRating, RatingTemplates };
69
+ export type { RatingIndicatorContext };
@@ -3,9 +3,10 @@ import * as _ngneers_controls_api_ng from '@ngneers/controls/api/ng';
3
3
  import * as _ngneers_controls_themes from '@ngneers/controls-themes';
4
4
 
5
5
  declare class NgnScrollShadow {
6
- protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"scrollShadow", ["root", "scrolled-start", "scrolled-end", "scrolled-top", "scrolled-bottom"], readonly []>>;
6
+ protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"scrollShadow", ["root", "scrolled-start", "scrolled-end", "scrolled-top", "scrolled-bottom", "overlay", "surface", "unstyled"], readonly []>>;
7
7
  private readonly _el;
8
8
  private readonly _injector;
9
+ private readonly _renderer;
9
10
  /**
10
11
  * Which scroll axis to track and add shadow classes for.
11
12
  * @default 'horizontal'
@@ -17,9 +18,17 @@ declare class NgnScrollShadow {
17
18
  * @default undefined
18
19
  */
19
20
  readonly scrollShadowTarget: _angular_core.InputSignal<HTMLElement | undefined>;
21
+ /**
22
+ * Suppress the built-in edge-shadow overlay's styling (the theme hides it). The overlay element
23
+ * is still injected but rendered inert, so it never disturbs the scroll container's layout.
24
+ * Set this when the consumer paints its own shadows off the `scrolled-*` classes — e.g. the
25
+ * table anchors them to its sticky-column edges, reusing the shared `--ngn-scroll-shadow-color`.
26
+ * @default false
27
+ */
28
+ readonly unstyled: _angular_core.InputSignalWithTransform<boolean, unknown>;
20
29
  constructor();
21
30
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgnScrollShadow, never>;
22
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgnScrollShadow, "[ngnScrollShadow]", never, { "ngnScrollShadow": { "alias": "ngnScrollShadow"; "required": false; "isSignal": true; }; "scrollShadowTarget": { "alias": "scrollShadowTarget"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
31
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgnScrollShadow, "[ngnScrollShadow]", never, { "ngnScrollShadow": { "alias": "ngnScrollShadow"; "required": false; "isSignal": true; }; "scrollShadowTarget": { "alias": "scrollShadowTarget"; "required": false; "isSignal": true; }; "unstyled": { "alias": "ngnScrollShadowUnstyled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
23
32
  }
24
33
 
25
34
  export { NgnScrollShadow };
@@ -48,6 +48,8 @@ declare class NgnScroller<T> extends ScrollerTemplates<T> {
48
48
  protected readonly theme: _ngneers_controls_api_ng.ControlTemplateInfo<_ngneers_controls_themes.ControlTemplate<"scroller", ["root", "virtual", "item", "item-sticky"], readonly []>>;
49
49
  private readonly _el;
50
50
  private readonly _scrollAmount;
51
+ /** Remaining vertical scroll distance to the bottom (px). Proxied from the host scroll directive. */
52
+ readonly distanceFromEnd: _angular_core.Signal<number>;
51
53
  /**
52
54
  * The items to be displayed in the scroller.
53
55
  * This is a required input and should be an array of items of type {@link T}.
@@ -131,7 +133,7 @@ declare class NgnScroller<T> extends ScrollerTemplates<T> {
131
133
  index: number;
132
134
  }): unknown;
133
135
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgnScroller<any>, never>;
134
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgnScroller<any>, "ngn-scroller, [ngn-scroller]", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "fieldId": { "alias": "fieldId"; "required": false; "isSignal": true; }; "virtual": { "alias": "virtual"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "virtualPadding": { "alias": "virtualPadding"; "required": false; "isSignal": true; }; "focusable": { "alias": "focusable"; "required": false; "isSignal": true; }; "fieldSticky": { "alias": "fieldSticky"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgnScrollAmount; inputs: { "ngnScrollAmountContainer": "scrollContainer"; }; outputs: {}; }]>;
136
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NgnScroller<any>, "ngn-scroller, [ngn-scroller]", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "fieldId": { "alias": "fieldId"; "required": false; "isSignal": true; }; "virtual": { "alias": "virtual"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "virtualPadding": { "alias": "virtualPadding"; "required": false; "isSignal": true; }; "focusable": { "alias": "focusable"; "required": false; "isSignal": true; }; "fieldSticky": { "alias": "fieldSticky"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, [{ directive: typeof i1.NgnScrollAmount; inputs: { "ngnScrollAmountContainer": "scrollContainer"; }; outputs: {}; }]>;
135
137
  }
136
138
 
137
139
  declare class NgnScrollerItem implements AfterViewInit {