@cdevhub/ngx-tw 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +264 -49
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs +11 -7
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-alert.mjs +43 -29
- package/fesm2022/cdevhub-ngx-tw-alert.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs +103 -0
- package/fesm2022/cdevhub-ngx-tw-aspect-ratio.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs +56 -31
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-badge.mjs +61 -35
- package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +154 -93
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-button.mjs +24 -15
- package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +3 -3
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs +408 -215
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-card.mjs +33 -24
- package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs +144 -79
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +99 -47
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs +34 -20
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +46 -29
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs +195 -110
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +140 -73
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-core.mjs +16 -11
- package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +393 -149
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +305 -150
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs +56 -43
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +51 -33
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +905 -0
- package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +49 -26
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs +133 -74
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs +2 -2
- package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-icon.mjs +28 -17
- package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-input.mjs +37 -21
- package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-item.mjs +33 -24
- package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-menu.mjs +63 -48
- package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-number-input.mjs +622 -0
- package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs +137 -71
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-popover.mjs +101 -46
- package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +57 -30
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-radio.mjs +108 -57
- package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +46 -26
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-select.mjs +217 -122
- package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-separator.mjs +21 -12
- package/fesm2022/cdevhub-ngx-tw-separator.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs +58 -44
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-skeleton.mjs +25 -14
- package/fesm2022/cdevhub-ngx-tw-skeleton.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-slider.mjs +155 -79
- package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-sort.mjs +44 -25
- package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-spinner.mjs +29 -16
- package/fesm2022/cdevhub-ngx-tw-spinner.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -42
- package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-stat.mjs +107 -64
- package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs +113 -47
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-switch.mjs +61 -32
- package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +88 -42
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-table.mjs +266 -118
- package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs +101 -51
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +798 -0
- package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs +11 -7
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-theme.mjs +22 -14
- package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +243 -95
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs +149 -82
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-toast.mjs +89 -55
- package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +50 -28
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
- package/fesm2022/cdevhub-ngx-tw-transfer.mjs +1129 -0
- package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-tree.mjs +554 -0
- package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw.mjs +7 -0
- package/fesm2022/cdevhub-ngx-tw.mjs.map +1 -1
- package/index.json +1 -0
- package/package.json +45 -20
- package/theme/index.css +10 -2
- package/types/cdevhub-ngx-tw-aspect-ratio.d.ts +40 -0
- package/types/cdevhub-ngx-tw-calendar.d.ts +39 -8
- package/types/cdevhub-ngx-tw-command-palette.d.ts +7 -0
- package/types/cdevhub-ngx-tw-date-picker.d.ts +36 -10
- package/types/cdevhub-ngx-tw-file-upload.d.ts +250 -0
- package/types/cdevhub-ngx-tw-form-field.d.ts +22 -3
- package/types/cdevhub-ngx-tw-icon-lucide.d.ts +21 -3
- package/types/cdevhub-ngx-tw-number-input.d.ts +130 -0
- package/types/cdevhub-ngx-tw-popover.d.ts +8 -0
- package/types/cdevhub-ngx-tw-stepper.d.ts +30 -2
- package/types/cdevhub-ngx-tw-tab-nav.d.ts +8 -0
- package/types/cdevhub-ngx-tw-table.d.ts +30 -1
- package/types/cdevhub-ngx-tw-tabs.d.ts +8 -0
- package/types/cdevhub-ngx-tw-tags-input.d.ts +217 -0
- package/types/cdevhub-ngx-tw-time-picker.d.ts +31 -6
- package/types/cdevhub-ngx-tw-transfer.d.ts +330 -0
- package/types/cdevhub-ngx-tw-tree.d.ts +189 -0
- package/types/cdevhub-ngx-tw.d.ts +7 -0
|
@@ -52,6 +52,25 @@ declare abstract class FormFieldControl<T = unknown> {
|
|
|
52
52
|
* `providers: [{ provide: TW_FORM_FIELD_CONTROL, useExisting: MyControl }]`.
|
|
53
53
|
*/
|
|
54
54
|
declare const TW_FORM_FIELD_CONTROL: InjectionToken<FormFieldControl<unknown>>;
|
|
55
|
+
/**
|
|
56
|
+
* Minimal surface a wrapped control reads from its surrounding form-field —
|
|
57
|
+
* presence (via optional injection) plus whether a label is projected — without
|
|
58
|
+
* depending on the concrete {@link FormFieldComponent}. Controls inject
|
|
59
|
+
* {@link TW_FORM_FIELD} typed as this interface so detecting a parent form-field
|
|
60
|
+
* never pins the heavier component class into the control's own bundle.
|
|
61
|
+
*/
|
|
62
|
+
interface TwFormFieldParent {
|
|
63
|
+
/** Whether a `twLabel` element is projected into the form-field. */
|
|
64
|
+
readonly hasLabel: Signal<boolean>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Injection token exposing the wrapping {@link TwFormFieldParent}. The
|
|
68
|
+
* {@link FormFieldComponent} provides itself under this token; controls inject
|
|
69
|
+
* it with `{ optional: true }` to detect (and read label state from) a parent
|
|
70
|
+
* `tw-form-field` without referencing the concrete component class — keeping the
|
|
71
|
+
* form-field component out of each control's bundle.
|
|
72
|
+
*/
|
|
73
|
+
declare const TW_FORM_FIELD: InjectionToken<TwFormFieldParent>;
|
|
55
74
|
declare class LabelDirective {
|
|
56
75
|
private readonly formField;
|
|
57
76
|
private readonly elementRef;
|
|
@@ -119,7 +138,7 @@ declare class SuffixIconDirective extends SuffixDirective {
|
|
|
119
138
|
static ɵfac: i0.ɵɵFactoryDeclaration<SuffixIconDirective, never>;
|
|
120
139
|
static ɵdir: i0.ɵɵDirectiveDeclaration<SuffixIconDirective, "[twSuffixIcon]", never, {}, {}, never, never, true, never>;
|
|
121
140
|
}
|
|
122
|
-
declare class FormFieldComponent implements AfterContentInit {
|
|
141
|
+
declare class FormFieldComponent implements AfterContentInit, TwFormFieldParent {
|
|
123
142
|
/** Visual appearance of the field container. `'outline'` draws a full border around the control; `'filled'` uses a filled surface with a bottom border. Defaults to `'outline'`. */
|
|
124
143
|
readonly appearance: i0.InputSignal<FormFieldAppearance>;
|
|
125
144
|
/** Density of the field container. Maps to the inline-padding scale (`px-2 py-1` xs … `px-5 py-3` xl) and the floating-label font scale. Defaults to `'md'`. */
|
|
@@ -206,5 +225,5 @@ declare class FormFieldComponent implements AfterContentInit {
|
|
|
206
225
|
static ɵcmp: i0.ɵɵComponentDeclaration<FormFieldComponent, "tw-form-field", never, { "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "subscriptSizing": { "alias": "subscriptSizing"; "required": false; "isSignal": true; }; "hideRequiredMarker": { "alias": "hideRequiredMarker"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "hintAlign": { "alias": "hintAlign"; "required": false; "isSignal": true; }; }, {}, ["control", "labelChild", "hintChildren", "errorChildren", "prefixChildren"], ["[twPrefix]", "[twPrefixIcon]", "*", "[twSuffix]", "[twSuffixIcon]", "[twLabel]", "[twError]", "[twHint]"], true, never>;
|
|
207
226
|
}
|
|
208
227
|
|
|
209
|
-
export { ErrorDirective, FormFieldComponent, FormFieldControl, HintDirective, LabelDirective, PrefixDirective, PrefixIconDirective, SuffixDirective, SuffixIconDirective, TW_FORM_FIELD_CONTROL };
|
|
210
|
-
export type { FloatLabel, FormFieldAppearance, SubscriptSizing };
|
|
228
|
+
export { ErrorDirective, FormFieldComponent, FormFieldControl, HintDirective, LabelDirective, PrefixDirective, PrefixIconDirective, SuffixDirective, SuffixIconDirective, TW_FORM_FIELD, TW_FORM_FIELD_CONTROL };
|
|
229
|
+
export type { FloatLabel, FormFieldAppearance, SubscriptSizing, TwFormFieldParent };
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import { Provider } from '@angular/core';
|
|
2
|
-
import { LucideIconData, LucideIcons } from 'lucide-angular';
|
|
3
2
|
import { TwIconData } from '@cdevhub/ngx-tw/icon';
|
|
4
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A single Lucide SVG element: `[tagName, attributes]`.
|
|
6
|
+
*
|
|
7
|
+
* Declared structurally rather than imported from a Lucide package on purpose.
|
|
8
|
+
* An `import type … from 'lucide'` here would be emitted into the published
|
|
9
|
+
* `.d.ts`, making a package this library does not depend on a hard requirement
|
|
10
|
+
* for anyone who merely *type-checks* against this entry point. Declaring the
|
|
11
|
+
* shape locally keeps the entry point dependency-free and lets it accept icons
|
|
12
|
+
* from `lucide`, `lucide-angular`, or any other source with the same shape.
|
|
13
|
+
*/
|
|
14
|
+
type LucideIconNode = readonly [
|
|
15
|
+
tag: string,
|
|
16
|
+
attrs: Record<string, string | number | undefined>
|
|
17
|
+
];
|
|
18
|
+
/** Icon data as Lucide emits it: the SVG child elements, without the `<svg>` wrapper. */
|
|
19
|
+
type LucideIconData = readonly LucideIconNode[];
|
|
20
|
+
/** A map of PascalCase icon names to Lucide icon data, as produced by `import { Star } from 'lucide'`. */
|
|
21
|
+
type LucideIcons = Readonly<Record<string, LucideIconData>>;
|
|
5
22
|
/**
|
|
6
23
|
* Converts a single Lucide icon to the generic `TwIconData` format.
|
|
7
24
|
*
|
|
8
|
-
* Lucide's
|
|
25
|
+
* Lucide's icon data is structurally identical to `TwIconData`.
|
|
9
26
|
* This function exists for type-level conversion and explicit intent.
|
|
10
27
|
*/
|
|
11
28
|
declare function fromLucideIcon(icon: LucideIconData): TwIconData;
|
|
@@ -17,7 +34,7 @@ declare function fromLucideIcon(icon: LucideIconData): TwIconData;
|
|
|
17
34
|
* @example
|
|
18
35
|
* ```ts
|
|
19
36
|
* import { provideTwLucideIcons } from '@cdevhub/ngx-tw/icon/lucide';
|
|
20
|
-
* import { ChevronRight, Star, Check } from 'lucide
|
|
37
|
+
* import { ChevronRight, Star, Check } from 'lucide';
|
|
21
38
|
*
|
|
22
39
|
* export const appConfig = {
|
|
23
40
|
* providers: [provideTwLucideIcons({ ChevronRight, Star, Check })]
|
|
@@ -27,3 +44,4 @@ declare function fromLucideIcon(icon: LucideIconData): TwIconData;
|
|
|
27
44
|
declare function provideTwLucideIcons(icons: LucideIcons): Provider[];
|
|
28
45
|
|
|
29
46
|
export { fromLucideIcon, provideTwLucideIcons };
|
|
47
|
+
export type { LucideIconData, LucideIconNode, LucideIcons };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
3
|
+
import { TwSize } from '@cdevhub/ngx-tw/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Turns a plain `<input twInput twNumberInput>` into a robust numeric field
|
|
7
|
+
* without `type="number"` — fixing the broken-on-mobile, browser-inconsistent
|
|
8
|
+
* native control. It composes the sibling {@link InputDirective}: that directive
|
|
9
|
+
* keeps owning the form-field chrome, error-state, and `aria-invalid` /
|
|
10
|
+
* `aria-required`, while this directive owns the numeric value transport,
|
|
11
|
+
* locale-aware parse/format, spinbutton ARIA, `inputmode`, and keyboard stepping.
|
|
12
|
+
*
|
|
13
|
+
* Pair it with the companion `<tw-number-stepper [for]="ref">` for visible
|
|
14
|
+
* up/down spinner buttons.
|
|
15
|
+
*
|
|
16
|
+
* Forms: implements `ControlValueAccessor`, so the value round-trips as a real
|
|
17
|
+
* `number | null` (never a string) through template-driven, reactive, and
|
|
18
|
+
* signal-based forms.
|
|
19
|
+
*/
|
|
20
|
+
declare class NumberInputDirective implements ControlValueAccessor {
|
|
21
|
+
private readonly el;
|
|
22
|
+
/** Smallest accepted value. Clamps the committed value (on blur, Enter, and stepping) and sets `aria-valuemin`. Does not clamp per keystroke. Defaults to `undefined` (no lower bound). */
|
|
23
|
+
readonly min: _angular_core.InputSignal<number | undefined>;
|
|
24
|
+
/** Largest accepted value. Clamps the committed value (on blur, Enter, and stepping) and sets `aria-valuemax`. Does not clamp per keystroke. Defaults to `undefined` (no upper bound). */
|
|
25
|
+
readonly max: _angular_core.InputSignal<number | undefined>;
|
|
26
|
+
/** Amount added or subtracted by ArrowUp/ArrowDown and the stepper buttons. Defaults to `1`. Values `<= 0` or non-finite fall back to `1`. */
|
|
27
|
+
readonly step: _angular_core.InputSignal<number>;
|
|
28
|
+
/** `Intl.NumberFormat` options driving the blurred display (grouping, decimals, currency). The formatter's resolved `maximumFractionDigits` also sets commit-time rounding precision and switches `inputmode` to `'numeric'` when it is `0`. Percent style is not supported in v1. Defaults to `undefined` (locale default number formatting, grouping on). */
|
|
29
|
+
readonly format: _angular_core.InputSignal<Intl.NumberFormatOptions | undefined>;
|
|
30
|
+
/** BCP-47 locale for `Intl.NumberFormat` formatting and for locale-aware parsing (decimal and group separators). Defaults to `undefined` (the runtime default locale). */
|
|
31
|
+
readonly locale: _angular_core.InputSignal<string | undefined>;
|
|
32
|
+
/** Fires when the committed numeric value changes through user interaction (typing, stepping, clamping on blur/Enter). Does not fire on `writeValue` (programmatic form writes). Useful for non-form / template-ref usage alongside the `value` signal. */
|
|
33
|
+
readonly valueChange: _angular_core.OutputEmitterRef<number | null>;
|
|
34
|
+
private readonly _value;
|
|
35
|
+
private readonly cvaDisabled;
|
|
36
|
+
private readonly readonlySig;
|
|
37
|
+
/** The current committed numeric value, or `null` when empty / unparseable. Read this from a template ref (`#n="twNumberInput"`) for non-form usage. */
|
|
38
|
+
readonly value: _angular_core.Signal<number | null>;
|
|
39
|
+
/** @internal Formatted display text surfaced through `TW_INPUT_VALUE_ACCESSOR` so the sibling InputDirective's empty / float-label state tracks the text in the box (not the numeric model). Updated on every field mutation. */
|
|
40
|
+
readonly displayText: _angular_core.WritableSignal<string>;
|
|
41
|
+
/** True when the control is disabled. Reactively tracks the reactive-forms path (`setDisabledState` via `control.disable()`) and a static `disabled` attribute read at mount. A runtime-toggled declarative `[disabled]` binding without reactive forms is NOT reactively tracked (v2 limitation — same class as `readonly`). Read by the companion stepper so its buttons disable in lock-step. */
|
|
42
|
+
readonly disabled: _angular_core.Signal<boolean>;
|
|
43
|
+
/** True when the host input carries the `readonly` attribute (static / declarative, seeded after render). A runtime toggle of the bare `readonly` attribute is not reactively tracked (v2). Read by the companion stepper so its buttons disable in lock-step. */
|
|
44
|
+
readonly readonly: _angular_core.Signal<boolean>;
|
|
45
|
+
/** @internal Mobile-keyboard hint: `'numeric'` for integer-only formats, else `'decimal'`. */
|
|
46
|
+
readonly inputMode: _angular_core.Signal<"numeric" | "decimal">;
|
|
47
|
+
/** @internal Locale group / decimal separators, memoized per `locale()`. */
|
|
48
|
+
private readonly separators;
|
|
49
|
+
private _focused;
|
|
50
|
+
private _lastValue;
|
|
51
|
+
private _lastDisplay;
|
|
52
|
+
private onChange;
|
|
53
|
+
private onTouched;
|
|
54
|
+
constructor();
|
|
55
|
+
/** @internal */
|
|
56
|
+
writeValue(value: number | null | undefined): void;
|
|
57
|
+
/** @internal */
|
|
58
|
+
registerOnChange(fn: (value: number | null) => void): void;
|
|
59
|
+
/** @internal */
|
|
60
|
+
registerOnTouched(fn: () => void): void;
|
|
61
|
+
/** @internal */
|
|
62
|
+
setDisabledState(isDisabled: boolean): void;
|
|
63
|
+
/** Steps the value up: treats an empty field as `0`, adds `step`, clamps to `[min,max]`, rounds to the formatter's resolved precision, formats, and writes both the display and the model. Emits `valueChange`. No-op when the host input is disabled or readonly. Does not move focus. */
|
|
64
|
+
increment(): void;
|
|
65
|
+
/** Steps the value down: treats an empty field as `0`, subtracts `step`, clamps to `[min,max]`, rounds, formats, writes display and model. Emits `valueChange`. No-op when disabled or readonly. Does not move focus. */
|
|
66
|
+
decrement(): void;
|
|
67
|
+
/** Moves focus to the underlying input element. */
|
|
68
|
+
focus(options?: FocusOptions): void;
|
|
69
|
+
/** @internal */
|
|
70
|
+
onInput(): void;
|
|
71
|
+
/** @internal */
|
|
72
|
+
onFocus(): void;
|
|
73
|
+
/** @internal */
|
|
74
|
+
onBlur(): void;
|
|
75
|
+
/** @internal */
|
|
76
|
+
onKeydown(event: KeyboardEvent): void;
|
|
77
|
+
private stepBy;
|
|
78
|
+
private commitFromElement;
|
|
79
|
+
private commitNumber;
|
|
80
|
+
private commitEmpty;
|
|
81
|
+
private revertToLastCommitted;
|
|
82
|
+
private resolvedStep;
|
|
83
|
+
private clamp;
|
|
84
|
+
private roundToPrecision;
|
|
85
|
+
private resolvedMaxFractionDigits;
|
|
86
|
+
private formatValue;
|
|
87
|
+
/**
|
|
88
|
+
* Parse a raw string to `number | null` in a load-bearing order: the `e`/`E`
|
|
89
|
+
* rejection MUST precede stripping (otherwise `'1e3'` would survive as `'13'`).
|
|
90
|
+
*/
|
|
91
|
+
private parseValue;
|
|
92
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NumberInputDirective, never>;
|
|
93
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NumberInputDirective, "input[twNumberInput]", ["twNumberInput"], { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The visible up/down spinner column for a {@link NumberInputDirective}. A
|
|
98
|
+
* directive cannot emit sibling DOM, so the spinner buttons live in this tiny
|
|
99
|
+
* companion. Bind it to the directive via a template ref and drop it into a
|
|
100
|
+
* `<tw-form-field>`'s `[twSuffix]` slot (or a standalone flex row):
|
|
101
|
+
*
|
|
102
|
+
* ```html
|
|
103
|
+
* <input twInput twNumberInput #qty="twNumberInput" [formControl]="ctrl" />
|
|
104
|
+
* <tw-number-stepper twSuffix [for]="qty" />
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* The buttons are kept out of the tab order (`tabindex="-1"`) — the spinbutton
|
|
108
|
+
* input owns value + keyboard semantics — and refocus the input after stepping.
|
|
109
|
+
*/
|
|
110
|
+
declare class NumberStepperComponent {
|
|
111
|
+
/** The number-input directive instance this stepper controls. Bind to a template ref, e.g. `[for]="qty"` with `#qty="twNumberInput"`. When omitted, the buttons render but do nothing (no-op) and disable. */
|
|
112
|
+
readonly for: _angular_core.InputSignal<NumberInputDirective | undefined>;
|
|
113
|
+
/** Button + glyph density. Match the field's `size` for visual alignment. Defaults to `'md'`. */
|
|
114
|
+
readonly size: _angular_core.InputSignal<TwSize>;
|
|
115
|
+
private readonly variant;
|
|
116
|
+
/** @internal */
|
|
117
|
+
readonly groupClasses: _angular_core.Signal<string>;
|
|
118
|
+
/** @internal */
|
|
119
|
+
readonly buttonClasses: _angular_core.Signal<string>;
|
|
120
|
+
/** @internal */
|
|
121
|
+
readonly iconClasses: _angular_core.Signal<string>;
|
|
122
|
+
/** @internal Disabled when there is no target, or the target input is disabled / readonly. */
|
|
123
|
+
readonly isDisabled: _angular_core.Signal<boolean>;
|
|
124
|
+
/** @internal Step the bound directive, then refocus the input (the refocus lives here, not in `increment`/`decrement`). */
|
|
125
|
+
onStep(direction: 1 | -1): void;
|
|
126
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NumberStepperComponent, never>;
|
|
127
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NumberStepperComponent, "tw-number-stepper", ["twNumberStepper"], { "for": { "alias": "for"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["[slot=up]", "[slot=down]"], true, never>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { NumberInputDirective, NumberStepperComponent };
|
|
@@ -111,6 +111,14 @@ declare class PopoverDirective {
|
|
|
111
111
|
private setupFocusTrap;
|
|
112
112
|
private destroyFocusTrap;
|
|
113
113
|
private disposeOverlay;
|
|
114
|
+
/**
|
|
115
|
+
* Aborts an in-flight close, leaving the popover open.
|
|
116
|
+
*
|
|
117
|
+
* `closePopover` tears the focus trap down immediately and defers only the
|
|
118
|
+
* detach, so cancelling has to rebuild the trap — the overlay itself is still
|
|
119
|
+
* attached and the instance still live.
|
|
120
|
+
*/
|
|
121
|
+
private cancelPendingClose;
|
|
114
122
|
private clearCloseTimer;
|
|
115
123
|
private resolveScrollStrategy;
|
|
116
124
|
private resolvePanelClass;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { TemplateRef, AfterViewInit, Provider } from '@angular/core';
|
|
2
|
+
import { TemplateRef, AfterViewInit, QueryList, Provider } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/cdk/stepper';
|
|
4
|
-
import { CdkStep, CdkStepLabel, CdkStepper, StepperOrientation, StepState, StepperOptions } from '@angular/cdk/stepper';
|
|
4
|
+
import { CdkStep, CdkStepLabel, CdkStepper, StepperOrientation, StepState, CdkStepHeader, StepperOptions } from '@angular/cdk/stepper';
|
|
5
5
|
export { STEPPER_GLOBAL_OPTIONS, STEP_STATE, StepState, StepperOptions, StepperOrientation, StepperSelectionEvent } from '@angular/cdk/stepper';
|
|
6
6
|
import { TwColor, TwSize } from '@cdevhub/ngx-tw/core';
|
|
7
7
|
|
|
@@ -106,6 +106,34 @@ declare class StepperComponent extends CdkStepper implements AfterViewInit {
|
|
|
106
106
|
/** @internal Context supplied to custom icon templates. */
|
|
107
107
|
iconContext(index: number): StepperIconContext;
|
|
108
108
|
/** @internal Click handler for the step header button. */
|
|
109
|
+
/**
|
|
110
|
+
* @internal Re-declares CdkStepper's `_stepHeader` query as a **view** query.
|
|
111
|
+
*
|
|
112
|
+
* CdkStepper declares it as `@ContentChildren`, which assumes the host
|
|
113
|
+
* projects its own headers. `tw-stepper` renders the header strip inside its
|
|
114
|
+
* own template instead, so the base query matched nothing: `_sortedHeaders`
|
|
115
|
+
* stayed empty, the FocusKeyManager had zero items, and arrow-key navigation
|
|
116
|
+
* silently did nothing at all. Angular Material overrides the same query for
|
|
117
|
+
* the same reason.
|
|
118
|
+
*
|
|
119
|
+
* Decorator form, not `viewChildren()`, because CdkStepper subscribes to
|
|
120
|
+
* `_stepHeader.changes` — a QueryList API that signal queries do not expose.
|
|
121
|
+
*/
|
|
122
|
+
_stepHeader: QueryList<CdkStepHeader>;
|
|
123
|
+
/**
|
|
124
|
+
* @internal Which step header currently holds the single tab stop.
|
|
125
|
+
*
|
|
126
|
+
* Mirrors CdkStepper's `_getFocusIndex()` into a signal because that method
|
|
127
|
+
* reads `_keyManager.activeItemIndex`, a plain property — and CdkStepper's
|
|
128
|
+
* `_onKeydown` does not call `_stateChanged()` on the arrow-key path, so an
|
|
129
|
+
* OnPush template binding straight to `_getFocusIndex()` would render the
|
|
130
|
+
* roving tabindex once and then go stale the moment the user arrows.
|
|
131
|
+
*/
|
|
132
|
+
readonly focusIndexValue: _angular_core.WritableSignal<number>;
|
|
133
|
+
/** @internal Re-reads the CDK key manager's active item into `focusIndexValue`. */
|
|
134
|
+
private syncFocusIndex;
|
|
135
|
+
/** @internal Relays tablist keydown to CdkStepper, then republishes the tab stop. */
|
|
136
|
+
onTablistKeydown(event: KeyboardEvent): void;
|
|
109
137
|
onHeaderClick(step: StepComponent, index: number): void;
|
|
110
138
|
/** @internal Whether the stepper should render the error state for a step. */
|
|
111
139
|
shouldRenderError(step: StepComponent): boolean;
|
|
@@ -41,6 +41,14 @@ declare class TabNavComponent {
|
|
|
41
41
|
/** @internal Resolved panel — explicit `tabPanel` input wins, falls back to a projected `<tw-tab-nav-panel>` inside the nav. */
|
|
42
42
|
readonly resolvedPanel: _angular_core.Signal<TabNavPanel | undefined>;
|
|
43
43
|
private readonly liveAnnouncer;
|
|
44
|
+
private readonly directionality;
|
|
45
|
+
private readonly destroyRef;
|
|
46
|
+
/**
|
|
47
|
+
* Live layout direction. Hardcoding 'ltr' inverts ArrowLeft/ArrowRight in RTL
|
|
48
|
+
* locales — the arrow moves to the next link in DOM order but the previous
|
|
49
|
+
* one visually. Mirrored into a signal so the key manager rebuilds on change.
|
|
50
|
+
*/
|
|
51
|
+
private readonly layoutDirection;
|
|
44
52
|
/** Tracks the previously-announced active link id so we only announce on actual changes. `null` = before the first sync. */
|
|
45
53
|
private readonly previousActiveLinkId;
|
|
46
54
|
private readonly layoutResult;
|
|
@@ -322,7 +322,16 @@ declare class ColumnComponent<T = unknown> {
|
|
|
322
322
|
declare class TableComponent<T = unknown> {
|
|
323
323
|
/** The table's rows. Accepts a plain array, an `Observable<readonly T[]>`, or a CDK `DataSource<T>`. Wired directly to `CdkTable.dataSource`. Defaults to an empty array. */
|
|
324
324
|
readonly data: _angular_core.InputSignal<TwTableDataSourceInput<T>>;
|
|
325
|
-
/**
|
|
325
|
+
/**
|
|
326
|
+
* Tracking function used to identify rows across data changes. When unset, rows are identified by
|
|
327
|
+
* object reference.
|
|
328
|
+
*
|
|
329
|
+
* This drives **selection and expansion membership** as well as CDK's DOM diffing. Supply it when
|
|
330
|
+
* the data source re-emits equal-but-new objects — an HTTP refetch, an immutable store — or the
|
|
331
|
+
* user's selection empties on every refresh with no event and no error. It is called with `-1` as
|
|
332
|
+
* the index for membership lookups, so return a value derived from the row alone (`row.id`), not
|
|
333
|
+
* from the index.
|
|
334
|
+
*/
|
|
326
335
|
readonly trackBy: _angular_core.InputSignal<TrackByFunction<T> | undefined>;
|
|
327
336
|
/** When true, renders the loading slot as an overlay and applies `opacity-60 pointer-events-none` to the body. Defaults to `false`. */
|
|
328
337
|
readonly loading: _angular_core.InputSignal<boolean>;
|
|
@@ -444,6 +453,26 @@ declare class TableComponent<T = unknown> {
|
|
|
444
453
|
collapse(row: T): void;
|
|
445
454
|
/** Toggles the expansion state of the given row. */
|
|
446
455
|
toggleExpansion(row: T): void;
|
|
456
|
+
/**
|
|
457
|
+
* @internal Identity key for a row.
|
|
458
|
+
*
|
|
459
|
+
* Selection and expansion are membership questions, and answering them by
|
|
460
|
+
* object reference breaks the moment a data source re-emits equal-but-new
|
|
461
|
+
* objects — an HTTP refetch, an immutable store, `signal.set([...mapped])`.
|
|
462
|
+
* The user's selection empties with no event and no error.
|
|
463
|
+
*
|
|
464
|
+
* `trackBy` is already the consumer's declaration of row identity, so it is
|
|
465
|
+
* reused here rather than adding a second, redundant input. With no `trackBy`
|
|
466
|
+
* the key IS the row, i.e. reference identity — the same default CDK uses.
|
|
467
|
+
*
|
|
468
|
+
* Note this must be a *key* function, not a comparator: a comparator would fix
|
|
469
|
+
* identity but leave membership as an O(rows x selected) scan, and a
|
|
470
|
+
* reference-keyed Set would fix the scan but ignore custom identity. Only a
|
|
471
|
+
* key fixes both.
|
|
472
|
+
*/
|
|
473
|
+
private rowKey;
|
|
474
|
+
/** @internal O(1) membership lookup for the current selection, keyed by `rowKey`. */
|
|
475
|
+
private readonly selectedKeys;
|
|
447
476
|
/** Whether a given row is currently in the `selected` list. */
|
|
448
477
|
isSelected(row: T): boolean;
|
|
449
478
|
/** Selects or deselects a row and emits `selectionChange`. */
|
|
@@ -68,6 +68,14 @@ declare class TabsComponent implements AfterViewInit {
|
|
|
68
68
|
readonly closed: _angular_core.OutputEmitterRef<string>;
|
|
69
69
|
private readonly destroyRef;
|
|
70
70
|
private readonly liveAnnouncer;
|
|
71
|
+
private readonly directionality;
|
|
72
|
+
/**
|
|
73
|
+
* Live layout direction, mirrored into a signal so the key manager rebuilds
|
|
74
|
+
* when it changes. Without this the tablist hardcodes 'ltr' and ArrowRight
|
|
75
|
+
* moves to the next tab in DOM order but the *previous* tab visually in an
|
|
76
|
+
* RTL locale. CdkStepper and `tw-split` already honour Directionality.
|
|
77
|
+
*/
|
|
78
|
+
private readonly layoutDirection;
|
|
71
79
|
/** @internal */
|
|
72
80
|
readonly tabs: _angular_core.Signal<readonly TabComponent[]>;
|
|
73
81
|
/** @internal */
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { OnInit, Signal } from '@angular/core';
|
|
3
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
4
|
+
import { TwColor, TwSize, ErrorStateMatcher } from '@cdevhub/ngx-tw/core';
|
|
5
|
+
import { FormFieldControl } from '@cdevhub/ngx-tw/form-field';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Maps the committed input text to a tag value. The default returns the trimmed
|
|
9
|
+
* string, so the value type defaults to `string`. Override to build object tags
|
|
10
|
+
* (e.g. `(text) => ({ id: crypto.randomUUID(), name: text })`).
|
|
11
|
+
*/
|
|
12
|
+
type TwTagFactory<T> = (text: string) => T;
|
|
13
|
+
/**
|
|
14
|
+
* Maps a tag value to its visible chip label and the remove-button accessible
|
|
15
|
+
* name. Defaults to `String(tag)`.
|
|
16
|
+
*/
|
|
17
|
+
type TwTagLabelFn<T> = (tag: T) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Equality comparator used to dedupe tags when `allowDuplicates` is `false` and
|
|
20
|
+
* to resolve a tag passed to `removeTag`. Defaults to `Object.is`.
|
|
21
|
+
*/
|
|
22
|
+
type TwTagCompareFn<T> = (a: T, b: T) => boolean;
|
|
23
|
+
/** Payload of the `tagAdded` output. */
|
|
24
|
+
interface TwTagAddedEvent<T> {
|
|
25
|
+
/** The tag that was committed. */
|
|
26
|
+
tag: T;
|
|
27
|
+
/** The full tag array after the addition. A fresh array reference. */
|
|
28
|
+
value: T[];
|
|
29
|
+
}
|
|
30
|
+
/** Payload of the `tagRemoved` output. */
|
|
31
|
+
interface TwTagRemovedEvent<T> {
|
|
32
|
+
/** The tag that was removed. */
|
|
33
|
+
tag: T;
|
|
34
|
+
/** The full tag array after the removal. A fresh array reference. */
|
|
35
|
+
value: T[];
|
|
36
|
+
/** The index the removed tag occupied before removal. */
|
|
37
|
+
index: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Free-text multi-value input. The user types a token and commits it via Enter,
|
|
42
|
+
* a separator key, paste, or blur; committed tokens render as dismissible chips
|
|
43
|
+
* (composing `[twBadge]`) inline with the text input. The value is exposed as a
|
|
44
|
+
* real `T[]` (default `string[]`) through `ControlValueAccessor`, so it works
|
|
45
|
+
* with template-driven, reactive, and signal forms and integrates with
|
|
46
|
+
* `<tw-form-field>` for label / hint / error chrome.
|
|
47
|
+
*
|
|
48
|
+
* The control is a single tab stop with a roving-tabindex chip strip
|
|
49
|
+
* (Material `MatChipGrid` interaction model): Arrow keys traverse chips and the
|
|
50
|
+
* input, Delete / a two-step Backspace remove chips, and `LiveAnnouncer` voices
|
|
51
|
+
* add / remove. Autocomplete suggestions are out of scope (use `tw-combobox`).
|
|
52
|
+
*/
|
|
53
|
+
declare class TagsInputComponent<T = string> extends FormFieldControl<T[]> implements ControlValueAccessor, OnInit {
|
|
54
|
+
/** Semantic color for the container focus-within ring and the chip accent. Defaults to `'primary'`. */
|
|
55
|
+
readonly color: _angular_core.InputSignal<TwColor>;
|
|
56
|
+
/** Controls overall density: container padding, chip size, and text scale. Defaults to `'md'`. */
|
|
57
|
+
readonly size: _angular_core.InputSignal<TwSize>;
|
|
58
|
+
/** When true, blocks typing, committing, and chip removal, and applies muted styling. Reactive forms also propagate disabled via `setDisabledState`. Defaults to `false`. */
|
|
59
|
+
readonly disabledInput: _angular_core.InputSignal<boolean>;
|
|
60
|
+
/** Marks the control as required. Mirrored to the input's `aria-required`. Also inferred from `Validators.required` on a bound control. Defaults to `false`. */
|
|
61
|
+
readonly requiredInput: _angular_core.InputSignal<boolean>;
|
|
62
|
+
/** Placeholder shown in the text input only while there are no chips and the input is empty. */
|
|
63
|
+
readonly placeholder: _angular_core.InputSignal<string | undefined>;
|
|
64
|
+
/** Keys that commit the in-progress text as a tag. Each entry is a `KeyboardEvent.key` value (`'Enter'`) or a single separator character (`','`). Single-character separators also split pasted text. Defaults to `['Enter', ',']`. */
|
|
65
|
+
readonly separatorKeys: _angular_core.InputSignal<readonly string[]>;
|
|
66
|
+
/** When true, blurring the control while the input holds non-empty text commits it as a tag. Defaults to `false`. */
|
|
67
|
+
readonly addOnBlur: _angular_core.InputSignal<boolean>;
|
|
68
|
+
/** Maximum number of tags. Once reached, further commits are blocked and announced. Does not truncate an oversized `writeValue`. Defaults to `undefined` (no limit). */
|
|
69
|
+
readonly maxTags: _angular_core.InputSignal<number | undefined>;
|
|
70
|
+
/** When false (default), a committed tag equal (per `compareWith`) to an existing tag is dropped silently. When true, duplicates are kept. Defaults to `false`. */
|
|
71
|
+
readonly allowDuplicates: _angular_core.InputSignal<boolean>;
|
|
72
|
+
/** Maps committed text to a tag value. Default is identity — the trimmed string. Override to build object tags. */
|
|
73
|
+
readonly createTag: _angular_core.InputSignal<TwTagFactory<T>>;
|
|
74
|
+
/** Maps a tag value to its visible chip label and the remove-button accessible name. Defaults to `String(tag)`. */
|
|
75
|
+
readonly tagLabel: _angular_core.InputSignal<TwTagLabelFn<T>>;
|
|
76
|
+
/** Equality comparator used for dedup when `allowDuplicates` is false. Defaults to `Object.is` (reference / value identity). String tags dedupe case-sensitively by default; pass `(a, b) => a.toLowerCase() === b.toLowerCase()` for case-insensitive dedup. */
|
|
77
|
+
readonly compareWith: _angular_core.InputSignal<TwTagCompareFn<T>>;
|
|
78
|
+
/** Applied to the text input for labeling and identification only; does not submit the tag array via native (non-Angular) form posting. */
|
|
79
|
+
readonly name: _angular_core.InputSignal<string | undefined>;
|
|
80
|
+
/** Id on the host element. Auto-generated as `tw-tags-input-N` when not provided. Used by the form-field's `<label for>` association. */
|
|
81
|
+
readonly idInput: _angular_core.InputSignal<string | undefined>;
|
|
82
|
+
/** Accessible name applied to the control when no visible label is wired. Mirrored to `aria-label`. */
|
|
83
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
84
|
+
/** ID of an external element that labels the control. Mirrored to `aria-labelledby`. */
|
|
85
|
+
readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
|
|
86
|
+
/** ID of an external element that describes the control. Form-field merges its hint / error ids alongside. */
|
|
87
|
+
readonly ariaDescribedby: _angular_core.InputSignal<string | undefined>;
|
|
88
|
+
/** Per-instance override of the {@link ErrorStateMatcher}. When omitted, uses the `TW_ERROR_STATE_MATCHER` token's value. */
|
|
89
|
+
readonly errorStateMatcher: _angular_core.InputSignal<ErrorStateMatcher | undefined>;
|
|
90
|
+
/** Fires when the tag array changes through user interaction (add, remove, clear). Emits a fresh array reference. Does not fire on `writeValue`. */
|
|
91
|
+
readonly valueChange: _angular_core.OutputEmitterRef<T[]>;
|
|
92
|
+
/** Fires when a tag is committed via Enter, a separator key, paste, or `addTag()`. Does not fire for dropped duplicates, blocked-by-max commits, empty commits, or `writeValue`. */
|
|
93
|
+
readonly tagAdded: _angular_core.OutputEmitterRef<TwTagAddedEvent<T>>;
|
|
94
|
+
/** Fires when a tag is removed via the remove button, Backspace / Delete, or `removeTag()`. Does not fire on `writeValue` or `clear()`. */
|
|
95
|
+
readonly tagRemoved: _angular_core.OutputEmitterRef<TwTagRemovedEvent<T>>;
|
|
96
|
+
private readonly focusMonitor;
|
|
97
|
+
private readonly liveAnnouncer;
|
|
98
|
+
private readonly elementRef;
|
|
99
|
+
private readonly destroyRef;
|
|
100
|
+
private readonly ngControl;
|
|
101
|
+
private readonly parentForm;
|
|
102
|
+
private readonly parentFormGroup;
|
|
103
|
+
private readonly defaultMatcher;
|
|
104
|
+
private readonly formField;
|
|
105
|
+
private readonly textInputRef;
|
|
106
|
+
private readonly removeButtons;
|
|
107
|
+
private onChange;
|
|
108
|
+
private onTouched;
|
|
109
|
+
private readonly tags;
|
|
110
|
+
/** The current in-progress (uncommitted) text in the input. Empty when nothing is typed. */
|
|
111
|
+
readonly inputText: _angular_core.WritableSignal<string>;
|
|
112
|
+
/** @internal Roving-tabindex position. `null` = the text input is the active element; a number = that chip's remove button. */
|
|
113
|
+
protected readonly activeChipIndex: _angular_core.WritableSignal<number | null>;
|
|
114
|
+
private readonly cvaDisabled;
|
|
115
|
+
private readonly _focused;
|
|
116
|
+
private readonly _ngControlRev;
|
|
117
|
+
private readonly _formSubmitRev;
|
|
118
|
+
private readonly describedByIdsSignal;
|
|
119
|
+
private readonly labelledByIdsSignal;
|
|
120
|
+
/** Nonce bumped only on explicit focus intent — keeps the focus effect from stealing focus on unrelated renders. */
|
|
121
|
+
private readonly focusNonce;
|
|
122
|
+
private lastMaxAnnounce;
|
|
123
|
+
private readonly uid;
|
|
124
|
+
/** @internal Fallback id used when the consumer does not set `[id]`. */
|
|
125
|
+
readonly hostId: string;
|
|
126
|
+
/** @internal */
|
|
127
|
+
readonly id: Signal<string>;
|
|
128
|
+
/** The current tag array (empty array when there are no tags). Read from a template ref (`#t="twTagsInput"`) for non-form usage. Doubles as the `FormFieldControl` contract member. */
|
|
129
|
+
readonly value: Signal<T[]>;
|
|
130
|
+
/** @internal */
|
|
131
|
+
readonly focused: Signal<boolean>;
|
|
132
|
+
/** @internal Empty when there are no chips AND the input text is blank — drives the form-field floating label. */
|
|
133
|
+
readonly empty: Signal<boolean>;
|
|
134
|
+
/** @internal */
|
|
135
|
+
readonly disabled: Signal<boolean>;
|
|
136
|
+
/** @internal */
|
|
137
|
+
readonly required: Signal<boolean>;
|
|
138
|
+
/** @internal */
|
|
139
|
+
readonly errorState: Signal<boolean>;
|
|
140
|
+
/** @internal Active validation errors map from the bound control, for `[twError match="…"]` filtering. */
|
|
141
|
+
readonly errors: Signal<Record<string, unknown> | null>;
|
|
142
|
+
/** @internal */
|
|
143
|
+
readonly controlType = "tags-input";
|
|
144
|
+
/** @internal */
|
|
145
|
+
readonly userAriaDescribedBy: Signal<string | undefined>;
|
|
146
|
+
/** @internal */
|
|
147
|
+
readonly userAriaLabelledby: Signal<string | undefined>;
|
|
148
|
+
/** @internal Merged `aria-describedby` (form-field hint/error ids + consumer-supplied). */
|
|
149
|
+
readonly resolvedDescribedBy: Signal<string>;
|
|
150
|
+
/** @internal Merged `aria-labelledby` (form-field label id + consumer-supplied). */
|
|
151
|
+
readonly resolvedLabelledBy: Signal<string>;
|
|
152
|
+
private readonly variantResult;
|
|
153
|
+
/** @internal */
|
|
154
|
+
readonly rootClasses: Signal<string>;
|
|
155
|
+
/** @internal */
|
|
156
|
+
readonly chipClasses: Signal<string>;
|
|
157
|
+
/** @internal */
|
|
158
|
+
readonly chipLabelClasses: Signal<string>;
|
|
159
|
+
/** @internal */
|
|
160
|
+
readonly removeButtonClasses: Signal<string>;
|
|
161
|
+
/** @internal */
|
|
162
|
+
readonly removeIconClasses: Signal<string>;
|
|
163
|
+
/** @internal */
|
|
164
|
+
readonly inputClasses: Signal<string>;
|
|
165
|
+
/** @internal Pre-resolved chip view models so the template never calls accessor functions inline. */
|
|
166
|
+
readonly chipViews: Signal<{
|
|
167
|
+
tag: T;
|
|
168
|
+
label: string;
|
|
169
|
+
removeLabel: string;
|
|
170
|
+
index: number;
|
|
171
|
+
}[]>;
|
|
172
|
+
constructor();
|
|
173
|
+
/** Commits `text` as a tag (trim → `createTag` → dedup unless `allowDuplicates` → `maxTags` check). Returns true if a tag was added, false if dropped (empty / duplicate / max). Emits `tagAdded` + `valueChange` on success. No-op when disabled. */
|
|
174
|
+
addTag(text: string): boolean;
|
|
175
|
+
/** Removes a tag by value (first match via `compareWith`) or by index when a number is passed. Emits `tagRemoved` + `valueChange` and restores focus. No-op when disabled or when no match. Note: when the tag type is `number`, the argument is treated as an index. */
|
|
176
|
+
removeTag(tag: T | number): void;
|
|
177
|
+
/** Removes all tags and clears the in-progress input text. Emits `valueChange` with `[]`. Does NOT emit `tagRemoved` per tag (bulk reset). No-op when already empty or disabled. */
|
|
178
|
+
clear(): void;
|
|
179
|
+
/** Moves focus to the text input. */
|
|
180
|
+
focus(): void;
|
|
181
|
+
private tryAdd;
|
|
182
|
+
private commitInput;
|
|
183
|
+
private removeAt;
|
|
184
|
+
/** @internal */
|
|
185
|
+
onInput(event: Event): void;
|
|
186
|
+
/** @internal */
|
|
187
|
+
onInputKeydown(event: KeyboardEvent): void;
|
|
188
|
+
/** @internal */
|
|
189
|
+
onChipKeydown(event: KeyboardEvent, index: number): void;
|
|
190
|
+
/** @internal */
|
|
191
|
+
onRemoveClick(index: number): void;
|
|
192
|
+
/** @internal */
|
|
193
|
+
onPaste(event: ClipboardEvent): void;
|
|
194
|
+
writeValue(value: T[] | null | undefined): void;
|
|
195
|
+
registerOnChange(fn: (value: T[]) => void): void;
|
|
196
|
+
registerOnTouched(fn: () => void): void;
|
|
197
|
+
setDisabledState(isDisabled: boolean): void;
|
|
198
|
+
/** @internal */
|
|
199
|
+
setDescribedByIds(ids: string[]): void;
|
|
200
|
+
/** @internal */
|
|
201
|
+
setLabelledByIds(ids: string[]): void;
|
|
202
|
+
/** @internal Clicking the form-field surface (outside the control) focuses the text input. Clicks inside the control are left alone so chip removal keeps its own focus restoration. */
|
|
203
|
+
onContainerClick(event: MouseEvent): void;
|
|
204
|
+
ngOnInit(): void;
|
|
205
|
+
private focusChip;
|
|
206
|
+
private focusInput;
|
|
207
|
+
private requestFocus;
|
|
208
|
+
private setInputText;
|
|
209
|
+
private announceMax;
|
|
210
|
+
private splitOnSeparators;
|
|
211
|
+
private hasAccessibleNameHint;
|
|
212
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TagsInputComponent<any>, never>;
|
|
213
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<TagsInputComponent<any>, "tw-tags-input", ["twTagsInput"], { "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disabledInput": { "alias": "disabled"; "required": false; "isSignal": true; }; "requiredInput": { "alias": "required"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "separatorKeys": { "alias": "separatorKeys"; "required": false; "isSignal": true; }; "addOnBlur": { "alias": "addOnBlur"; "required": false; "isSignal": true; }; "maxTags": { "alias": "maxTags"; "required": false; "isSignal": true; }; "allowDuplicates": { "alias": "allowDuplicates"; "required": false; "isSignal": true; }; "createTag": { "alias": "createTag"; "required": false; "isSignal": true; }; "tagLabel": { "alias": "tagLabel"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "idInput": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; "tagAdded": "tagAdded"; "tagRemoved": "tagRemoved"; }, never, never, true, never>;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { TagsInputComponent };
|
|
217
|
+
export type { TwTagAddedEvent, TwTagCompareFn, TwTagFactory, TwTagLabelFn, TwTagRemovedEvent };
|