@nexterajs/ui 0.0.1 → 0.1.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 +279 -34
- package/fesm2022/nexterajs-ui-charts.mjs +1096 -0
- package/fesm2022/nexterajs-ui-charts.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-core.mjs +835 -11
- package/fesm2022/nexterajs-ui-core.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-display.mjs +1142 -0
- package/fesm2022/nexterajs-ui-display.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-dropdowns.mjs +621 -69
- package/fesm2022/nexterajs-ui-dropdowns.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-file-uploader.mjs +576 -11
- package/fesm2022/nexterajs-ui-file-uploader.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-forms.mjs +2702 -452
- package/fesm2022/nexterajs-ui-forms.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-grid.mjs +2350 -336
- package/fesm2022/nexterajs-ui-grid.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-intl.mjs +117 -15
- package/fesm2022/nexterajs-ui-intl.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-navigation.mjs +1054 -0
- package/fesm2022/nexterajs-ui-navigation.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-notify.mjs +353 -0
- package/fesm2022/nexterajs-ui-notify.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-overlay.mjs +1671 -0
- package/fesm2022/nexterajs-ui-overlay.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-pivot.mjs +191 -136
- package/fesm2022/nexterajs-ui-pivot.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-shell.mjs +542 -0
- package/fesm2022/nexterajs-ui-shell.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-styling.mjs +568 -3
- package/fesm2022/nexterajs-ui-styling.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-tree-view.mjs +150 -18
- package/fesm2022/nexterajs-ui-tree-view.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-validation.mjs +283 -97
- package/fesm2022/nexterajs-ui-validation.mjs.map +1 -1
- package/fesm2022/nexterajs-ui.mjs +6 -0
- package/fesm2022/nexterajs-ui.mjs.map +1 -1
- package/package.json +37 -2
- package/styles/_dropdown.scss +150 -1
- package/styles/_editor.scss +75 -21
- package/styles/_icons.scss +92 -0
- package/styles/_mixins.scss +104 -1
- package/styles/_scrollbar.scss +134 -0
- package/styles/_status.scss +21 -0
- package/styles/_toast.scss +243 -0
- package/styles/_tokens.scss +467 -2
- package/styles/_widget.scss +14 -3
- package/styles/index.scss +10 -4
- package/types/nexterajs-ui-charts.d.ts +446 -0
- package/types/nexterajs-ui-core.d.ts +515 -30
- package/types/nexterajs-ui-display.d.ts +720 -0
- package/types/nexterajs-ui-dropdowns.d.ts +318 -57
- package/types/nexterajs-ui-file-uploader.d.ts +240 -8
- package/types/nexterajs-ui-forms.d.ts +772 -43
- package/types/nexterajs-ui-grid.d.ts +878 -135
- package/types/nexterajs-ui-intl.d.ts +39 -4
- package/types/nexterajs-ui-navigation.d.ts +531 -0
- package/types/nexterajs-ui-notify.d.ts +149 -0
- package/types/nexterajs-ui-overlay.d.ts +703 -0
- package/types/nexterajs-ui-pivot.d.ts +91 -70
- package/types/nexterajs-ui-shell.d.ts +294 -0
- package/types/nexterajs-ui-styling.d.ts +163 -3
- package/types/nexterajs-ui-tree-view.d.ts +56 -4
- package/types/nexterajs-ui-validation.d.ts +110 -22
- package/types/nexterajs-ui.d.ts +6 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnDestroy } from '@angular/core';
|
|
3
|
-
import { NxeValidationResult, NxeFormControlBase } from '@nexterajs/ui/core';
|
|
2
|
+
import { OnChanges, SimpleChanges, OnDestroy, InjectionToken, EnvironmentProviders, AfterContentInit, TemplateRef } from '@angular/core';
|
|
3
|
+
import { NxeValidationResult, NxeFormControlBase, NxeMessageKey, NxeExpr } from '@nexterajs/ui/core';
|
|
4
4
|
import { DateTime } from 'luxon';
|
|
5
5
|
import { NxeCalendarZoom, NxePeriodCell } from '@nexterajs/ui/intl';
|
|
6
6
|
|
|
7
7
|
/** DevExtreme button `type` (style intent), as used in this codebase. */
|
|
8
8
|
type NxeButtonType = 'normal' | 'default' | 'success' | 'danger';
|
|
9
|
+
/** Fill treatment: dx `stylingMode`. `contained` (filled) is the default and the legacy look. */
|
|
10
|
+
type NxeButtonStylingMode = 'contained' | 'outlined' | 'text';
|
|
11
|
+
/** Button scale. `md` is the legacy size and adds no class. */
|
|
12
|
+
type NxeButtonSize = 'sm' | 'md' | 'lg';
|
|
9
13
|
/**
|
|
10
14
|
* The `validationGroup` object carried on a {@link NxeButtonClickEvent}, mirroring the
|
|
11
15
|
* DevExtreme button-click `event.validationGroup`. Its `validate()` runs every member of the
|
|
@@ -30,24 +34,40 @@ interface NxeButtonClickEvent {
|
|
|
30
34
|
/**
|
|
31
35
|
* `nxe-button` — drop-in replacement for DevExtreme `dx-button`.
|
|
32
36
|
*
|
|
33
|
-
* The host element IS the button (mirrors DevExtreme's `
|
|
34
|
-
* styling classes and contains a single `.
|
|
35
|
-
* `.nxe-btn*` / `.
|
|
36
|
-
* shared `buttonLoading` directive working, which swaps `.
|
|
37
|
-
* spinner (`getElementsByClassName('
|
|
37
|
+
* The host element IS the button (mirrors DevExtreme's `nxe-button` DOM: the host carries the
|
|
38
|
+
* styling classes and contains a single `.nxe-button-content` child). This keeps every existing
|
|
39
|
+
* `.nxe-btn*` / `.nxe-button-content` global rule matching verbatim, and — critically — keeps the
|
|
40
|
+
* shared `buttonLoading` directive working, which swaps `.nxe-button-content` innerHTML for a
|
|
41
|
+
* spinner (`getElementsByClassName('nxe-button-content')[0]`).
|
|
38
42
|
*
|
|
39
43
|
* Content is projected (`<nxe-icon> + <span>`, the dominant pattern). The legacy `text`/`type`
|
|
40
|
-
* inputs render a `.
|
|
44
|
+
* inputs render a `.nxe-button-text` label for the ~25 attribute-styled buttons.
|
|
45
|
+
*
|
|
46
|
+
* `stylingMode`, `size`, `loading` and `block` are additive: with none of them set the host renders
|
|
47
|
+
* exactly as before. An icon can be projected into the leading slot as
|
|
48
|
+
* `<svg nxeButtonIcon ...>` (or `[nxeIcon]`), placed before the label.
|
|
41
49
|
*
|
|
42
50
|
* `onClick` emits {@link NxeButtonClickEvent}; native `(click)` also fires (27 sites bind it).
|
|
43
51
|
*/
|
|
44
52
|
declare class NxeButtonComponent {
|
|
45
53
|
private readonly registry;
|
|
54
|
+
private readonly groupScope;
|
|
46
55
|
private readonly elementRef;
|
|
47
|
-
/** Legacy `text` label (rendered as `.
|
|
48
|
-
readonly text: _angular_core.InputSignal<string>;
|
|
56
|
+
/** Legacy `text` label (rendered as `.nxe-button-text` when set, no projected content). */
|
|
57
|
+
readonly text: _angular_core.InputSignal<string | undefined>;
|
|
49
58
|
/** Style intent (`default`=blue, `success`=green, `danger`=red, `normal`=white). */
|
|
50
59
|
readonly type: _angular_core.InputSignal<NxeButtonType>;
|
|
60
|
+
/** Fill treatment: `contained` (default), `outlined` (transparent with a coloured border) or `text` (no border). */
|
|
61
|
+
readonly stylingMode: _angular_core.InputSignal<NxeButtonStylingMode>;
|
|
62
|
+
/** Scale: `sm`, `md` (default, the legacy size) or `lg`. */
|
|
63
|
+
readonly size: _angular_core.InputSignal<NxeButtonSize>;
|
|
64
|
+
/**
|
|
65
|
+
* In-flight state: shows a spinner over the (hidden but still laid out, so the width holds)
|
|
66
|
+
* content, sets `aria-busy="true"` and swallows clicks and Enter/Space until it clears.
|
|
67
|
+
*/
|
|
68
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
69
|
+
/** Full-width button (`display: flex; width: 100%`). An explicit `width` still wins. */
|
|
70
|
+
readonly block: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
51
71
|
/** Disabled state (`[disabled]`); blocks `onClick` and dims the button. */
|
|
52
72
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
53
73
|
/** Named validation group resolved via {@link NxeValidationGroupRegistry} on click. */
|
|
@@ -55,23 +75,23 @@ declare class NxeButtonComponent {
|
|
|
55
75
|
/** DevExtreme parity input; only ever `false` in this codebase (suppresses tab focus). */
|
|
56
76
|
readonly focusStateEnabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
57
77
|
/**
|
|
58
|
-
* dx `icon` — renders `<i class="
|
|
59
|
-
* `.
|
|
78
|
+
* dx `icon` — renders `<i class="nxe-icon nxe-icon-NAME">` as the first child of
|
|
79
|
+
* `.nxe-button-content`, before any projected content. Projection is the dominant pattern
|
|
60
80
|
* here (a `mat-icon` plus a `span`), so the two must coexist rather than compete.
|
|
61
81
|
*/
|
|
62
|
-
readonly icon: _angular_core.InputSignal<string>;
|
|
82
|
+
readonly icon: _angular_core.InputSignal<string | undefined>;
|
|
63
83
|
/** dx `height` — a bare number (or numeric string) means px; anything else passes through. */
|
|
64
|
-
readonly height: _angular_core.InputSignal<string | number>;
|
|
84
|
+
readonly height: _angular_core.InputSignal<string | number | undefined>;
|
|
65
85
|
/** dx `width` — same coercion as {@link height}. */
|
|
66
|
-
readonly width: _angular_core.InputSignal<string | number>;
|
|
67
|
-
protected readonly heightStyle: _angular_core.Signal<string>;
|
|
68
|
-
protected readonly widthStyle: _angular_core.Signal<string>;
|
|
86
|
+
readonly width: _angular_core.InputSignal<string | number | undefined>;
|
|
87
|
+
protected readonly heightStyle: _angular_core.Signal<string | null>;
|
|
88
|
+
protected readonly widthStyle: _angular_core.Signal<string | null>;
|
|
69
89
|
/** DevExtreme-compatible click event. */
|
|
70
90
|
readonly onClick: _angular_core.OutputEmitterRef<NxeButtonClickEvent>;
|
|
71
91
|
protected handleKeydown(event: KeyboardEvent): void;
|
|
72
92
|
protected handleClick(event: Event): void;
|
|
73
93
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeButtonComponent, never>;
|
|
74
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeButtonComponent, "nxe-button", never, { "text": { "alias": "text"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "validationGroup": { "alias": "validationGroup"; "required": false; "isSignal": true; }; "focusStateEnabled": { "alias": "focusStateEnabled"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; }, never, ["*"], true, never>;
|
|
94
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeButtonComponent, "nxe-button", never, { "text": { "alias": "text"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "stylingMode": { "alias": "stylingMode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "block": { "alias": "block"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "validationGroup": { "alias": "validationGroup"; "required": false; "isSignal": true; }; "focusStateEnabled": { "alias": "focusStateEnabled"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; }, never, ["[nxeButtonIcon], [nxeIcon]", "*"], true, never>;
|
|
75
95
|
}
|
|
76
96
|
|
|
77
97
|
/** Text-box input mode (only `text`/`password` are used in this codebase). */
|
|
@@ -83,21 +103,54 @@ type NxeTextBoxMode = 'text' | 'password' | 'email' | 'tel' | 'search';
|
|
|
83
103
|
* `[(ngModel)]`, one-way `[value]`, and `[readOnly]`. Like DevExtreme's default
|
|
84
104
|
* (`valueChangeEvent='change'`), the value commits on **blur** — not on every keystroke.
|
|
85
105
|
*
|
|
106
|
+
* `showClearButton` (dx default `false`) adds dx's clear area after the input while the field
|
|
107
|
+
* holds text and is neither read-only nor disabled; it sets the value to `''`, dx's own empty
|
|
108
|
+
* value for a text box, and focuses the input.
|
|
109
|
+
*
|
|
86
110
|
* It provides {@link NXE_VALIDATION_TARGET} so a projected `nxe-validator` can read its value
|
|
87
111
|
* and push back the invalid message, which renders as the red `.nxe-invalid-message` bubble.
|
|
88
112
|
*/
|
|
89
113
|
declare class NxeTextBoxComponent extends NxeFormControlBase<string> {
|
|
90
114
|
readonly mode: _angular_core.InputSignal<NxeTextBoxMode>;
|
|
91
|
-
readonly placeholderInput: _angular_core.InputSignal<string>;
|
|
115
|
+
readonly placeholderInput: _angular_core.InputSignal<string | undefined>;
|
|
92
116
|
readonly placeholder: _angular_core.Signal<string>;
|
|
93
117
|
/** DevExtreme parity input; cosmetic, unused in behaviour. */
|
|
94
|
-
readonly hoverStateEnabledInput: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
118
|
+
readonly hoverStateEnabledInput: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
95
119
|
readonly hoverStateEnabled: _angular_core.Signal<boolean>;
|
|
120
|
+
/** dx `showClearButton` — off by default, as in dx; `NXE_DEFAULT_OPTIONS.textBox` can turn it on app-wide. */
|
|
121
|
+
readonly showClearButtonInput: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
122
|
+
readonly showClearButton: _angular_core.Signal<boolean>;
|
|
123
|
+
/**
|
|
124
|
+
* With `mode="password"`, an icon button after the field that shows the password as text and
|
|
125
|
+
* hides it again. Off by default; it has no effect in any other mode.
|
|
126
|
+
*/
|
|
127
|
+
readonly showPasswordToggle: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
128
|
+
protected readonly passwordToggleVisible: _angular_core.Signal<boolean>;
|
|
129
|
+
/** Whether the password is showing as text right now; hidden again whenever the toggle goes away. */
|
|
130
|
+
protected readonly passwordRevealed: _angular_core.WritableSignal<boolean>;
|
|
131
|
+
protected readonly passwordToggleLabel: _angular_core.Signal<string>;
|
|
96
132
|
readonly focused: _angular_core.WritableSignal<boolean>;
|
|
97
133
|
readonly displayValue: _angular_core.Signal<string>;
|
|
134
|
+
private readonly fieldRef;
|
|
135
|
+
/**
|
|
136
|
+
* The text in the field right now, typed or not. dx shows the clear button by the field's
|
|
137
|
+
* emptiness (`.dx-texteditor-empty`), which follows every keystroke, not the committed value.
|
|
138
|
+
*/
|
|
139
|
+
private readonly fieldText;
|
|
140
|
+
protected readonly clearButtonVisible: _angular_core.Signal<boolean>;
|
|
141
|
+
/** dx `valueChangeEvent: 'input'` — the search-as-you-type case. */
|
|
142
|
+
protected onTypedInput(event: Event): void;
|
|
143
|
+
/**
|
|
144
|
+
* dx `_clearValueHandler`: value back to `''`, then focus on the input. The field is emptied by
|
|
145
|
+
* hand as well — typed-but-uncommitted text over an already-empty value would otherwise survive,
|
|
146
|
+
* because the `[value]` binding has not changed.
|
|
147
|
+
*/
|
|
148
|
+
protected onClear(event: Event): void;
|
|
149
|
+
protected onTypedKeyup(event: Event): void;
|
|
150
|
+
protected commitPending(event: Event | null): void;
|
|
98
151
|
protected onBlur(event: Event): void;
|
|
99
152
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeTextBoxComponent, never>;
|
|
100
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeTextBoxComponent, "nxe-text-box", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "placeholderInput": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hoverStateEnabledInput": { "alias": "hoverStateEnabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
153
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeTextBoxComponent, "nxe-text-box", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "placeholderInput": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hoverStateEnabledInput": { "alias": "hoverStateEnabled"; "required": false; "isSignal": true; }; "showClearButtonInput": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "showPasswordToggle": { "alias": "showPasswordToggle"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
101
154
|
}
|
|
102
155
|
|
|
103
156
|
/**
|
|
@@ -108,30 +161,80 @@ declare class NxeTextBoxComponent extends NxeFormControlBase<string> {
|
|
|
108
161
|
* {@link NXE_VALIDATION_TARGET}.
|
|
109
162
|
*/
|
|
110
163
|
declare class NxeTextAreaComponent extends NxeFormControlBase<string> {
|
|
111
|
-
readonly placeholderInput: _angular_core.InputSignal<string>;
|
|
164
|
+
readonly placeholderInput: _angular_core.InputSignal<string | undefined>;
|
|
112
165
|
readonly placeholder: _angular_core.Signal<string>;
|
|
113
166
|
/** Fixed height in px (DevExtreme `[height]`); unset = auto. */
|
|
114
|
-
readonly heightInput: _angular_core.InputSignal<number>;
|
|
167
|
+
readonly heightInput: _angular_core.InputSignal<number | undefined>;
|
|
115
168
|
readonly height: _angular_core.Signal<string | number>;
|
|
169
|
+
/**
|
|
170
|
+
* dx `maxLength`: the most characters the field takes. Sets the native `maxlength`, so typing
|
|
171
|
+
* and pasting stop at the limit, and shows a live "12/200" count under the text. Unset (the
|
|
172
|
+
* default), there is no limit and no counter.
|
|
173
|
+
*/
|
|
174
|
+
readonly maxLength: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
175
|
+
/**
|
|
176
|
+
* Grow with the text between {@link minRows} and {@link maxRows}, scrolling past the maximum.
|
|
177
|
+
* The fixed `height` is ignored while this is on. Off by default.
|
|
178
|
+
*/
|
|
179
|
+
readonly autoGrow: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
180
|
+
/** Rows the field never shrinks below while `autoGrow` is on. */
|
|
181
|
+
readonly minRows: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
182
|
+
/** Rows after which an auto-growing field scrolls instead of growing; `0` means never. */
|
|
183
|
+
readonly maxRows: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
116
184
|
readonly focused: _angular_core.WritableSignal<boolean>;
|
|
117
185
|
readonly displayValue: _angular_core.Signal<string>;
|
|
186
|
+
/** The text in the field right now, typed or not: the counter and the height follow every keystroke. */
|
|
187
|
+
protected readonly fieldText: _angular_core.WritableSignal<string>;
|
|
188
|
+
protected readonly remaining: _angular_core.Signal<number>;
|
|
189
|
+
/** Close enough to the limit to say so: the last 10 characters, or 10% of a long limit. */
|
|
190
|
+
protected readonly nearLimit: _angular_core.Signal<boolean>;
|
|
191
|
+
/** Spoken by the polite status; empty (so silent) until {@link nearLimit}. */
|
|
192
|
+
protected readonly limitStatus: _angular_core.Signal<string>;
|
|
193
|
+
private readonly growState;
|
|
194
|
+
constructor();
|
|
195
|
+
/** dx `valueChangeEvent: 'input'` — the search-as-you-type case. */
|
|
196
|
+
protected onTypedInput(event: Event): void;
|
|
197
|
+
/** Size the textarea to its text: collapse it to measure, then clamp to the row limits. */
|
|
198
|
+
private resize;
|
|
199
|
+
protected onTypedKeyup(event: Event): void;
|
|
200
|
+
protected commitPending(event: Event | null): void;
|
|
201
|
+
/** Enter types a newline here and submits nothing; Ctrl/Cmd+Enter is the submit chord. */
|
|
202
|
+
protected commitsOnEnter(event: KeyboardEvent): boolean;
|
|
118
203
|
protected onBlur(event: Event): void;
|
|
119
204
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeTextAreaComponent, never>;
|
|
120
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeTextAreaComponent, "nxe-text-area", never, { "placeholderInput": { "alias": "placeholder"; "required": false; "isSignal": true; }; "heightInput": { "alias": "height"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
205
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeTextAreaComponent, "nxe-text-area", never, { "placeholderInput": { "alias": "placeholder"; "required": false; "isSignal": true; }; "heightInput": { "alias": "height"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "autoGrow": { "alias": "autoGrow"; "required": false; "isSignal": true; }; "minRows": { "alias": "minRows"; "required": false; "isSignal": true; }; "maxRows": { "alias": "maxRows"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
121
206
|
}
|
|
122
207
|
|
|
123
208
|
/**
|
|
124
209
|
* `nxe-check-box` — drop-in replacement for DevExtreme `dx-check-box`.
|
|
125
210
|
*
|
|
126
|
-
* A
|
|
127
|
-
*
|
|
128
|
-
* `
|
|
129
|
-
*
|
|
211
|
+
* A signal-CVA editor (extends {@link NxeFormControlBase}) over `true` / `false` / `null`. As in
|
|
212
|
+
* dx, a `null` value is the indeterminate state: the box shows a 12px square and reports
|
|
213
|
+
* `aria-checked="mixed"`. That is what a `new FormControl()` (or a `reset()`) looks like, and what
|
|
214
|
+
* `[value]="null"` looks like; an unbound box starts unchecked, like dx's default `false`. A click
|
|
215
|
+
* or Space always lands on `true` or `false` — there is no `enableThreeStateBehavior` cycling back
|
|
216
|
+
* to `null`.
|
|
217
|
+
*
|
|
218
|
+
* Supports `formControlName`/`[(ngModel)]`/`[(value)]`/`[value]`, `[readOnly]`, `[disabled]`, an
|
|
219
|
+
* inline `text` label, `(onValueChanged)` (`{value}`) and `(valueChange)` (raw value). A read-only
|
|
220
|
+
* box stays focusable (tabindex 0) and still shows hover and focus, as in dx; it just never
|
|
221
|
+
* toggles. Provides {@link NXE_VALIDATION_TARGET} for a projected `nxe-validator` (a `required`
|
|
130
222
|
* rule is invalid while unchecked, matching DevExtreme's RequiredRule treating `false` as empty).
|
|
131
223
|
*/
|
|
132
|
-
declare class NxeCheckBoxComponent extends NxeFormControlBase<boolean> {
|
|
224
|
+
declare class NxeCheckBoxComponent extends NxeFormControlBase<boolean> implements OnChanges {
|
|
133
225
|
/** Inline label rendered next to the box. */
|
|
134
|
-
readonly text: _angular_core.InputSignal<string>;
|
|
226
|
+
readonly text: _angular_core.InputSignal<string | undefined>;
|
|
227
|
+
/**
|
|
228
|
+
* Whether a value has been handed in at all — by the forms API or a `[value]` binding.
|
|
229
|
+
*
|
|
230
|
+
* The base class starts `value` at `null`, which is also the indeterminate value, so `null`
|
|
231
|
+
* alone cannot tell "given null" from "given nothing". dx can: its unset value is `false`.
|
|
232
|
+
*/
|
|
233
|
+
private readonly valueProvided;
|
|
234
|
+
/** dx `.dx-checkbox-indeterminate`: the value was given, and it is `null`. */
|
|
235
|
+
readonly indeterminate: _angular_core.Signal<boolean>;
|
|
236
|
+
writeValue(value: boolean | null): void;
|
|
237
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
135
238
|
protected toggle(event: Event): void;
|
|
136
239
|
protected onSpace(event: Event): void;
|
|
137
240
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeCheckBoxComponent, never>;
|
|
@@ -148,21 +251,84 @@ declare class NxeCheckBoxComponent extends NxeFormControlBase<boolean> {
|
|
|
148
251
|
*
|
|
149
252
|
* Supports `formControlName`/`[(ngModel)]`/`[(value)]`/`[value]`, `[readOnly]`, `[min]`/`[max]`,
|
|
150
253
|
* `format` (string LDML pattern), `(valueChange)` (numeric), and a projected `nxe-validator`.
|
|
254
|
+
*
|
|
255
|
+
* Stepping: `step` (default 1) moves the value by exact decimal arithmetic (`0.1` steps never show
|
|
256
|
+
* `0.30000000000000004`) on ArrowUp/ArrowDown (`largeStep`, default 10 steps, on PageUp/PageDown),
|
|
257
|
+
* and on the optional spin buttons (`showSpinButtons`; held buttons repeat unless
|
|
258
|
+
* `[holdToRepeat]="false"`). Results are clamped to `[min, max]` and rounded to the format precision.
|
|
259
|
+
* The input carries `role="spinbutton"` with `aria-valuenow`/`aria-valuemin`/`aria-valuemax`.
|
|
260
|
+
*
|
|
261
|
+
* `currency` (an ISO 4217 code) shows `IDR 1.351.000` / `USD 1,234.50` (separators from
|
|
262
|
+
* `NXE_NUMBER_SEPARATORS`, so it follows the locale) and takes the currency's minor units as the
|
|
263
|
+
* precision. An explicit `format` still sets the number pattern; `currencyDecimals` overrides the
|
|
264
|
+
* minor units (reference data). Focused, the field holds the bare editable number.
|
|
265
|
+
*
|
|
266
|
+
* `showClearButton` (dx default `false`) adds dx's clear area after the input while the field
|
|
267
|
+
* holds text and is neither read-only nor disabled; it sets the value to `null`, as dx's
|
|
268
|
+
* `clear()` does for a number box, and focuses the input.
|
|
151
269
|
*/
|
|
152
270
|
declare class NxeNumberBoxComponent extends NxeFormControlBase<number> {
|
|
153
271
|
/** LDML format pattern (e.g. `#,##0.00`); empty = raw number. */
|
|
154
|
-
readonly formatInput: _angular_core.InputSignal<string>;
|
|
272
|
+
readonly formatInput: _angular_core.InputSignal<string | undefined>;
|
|
155
273
|
readonly format: _angular_core.Signal<string>;
|
|
156
|
-
readonly min: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
157
|
-
readonly max: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
274
|
+
readonly min: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
275
|
+
readonly max: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
276
|
+
/** dx `showClearButton` — off by default, as in dx; `NXE_DEFAULT_OPTIONS.numberBox` can turn it on app-wide. */
|
|
277
|
+
readonly showClearButtonInput: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
278
|
+
readonly showClearButton: _angular_core.Signal<boolean>;
|
|
279
|
+
/** Amount of one step (ArrowUp/ArrowDown, spin buttons). Default 1; zero, negative or invalid means 1. */
|
|
280
|
+
readonly step: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
281
|
+
/** PageUp/PageDown amount. Default 10 steps. */
|
|
282
|
+
readonly largeStep: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
283
|
+
/** Show the increase/decrease buttons after the input. Default off, as in dx. */
|
|
284
|
+
readonly showSpinButtons: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
285
|
+
/** Keep stepping while a spin button is held down. Default on. */
|
|
286
|
+
readonly holdToRepeat: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
287
|
+
/** ISO 4217 code: shows `CODE amount` and takes the currency's minor units as precision. */
|
|
288
|
+
readonly currency: _angular_core.InputSignal<string | null | undefined>;
|
|
289
|
+
/** The currency's minor units from reference data; overrides the built-in table. */
|
|
290
|
+
readonly currencyDecimals: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
158
291
|
readonly focused: _angular_core.WritableSignal<boolean>;
|
|
292
|
+
private readonly currencyCode;
|
|
293
|
+
/** The explicit `format` input only, so a currency does not inherit the app-wide default pattern. */
|
|
294
|
+
private readonly explicitFormat;
|
|
159
295
|
private readonly parsedFormat;
|
|
296
|
+
private readonly stepAmount;
|
|
297
|
+
private readonly largeStepAmount;
|
|
298
|
+
private readonly fieldRef;
|
|
160
299
|
/** Locale characters, configured once by the application. Defaults to en-US. */
|
|
161
300
|
private readonly separators;
|
|
301
|
+
/** The blurred, formatted text of the committed value. */
|
|
302
|
+
private readonly formattedValue;
|
|
303
|
+
/** `aria-valuetext`: the formatted amount, only when a format or currency makes it differ from the number. */
|
|
304
|
+
protected readonly valueText: _angular_core.Signal<string | null>;
|
|
162
305
|
readonly displayValue: _angular_core.Signal<string>;
|
|
306
|
+
/** The text in the field right now; dx shows the clear button by the field's emptiness. */
|
|
307
|
+
private readonly fieldText;
|
|
308
|
+
protected readonly clearButtonVisible: _angular_core.Signal<boolean>;
|
|
309
|
+
protected readonly incrementDisabled: _angular_core.Signal<boolean>;
|
|
310
|
+
protected readonly decrementDisabled: _angular_core.Signal<boolean>;
|
|
311
|
+
private spinDelay;
|
|
312
|
+
private spinTimer;
|
|
313
|
+
constructor();
|
|
314
|
+
protected onKeyDownStep(event: KeyboardEvent): void;
|
|
315
|
+
protected onSpinPointerDown(event: PointerEvent, direction: 1 | -1): void;
|
|
316
|
+
/** Keyboard and assistive-technology activation (`detail` 0); pointer presses stepped on pointerdown. */
|
|
317
|
+
protected onSpinClick(event: MouseEvent, direction: 1 | -1): void;
|
|
318
|
+
protected stopSpin(): void;
|
|
319
|
+
/** Step the value; returns false when it did not move (a bound, or nothing to do). */
|
|
320
|
+
private stepBy;
|
|
321
|
+
protected onFieldInput(event: Event): void;
|
|
322
|
+
/**
|
|
323
|
+
* dx `_clearValueHandler`: value to `null`, then focus on the input. The field is emptied by hand
|
|
324
|
+
* too, for typed-but-uncommitted text over a value that was already `null`.
|
|
325
|
+
*/
|
|
326
|
+
protected onClear(event: Event): void;
|
|
327
|
+
protected commitPending(event: Event | null): void;
|
|
163
328
|
protected onBlur(event: Event): void;
|
|
329
|
+
private commitText;
|
|
164
330
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeNumberBoxComponent, never>;
|
|
165
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeNumberBoxComponent, "nxe-number-box", never, { "formatInput": { "alias": "format"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
331
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeNumberBoxComponent, "nxe-number-box", never, { "formatInput": { "alias": "format"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "showClearButtonInput": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "largeStep": { "alias": "largeStep"; "required": false; "isSignal": true; }; "showSpinButtons": { "alias": "showSpinButtons"; "required": false; "isSignal": true; }; "holdToRepeat": { "alias": "holdToRepeat"; "required": false; "isSignal": true; }; "currency": { "alias": "currency"; "required": false; "isSignal": true; }; "currencyDecimals": { "alias": "currencyDecimals"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
166
332
|
}
|
|
167
333
|
|
|
168
334
|
/** DevExtreme date-box `type`. */
|
|
@@ -175,6 +341,15 @@ type NxeDateBoxType = 'date' | 'datetime' | 'time';
|
|
|
175
341
|
* typeable (parsed on blur per `displayFormat`) and opens a CDK-overlay calendar from the icon
|
|
176
342
|
* button. Built on Luxon. Default `displayFormat` is `dd-MMM-yyyy`. Hosts a projected
|
|
177
343
|
* `nxe-validator` via {@link NXE_VALIDATION_TARGET}.
|
|
344
|
+
*
|
|
345
|
+
* `showClearButton` (dx default `false`) adds dx's clear area between the input and the calendar
|
|
346
|
+
* button while the field holds text and is neither read-only nor disabled; it sets the value to
|
|
347
|
+
* `null` and focuses the input.
|
|
348
|
+
*
|
|
349
|
+
* The button and calendar glyphs are drawn in an 18-unit viewBox (1 unit = 1px) to the ink measured
|
|
350
|
+
* off dx's `event` (`date`), `eventall` (`datetime`) and `clock` (`time`) glyphs and its chevrons,
|
|
351
|
+
* each laid out from those metrics in rects, stroked rects and circles, and straight-edged polygons;
|
|
352
|
+
* the templates state each construction.
|
|
178
353
|
*/
|
|
179
354
|
declare class NxeDateBoxComponent extends NxeFormControlBase<string> implements OnDestroy {
|
|
180
355
|
private readonly overlay;
|
|
@@ -182,23 +357,31 @@ declare class NxeDateBoxComponent extends NxeFormControlBase<string> implements
|
|
|
182
357
|
private readonly calendarTemplate;
|
|
183
358
|
private readonly fieldRef;
|
|
184
359
|
readonly type: _angular_core.InputSignal<NxeDateBoxType>;
|
|
185
|
-
readonly displayFormat: _angular_core.InputSignal<string>;
|
|
186
|
-
readonly placeholder: _angular_core.InputSignal<string>;
|
|
360
|
+
readonly displayFormat: _angular_core.InputSignal<string | undefined>;
|
|
361
|
+
readonly placeholder: _angular_core.InputSignal<string | undefined>;
|
|
187
362
|
/** DevExtreme `[min]`/`[max]` bounds: calendar days outside are disabled, typed values clamp. */
|
|
188
|
-
readonly min: _angular_core.InputSignal<string | Date>;
|
|
189
|
-
readonly max: _angular_core.InputSignal<string | Date>;
|
|
363
|
+
readonly min: _angular_core.InputSignal<string | Date | null>;
|
|
364
|
+
readonly max: _angular_core.InputSignal<string | Date | null>;
|
|
365
|
+
/** dx `showClearButton` — off by default, as in dx; `NXE_DEFAULT_OPTIONS.dateBox` can turn it on app-wide. */
|
|
366
|
+
readonly showClearButtonInput: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
367
|
+
readonly showClearButton: _angular_core.Signal<boolean>;
|
|
190
368
|
readonly focused: _angular_core.WritableSignal<boolean>;
|
|
191
369
|
readonly opened: _angular_core.WritableSignal<boolean>;
|
|
192
370
|
readonly viewMonth: _angular_core.WritableSignal<DateTime<boolean>>;
|
|
193
371
|
/** Calendar zoom level; caption clicks zoom out, cell picks zoom back in (dx-calendar parity). */
|
|
194
372
|
readonly zoomLevel: _angular_core.WritableSignal<NxeCalendarZoom>;
|
|
195
|
-
|
|
373
|
+
/** Short weekday names for the active locale, Sunday first (the grid below starts on Sunday). */
|
|
374
|
+
readonly weekdays: _angular_core.Signal<string[]>;
|
|
196
375
|
/** The format actually used, from `displayFormat` or the default for this `type`. */
|
|
197
376
|
readonly effectiveDisplayFormat: _angular_core.Signal<string>;
|
|
198
377
|
/** dx's default placeholder is '', but orbit's global default is the format itself. */
|
|
199
378
|
readonly effectivePlaceholder: _angular_core.Signal<string>;
|
|
379
|
+
/** The value as a Luxon date in the active locale, so `MMM` and `MMMM` follow the language. */
|
|
200
380
|
private readonly selected;
|
|
201
381
|
readonly displayValue: _angular_core.Signal<string>;
|
|
382
|
+
/** The text in the field right now; dx shows the clear button by the field's emptiness. */
|
|
383
|
+
private readonly fieldText;
|
|
384
|
+
protected readonly clearButtonVisible: _angular_core.Signal<boolean>;
|
|
202
385
|
readonly weeks: _angular_core.Signal<DateTime<boolean>[][]>;
|
|
203
386
|
/** Two-digit hour/minute for the popup's time strip; blank when nothing is selected. */
|
|
204
387
|
readonly hourText: _angular_core.Signal<string>;
|
|
@@ -231,6 +414,13 @@ declare class NxeDateBoxComponent extends NxeFormControlBase<string> implements
|
|
|
231
414
|
disabled: boolean;
|
|
232
415
|
}): void;
|
|
233
416
|
protected onButtonMousedown(event: Event): void;
|
|
417
|
+
protected onFieldInput(event: Event): void;
|
|
418
|
+
/**
|
|
419
|
+
* dx `_clearValueHandler`: value to `null` (dx's `clear()` for a date box), then focus on the
|
|
420
|
+
* input. `syncField` repaints the field, so typed-but-uncommitted text over a value that was
|
|
421
|
+
* already `null` goes too.
|
|
422
|
+
*/
|
|
423
|
+
protected onClear(event: Event): void;
|
|
234
424
|
protected onFocus(event: Event): void;
|
|
235
425
|
/**
|
|
236
426
|
* Commit what the user TYPED — and nothing when they typed nothing.
|
|
@@ -247,6 +437,9 @@ declare class NxeDateBoxComponent extends NxeFormControlBase<string> implements
|
|
|
247
437
|
* re-render on its own and the unparseable text would sit there looking accepted.
|
|
248
438
|
*/
|
|
249
439
|
protected onBlur(event: Event): void;
|
|
440
|
+
/** Enter commits what was typed, before a surrounding form submits; nothing typed means nothing to do. */
|
|
441
|
+
protected commitPending(event: Event | null): void;
|
|
442
|
+
private commitTypedText;
|
|
250
443
|
/**
|
|
251
444
|
* Repaint the field from the committed value and re-baseline {@link textAtFocus}.
|
|
252
445
|
*
|
|
@@ -269,13 +462,229 @@ declare class NxeDateBoxComponent extends NxeFormControlBase<string> implements
|
|
|
269
462
|
protected close(): void;
|
|
270
463
|
ngOnDestroy(): void;
|
|
271
464
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeDateBoxComponent, never>;
|
|
272
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeDateBoxComponent, "nxe-date-box", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "displayFormat": { "alias": "displayFormat"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
465
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeDateBoxComponent, "nxe-date-box", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "displayFormat": { "alias": "displayFormat"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "showClearButtonInput": { "alias": "showClearButton"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* The value of `nxe-date-range-box`. Each end is a string in the box's `valueFormat`
|
|
470
|
+
* (`yyyy-MM-dd` unless stated), or `null` while that end is empty. A box with neither end set holds
|
|
471
|
+
* `null`, not an object of two nulls, so `Validators.required` means what it says.
|
|
472
|
+
*/
|
|
473
|
+
interface NxeDateRange {
|
|
474
|
+
start: string | null;
|
|
475
|
+
end: string | null;
|
|
476
|
+
}
|
|
477
|
+
/** A date a preset may return: a string in any format `nxe-date-box` accepts, a `Date` or a Luxon `DateTime`. */
|
|
478
|
+
type NxeDateRangeBound = string | Date | DateTime;
|
|
479
|
+
/** What a preset's `range` returns. The box serializes it in its own `valueFormat`. */
|
|
480
|
+
interface NxeDateRangeBounds {
|
|
481
|
+
start: NxeDateRangeBound | null;
|
|
482
|
+
end: NxeDateRangeBound | null;
|
|
483
|
+
}
|
|
484
|
+
/** One entry of the box's quick-range list. */
|
|
485
|
+
interface NxeDateRangePreset {
|
|
486
|
+
/** The text of the entry. Wins over `labelKey`. */
|
|
487
|
+
label?: string;
|
|
488
|
+
/** A message key for the entry, so the label follows the active language. */
|
|
489
|
+
labelKey?: NxeMessageKey;
|
|
490
|
+
/**
|
|
491
|
+
* The range, computed when the entry is chosen. `now` is the box's clock (see
|
|
492
|
+
* {@link NXE_DATE_RANGE_NOW}), so a preset needs no clock of its own and a test can fix it.
|
|
493
|
+
*/
|
|
494
|
+
range(now: DateTime): NxeDateRangeBounds;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* The clock the box reads for "today": the highlighted day, where the popup opens and what the
|
|
498
|
+
* built-in presets count back from. Provide a fixed one in a test:
|
|
499
|
+
*
|
|
500
|
+
* ```ts
|
|
501
|
+
* { provide: NXE_DATE_RANGE_NOW, useValue: () => DateTime.fromISO('2026-10-07T09:30:00') }
|
|
502
|
+
* ```
|
|
503
|
+
*/
|
|
504
|
+
declare const NXE_DATE_RANGE_NOW: InjectionToken<() => DateTime>;
|
|
505
|
+
/** Default `displayFormat`: `1 Okt 2026` in Indonesian, `1 Oct 2026` in English. */
|
|
506
|
+
declare const NXE_DATE_RANGE_DISPLAY_FORMAT = "d MMM yyyy";
|
|
507
|
+
/** Default `valueFormat`: date-only. */
|
|
508
|
+
declare const NXE_DATE_RANGE_VALUE_FORMAT = "yyyy-MM-dd";
|
|
509
|
+
/**
|
|
510
|
+
* The built-in presets. Each call returns a fresh entry whose label comes from the message bundle
|
|
511
|
+
* and whose range counts from the box's clock. Weeks are not offered: the first day of the week is
|
|
512
|
+
* a locale question this library does not decide.
|
|
513
|
+
*/
|
|
514
|
+
declare const nxeDateRangePresets: {
|
|
515
|
+
today: () => NxeDateRangePreset;
|
|
516
|
+
yesterday: () => NxeDateRangePreset;
|
|
517
|
+
/** Today and the six days before it. */
|
|
518
|
+
last7Days: () => NxeDateRangePreset;
|
|
519
|
+
/** Today and the 29 days before it. */
|
|
520
|
+
last30Days: () => NxeDateRangePreset;
|
|
521
|
+
/** The first of the month to its last day (not to today). */
|
|
522
|
+
thisMonth: () => NxeDateRangePreset;
|
|
523
|
+
lastMonth: () => NxeDateRangePreset;
|
|
524
|
+
/** 1 January to 31 December. */
|
|
525
|
+
thisYear: () => NxeDateRangePreset;
|
|
526
|
+
/** All seven, in the order above. */
|
|
527
|
+
all: () => NxeDateRangePreset[];
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
/** One day in a month grid, with everything the template needs to draw and label it. */
|
|
531
|
+
interface RangeDayCell {
|
|
532
|
+
readonly date: DateTime;
|
|
533
|
+
/** `yyyy-MM-dd`: the cell's `data-date`, and a string that sorts as a date does. */
|
|
534
|
+
readonly key: string;
|
|
535
|
+
readonly day: number;
|
|
536
|
+
readonly label: string;
|
|
537
|
+
readonly disabled: boolean;
|
|
538
|
+
readonly today: boolean;
|
|
539
|
+
readonly start: boolean;
|
|
540
|
+
readonly end: boolean;
|
|
541
|
+
readonly inRange: boolean;
|
|
542
|
+
/** Drawn from the hover or keyboard preview, not from the committed value. */
|
|
543
|
+
readonly preview: boolean;
|
|
544
|
+
readonly tabbable: boolean;
|
|
545
|
+
}
|
|
546
|
+
interface RangeMonthView {
|
|
547
|
+
readonly key: string;
|
|
548
|
+
readonly caption: string;
|
|
549
|
+
/** Weeks of the month; `null` is a day of a neighbouring month, drawn as a gap. */
|
|
550
|
+
readonly weeks: readonly (readonly (RangeDayCell | null)[])[];
|
|
551
|
+
}
|
|
552
|
+
interface RangePresetItem {
|
|
553
|
+
readonly index: number;
|
|
554
|
+
readonly label: string;
|
|
555
|
+
readonly active: boolean;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* `nxe-date-range-box` picks a start and an end date in one field.
|
|
559
|
+
*
|
|
560
|
+
* ```html
|
|
561
|
+
* <nxe-form-field label="Tanggal PO">
|
|
562
|
+
* <nxe-date-range-box formControlName="poDate" [presets]="presets" min="2020-01-01" />
|
|
563
|
+
* </nxe-form-field>
|
|
564
|
+
* ```
|
|
565
|
+
*
|
|
566
|
+
* The value is `{ start, end }`, each a string in `valueFormat` (`yyyy-MM-dd` by default; with a time
|
|
567
|
+
* format the start is the first second of its day and the end the last), `null` while that end is
|
|
568
|
+
* empty, and `null` as a whole when both are. The field shows `1 Okt 2026 - 31 Okt 2026` and opens
|
|
569
|
+
* a popup: two months side by side (one under 720px), a quick-range list, and a typed input for each
|
|
570
|
+
* end. The first click picks the start, the second the end; the days in between preview under the
|
|
571
|
+
* pointer, and a second click before the first swaps the two.
|
|
572
|
+
*
|
|
573
|
+
* Month and weekday names follow the active language of `NxeMessageService`. The field is a
|
|
574
|
+
* read-only combobox, so a label, `aria-invalid` and `aria-describedby` from `nxe-form-field` reach
|
|
575
|
+
* it; the popup is a dialog with the days in an ARIA grid (arrows, Home and End by week, PageUp and
|
|
576
|
+
* PageDown by month, Enter or Space to pick, Esc closes and returns focus to the field).
|
|
577
|
+
*/
|
|
578
|
+
declare class NxeDateRangeBoxComponent extends NxeFormControlBase<NxeDateRange> implements OnDestroy {
|
|
579
|
+
private readonly overlay;
|
|
580
|
+
private readonly viewContainerRef;
|
|
581
|
+
private readonly injector;
|
|
582
|
+
private readonly clock;
|
|
583
|
+
private readonly breakpoints;
|
|
584
|
+
private readonly popupTemplate;
|
|
585
|
+
private readonly fieldRef;
|
|
586
|
+
/** How the dates read in the field and in the typed inputs: a Luxon format. */
|
|
587
|
+
readonly displayFormat: _angular_core.InputSignal<string>;
|
|
588
|
+
/** How each end is written to the value. Date-only unless it carries time tokens. */
|
|
589
|
+
readonly valueFormat: _angular_core.InputSignal<string>;
|
|
590
|
+
/** Days before this are disabled, and a typed or preset date before it moves to it. */
|
|
591
|
+
readonly min: _angular_core.InputSignal<string | Date | null>;
|
|
592
|
+
/** Days after this are disabled, and a typed or preset date after it moves to it. */
|
|
593
|
+
readonly max: _angular_core.InputSignal<string | Date | null>;
|
|
594
|
+
/** The quick-range list. Empty draws none. See `nxeDateRangePresets` for the built-in ones. */
|
|
595
|
+
readonly presets: _angular_core.InputSignal<readonly NxeDateRangePreset[]>;
|
|
596
|
+
/** Shown in the field and the start input while the start is empty. Defaults to the message bundle's. */
|
|
597
|
+
readonly startPlaceholder: _angular_core.InputSignal<string | undefined>;
|
|
598
|
+
/** Shown in the field and the end input while the end is empty. Defaults to the message bundle's. */
|
|
599
|
+
readonly endPlaceholder: _angular_core.InputSignal<string | undefined>;
|
|
600
|
+
/** The clear area in the field. On by default: a filter is cleared more often than a form field. */
|
|
601
|
+
readonly showClearButton: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
602
|
+
protected readonly focused: _angular_core.WritableSignal<boolean>;
|
|
603
|
+
/** Whether the popup is showing. */
|
|
604
|
+
readonly opened: _angular_core.WritableSignal<boolean>;
|
|
605
|
+
private readonly uid;
|
|
606
|
+
protected readonly popupId: string;
|
|
607
|
+
protected readonly isNarrow: _angular_core.Signal<boolean>;
|
|
608
|
+
protected readonly monthsShown: _angular_core.Signal<1 | 2>;
|
|
609
|
+
private readonly locale;
|
|
610
|
+
private readonly minDate;
|
|
611
|
+
private readonly maxDate;
|
|
612
|
+
/** The committed value as days in the active locale. */
|
|
613
|
+
protected readonly range: _angular_core.Signal<{
|
|
614
|
+
start: DateTime<boolean> | null;
|
|
615
|
+
end: DateTime<boolean> | null;
|
|
616
|
+
}>;
|
|
617
|
+
protected readonly startText: _angular_core.Signal<string>;
|
|
618
|
+
protected readonly endText: _angular_core.Signal<string>;
|
|
619
|
+
protected readonly startHint: _angular_core.Signal<string>;
|
|
620
|
+
protected readonly endHint: _angular_core.Signal<string>;
|
|
621
|
+
/** `1 Okt 2026 - 31 Okt 2026`; an empty end leaves the dash hanging so a half-set range reads as one. */
|
|
622
|
+
protected readonly displayValue: _angular_core.Signal<string>;
|
|
623
|
+
protected readonly fieldPlaceholder: _angular_core.Signal<string>;
|
|
624
|
+
protected readonly clearButtonVisible: _angular_core.Signal<boolean>;
|
|
625
|
+
/** The first click of a range in progress; null when none is. */
|
|
626
|
+
protected readonly draftStart: _angular_core.WritableSignal<DateTime<boolean> | null>;
|
|
627
|
+
/** The day under the pointer or the keyboard while a range is in progress. */
|
|
628
|
+
protected readonly hovered: _angular_core.WritableSignal<DateTime<boolean> | null>;
|
|
629
|
+
/** The day the grid's single tab stop is on. */
|
|
630
|
+
private readonly activeDate;
|
|
631
|
+
/** The first month shown. */
|
|
632
|
+
protected readonly viewMonth: _angular_core.WritableSignal<DateTime<boolean>>;
|
|
633
|
+
protected readonly weekdays: _angular_core.Signal<{
|
|
634
|
+
short: string;
|
|
635
|
+
long: string;
|
|
636
|
+
}[]>;
|
|
637
|
+
private readonly presetResults;
|
|
638
|
+
protected readonly presetItems: _angular_core.Signal<RangePresetItem[]>;
|
|
639
|
+
/** The key of the grid's tab stop: the active day while it is on screen, else the first day shown. */
|
|
640
|
+
private readonly tabKey;
|
|
641
|
+
protected readonly months: _angular_core.Signal<RangeMonthView[]>;
|
|
642
|
+
protected readonly canGoBack: _angular_core.Signal<boolean>;
|
|
643
|
+
protected readonly canGoForward: _angular_core.Signal<boolean>;
|
|
644
|
+
/** The line under the grid, read out as it changes. */
|
|
645
|
+
protected readonly status: _angular_core.Signal<string>;
|
|
646
|
+
private overlayRef?;
|
|
647
|
+
private closeSub?;
|
|
648
|
+
private flipSub?;
|
|
649
|
+
protected onFieldClick(): void;
|
|
650
|
+
protected onFieldKeydown(event: KeyboardEvent): void;
|
|
651
|
+
protected onFocus(): void;
|
|
652
|
+
protected onBlur(): void;
|
|
653
|
+
protected onClearClick(event: Event): void;
|
|
654
|
+
/** Empties the range. The value becomes `null`. */
|
|
655
|
+
protected clear(event: Event | null): void;
|
|
656
|
+
protected pick(cell: RangeDayCell, event: Event): void;
|
|
657
|
+
protected onDayEnter(cell: RangeDayCell): void;
|
|
658
|
+
protected onDayFocus(cell: RangeDayCell): void;
|
|
659
|
+
/** The pointer left the grids: the preview falls back to the keyboard's day. */
|
|
660
|
+
protected onGridLeave(): void;
|
|
661
|
+
protected onDayKeydown(event: KeyboardEvent, cell: RangeDayCell): void;
|
|
662
|
+
private moveTo;
|
|
663
|
+
private ensureVisible;
|
|
664
|
+
private focusDay;
|
|
665
|
+
protected navigate(delta: number): void;
|
|
666
|
+
protected applyPreset(item: RangePresetItem, event: Event): void;
|
|
667
|
+
/** Commit the text typed into one end. Empty clears that end; unreadable text is put back. */
|
|
668
|
+
protected commitTyped(which: 'start' | 'end', event: Event): void;
|
|
669
|
+
protected onTypedKeydown(which: 'start' | 'end', event: KeyboardEvent): void;
|
|
670
|
+
protected onClearInPopup(event: Event): void;
|
|
671
|
+
private toDay;
|
|
672
|
+
private clampDay;
|
|
673
|
+
private serialize;
|
|
674
|
+
private commitRange;
|
|
675
|
+
/** Opens the popup on the start of the range (or today). No-op while open, disabled or read-only. */
|
|
676
|
+
open(): void;
|
|
677
|
+
/** Closes the popup, dropping a range that was only half picked. `restoreFocus` returns focus to the field. */
|
|
678
|
+
close(restoreFocus?: boolean): void;
|
|
679
|
+
ngOnDestroy(): void;
|
|
680
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeDateRangeBoxComponent, never>;
|
|
681
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeDateRangeBoxComponent, "nxe-date-range-box", never, { "displayFormat": { "alias": "displayFormat"; "required": false; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "presets": { "alias": "presets"; "required": false; "isSignal": true; }; "startPlaceholder": { "alias": "startPlaceholder"; "required": false; "isSignal": true; }; "endPlaceholder": { "alias": "endPlaceholder"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
273
682
|
}
|
|
274
683
|
|
|
275
684
|
/**
|
|
276
685
|
* `nxe-scroll-view` — drop-in replacement for DevExtreme `dx-scroll-view`.
|
|
277
686
|
*
|
|
278
|
-
* In this app `
|
|
687
|
+
* In this app `nxe-scroll-view` is used purely as a dumb scroll container: no `@ViewChild`, no
|
|
279
688
|
* `.instance` methods, no events (see survey). Every live tag is the same literal triple
|
|
280
689
|
* `[scrollByContent]="true" [scrollByThumb]="true" [showScrollbar]="'onScroll'"`. So this is a
|
|
281
690
|
* styled `overflow:auto` wrapper that projects its content inside a `.nxe-scrollview-content`
|
|
@@ -292,5 +701,325 @@ declare class NxeScrollViewComponent {
|
|
|
292
701
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeScrollViewComponent, "nxe-scroll-view", never, { "scrollByContent": { "alias": "scrollByContent"; "required": false; "isSignal": true; }; "scrollByThumb": { "alias": "scrollByThumb"; "required": false; "isSignal": true; }; "showScrollbar": { "alias": "showScrollbar"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
293
702
|
}
|
|
294
703
|
|
|
295
|
-
|
|
296
|
-
|
|
704
|
+
/**
|
|
705
|
+
* One validation message: a fixed string, or a function of the validator's error value (the
|
|
706
|
+
* object Angular puts under the validator key in `control.errors`, e.g. `{ requiredLength: 3,
|
|
707
|
+
* actualLength: 1 }` for `minlength`).
|
|
708
|
+
*/
|
|
709
|
+
type NxeErrorMessage = string | ((error: any) => string);
|
|
710
|
+
/** Validator key (`required`, `minlength`, ...) to the message shown for it. */
|
|
711
|
+
type NxeErrorMessages = Readonly<Record<string, NxeErrorMessage>>;
|
|
712
|
+
/** Key used when a failing validator has no entry and carries no message of its own. */
|
|
713
|
+
declare const NXE_FALLBACK_ERROR_KEY = "invalid";
|
|
714
|
+
/** English defaults for Angular's built-in validators. */
|
|
715
|
+
declare const NXE_DEFAULT_ERROR_MESSAGES: NxeErrorMessages;
|
|
716
|
+
/**
|
|
717
|
+
* Validator-key to message map read by `nxe-form-field`.
|
|
718
|
+
*
|
|
719
|
+
* Provide a plain object to replace it; keys you leave out fall back to
|
|
720
|
+
* {@link NXE_DEFAULT_ERROR_MESSAGES}, so a partial map is fine. {@link provideNxeErrorMessages} is
|
|
721
|
+
* the short way to write the provider. A custom validator is covered by adding its key:
|
|
722
|
+
* `{ uen: 'Enter a valid UEN.' }`.
|
|
723
|
+
*/
|
|
724
|
+
declare const NXE_ERROR_MESSAGES: InjectionToken<Readonly<Record<string, NxeErrorMessage>>>;
|
|
725
|
+
/**
|
|
726
|
+
* Registers messages for `nxe-form-field`, layered over the English defaults:
|
|
727
|
+
*
|
|
728
|
+
* ```ts
|
|
729
|
+
* provideNxeErrorMessages({
|
|
730
|
+
* required: 'Wajib diisi.',
|
|
731
|
+
* minlength: (e) => `Minimal ${e.requiredLength} karakter.`,
|
|
732
|
+
* })
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
declare function provideNxeErrorMessages(messages: NxeErrorMessages): EnvironmentProviders;
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* `nxe-form-field` wraps one `nxe-*` editor that is bound to a form control (`formControlName`,
|
|
739
|
+
* `[formControl]` or `ngModel`) and gives it the chrome a form needs:
|
|
740
|
+
*
|
|
741
|
+
* - a `label`, associated with the editor's inner control (`for` = the editor's `inputId`);
|
|
742
|
+
* - a required marker, from `Validators.required` on the control or the `required` input;
|
|
743
|
+
* - a `hint`, replaced by the error while one shows;
|
|
744
|
+
* - the message for the FIRST failing validator once the control is touched or its form submitted
|
|
745
|
+
* (`submitted` forces it), looked up in {@link NXE_ERROR_MESSAGES};
|
|
746
|
+
* - `serverErrors` / `serverError` from an API response, shown regardless of touched.
|
|
747
|
+
*
|
|
748
|
+
* It sets `aria-invalid`, `aria-required` and `aria-describedby` on the editor's focusable element
|
|
749
|
+
* and the editor host's `nxe-invalid` class, so the border, badge and colour come from the same
|
|
750
|
+
* `--nxe-ui-invalid*` tokens as an editor invalidated by `nxe-validator`.
|
|
751
|
+
*
|
|
752
|
+
* Reactivity is the control's own `events` stream (value, status, touched, submit, reset) feeding
|
|
753
|
+
* signals; the DOM sync runs through `afterRenderEffect`, which names the one computed it reads.
|
|
754
|
+
*/
|
|
755
|
+
declare class NxeFormFieldComponent implements AfterContentInit {
|
|
756
|
+
private readonly destroyRef;
|
|
757
|
+
private readonly tokenMessages;
|
|
758
|
+
private readonly messageService;
|
|
759
|
+
/** The enclosing form, when there is one: a template-driven control joins it a tick late. */
|
|
760
|
+
private readonly container;
|
|
761
|
+
/** Caption above the editor. */
|
|
762
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
763
|
+
/** Help text under the editor; hidden while an error is showing. */
|
|
764
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
765
|
+
/**
|
|
766
|
+
* Force the required marker on or off. Unset, it follows `Validators.required` (and
|
|
767
|
+
* `requiredTrue`) on the control. Needed for a rule the control does not declare as a validator.
|
|
768
|
+
*/
|
|
769
|
+
readonly required: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
770
|
+
/**
|
|
771
|
+
* API field errors, shown whether or not the control was touched. A string or a list of them;
|
|
772
|
+
* the app clears them (set `null`) when the user edits the field or resubmits.
|
|
773
|
+
*/
|
|
774
|
+
readonly serverErrors: _angular_core.InputSignal<string | readonly string[] | null | undefined>;
|
|
775
|
+
/** Singular spelling of {@link serverErrors}; both may be set, their messages are joined. */
|
|
776
|
+
readonly serverError: _angular_core.InputSignal<string | readonly string[] | null | undefined>;
|
|
777
|
+
/**
|
|
778
|
+
* Show client-side errors now (`true`) or never (`false`). Unset, they show once the control is
|
|
779
|
+
* touched or the surrounding form was submitted.
|
|
780
|
+
*/
|
|
781
|
+
readonly submitted: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
782
|
+
/** Messages for this field only, by validator key; override {@link NXE_ERROR_MESSAGES}. */
|
|
783
|
+
readonly errorMessages: _angular_core.InputSignal<Readonly<Record<string, NxeErrorMessage>> | undefined>;
|
|
784
|
+
private readonly ngControl;
|
|
785
|
+
private readonly ngControlHost;
|
|
786
|
+
/**
|
|
787
|
+
* Set when the projected editor carries Angular's Signal Forms `[formField]`. That directive
|
|
788
|
+
* provides a stand-in `NgControl` with no `events` stream, so the field then reads the field
|
|
789
|
+
* state's signals instead of subscribing to a control.
|
|
790
|
+
*/
|
|
791
|
+
private readonly formField;
|
|
792
|
+
private readonly formFieldHost;
|
|
793
|
+
private readonly editorHost;
|
|
794
|
+
private readonly fieldState;
|
|
795
|
+
/** Only read in dev mode, to catch a second editor the field would silently not bind. */
|
|
796
|
+
private readonly allControls;
|
|
797
|
+
private readonly touched;
|
|
798
|
+
private readonly controlErrors;
|
|
799
|
+
private readonly validatorRequired;
|
|
800
|
+
private readonly formSubmitted;
|
|
801
|
+
private readonly editor;
|
|
802
|
+
private readonly uid;
|
|
803
|
+
protected readonly labelId: string;
|
|
804
|
+
protected readonly hintId: string;
|
|
805
|
+
protected readonly errorId: string;
|
|
806
|
+
/** The id the label points at: the editor's inner control. Null for a non-nxe editor. */
|
|
807
|
+
protected readonly controlId: _angular_core.Signal<string | null>;
|
|
808
|
+
protected readonly isRequired: _angular_core.Signal<boolean>;
|
|
809
|
+
private readonly reveal;
|
|
810
|
+
private readonly clientMessage;
|
|
811
|
+
/** Everything shown under the editor as an error: the client message, then the server's. */
|
|
812
|
+
protected readonly messages: _angular_core.Signal<readonly string[]>;
|
|
813
|
+
readonly invalid: _angular_core.Signal<boolean>;
|
|
814
|
+
protected readonly showHint: _angular_core.Signal<boolean>;
|
|
815
|
+
private readonly domState;
|
|
816
|
+
/** Attributes this field put on the editor's element, so it only ever removes its own. */
|
|
817
|
+
private applied;
|
|
818
|
+
private invalidClassHost;
|
|
819
|
+
constructor();
|
|
820
|
+
ngAfterContentInit(): void;
|
|
821
|
+
private syncFromControl;
|
|
822
|
+
/**
|
|
823
|
+
* Message for one failing validator: this field's `errorMessages`, then an entry the app put in
|
|
824
|
+
* the {@link NXE_ERROR_MESSAGES} token, then the active `NxeMessageService` bundle (English
|
|
825
|
+
* unless the app switched language), then a string the validator itself returned
|
|
826
|
+
* (`{ uen: 'Not a valid UEN' }` or `{ uen: { message } }`), then the generic fallback.
|
|
827
|
+
*
|
|
828
|
+
* A token entry that IS the built-in default (the same reference, which is what
|
|
829
|
+
* `provideNxeErrorMessages` leaves for the keys it was not given) counts as unset, so it does
|
|
830
|
+
* not pin English over the bundle. Called from the `clientMessage` computed, so a language
|
|
831
|
+
* switch re-renders the error.
|
|
832
|
+
*/
|
|
833
|
+
private resolve;
|
|
834
|
+
/**
|
|
835
|
+
* Message for a Signal Forms error `{ kind, message? }`. The kind is mapped to the validator keys
|
|
836
|
+
* above (`minLength` to `minlength`, `maxLength` to `maxlength`; `required`, `min`, `max`, `pattern`
|
|
837
|
+
* and `email` as they are). Lookup order: this field's `errorMessages`, an app token entry, the
|
|
838
|
+
* error's own `message`, the library bundle, then the fallback (`invalid`). So a rule written
|
|
839
|
+
* with a message (`required(p.name, { message: '...' })`) shows it, and a custom kind does too.
|
|
840
|
+
*/
|
|
841
|
+
private resolveSignalError;
|
|
842
|
+
private explicitToken;
|
|
843
|
+
/** The library bundle's wording for Angular's built-in validators. */
|
|
844
|
+
private bundled;
|
|
845
|
+
/** The element a screen reader should treat as the field: the inner control, not the host. */
|
|
846
|
+
private focusable;
|
|
847
|
+
private setAttr;
|
|
848
|
+
private syncDom;
|
|
849
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeFormFieldComponent, never>;
|
|
850
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeFormFieldComponent, "nxe-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "serverErrors": { "alias": "serverErrors"; "required": false; "isSignal": true; }; "serverError": { "alias": "serverError"; "required": false; "isSignal": true; }; "submitted": { "alias": "submitted"; "required": false; "isSignal": true; }; "errorMessages": { "alias": "errorMessages"; "required": false; "isSignal": true; }; }, {}, ["ngControl", "ngControlHost", "formField", "formFieldHost", "allControls"], ["*"], true, never>;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/** What an `nxeRadioItem` template receives for each item. */
|
|
854
|
+
interface NxeRadioItemContext<T = unknown> {
|
|
855
|
+
/** The item, also available as `let-item`. */
|
|
856
|
+
$implicit: T;
|
|
857
|
+
item: T;
|
|
858
|
+
index: number;
|
|
859
|
+
selected: boolean;
|
|
860
|
+
disabled: boolean;
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Marks the `<ng-template>` that renders one radio's content in `nxe-radio-group`, in place of the
|
|
864
|
+
* `displayExpr` text:
|
|
865
|
+
*
|
|
866
|
+
* ```html
|
|
867
|
+
* <nxe-radio-group [items]="plans" valueExpr="id">
|
|
868
|
+
* <ng-template nxeRadioItem let-plan let-selected="selected">
|
|
869
|
+
* <strong>{{ plan.name }}</strong> <small>{{ plan.price }}</small>
|
|
870
|
+
* </ng-template>
|
|
871
|
+
* </nxe-radio-group>
|
|
872
|
+
* ```
|
|
873
|
+
*
|
|
874
|
+
* The radio's accessible name is the template's text, so keep it to text and inline markup.
|
|
875
|
+
*/
|
|
876
|
+
declare class NxeRadioItemDirective {
|
|
877
|
+
/** The template to render for each item. */
|
|
878
|
+
readonly template: TemplateRef<NxeRadioItemContext<unknown>>;
|
|
879
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeRadioItemDirective, never>;
|
|
880
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NxeRadioItemDirective, "ng-template[nxeRadioItem]", never, {}, {}, never, never, true, never>;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/** How the radios are laid out. */
|
|
884
|
+
type NxeRadioGroupLayout = 'horizontal' | 'vertical';
|
|
885
|
+
/** One radio, resolved from an item. */
|
|
886
|
+
interface RadioEntry {
|
|
887
|
+
readonly item: unknown;
|
|
888
|
+
readonly index: number;
|
|
889
|
+
readonly id: string;
|
|
890
|
+
readonly value: unknown;
|
|
891
|
+
readonly text: string;
|
|
892
|
+
readonly disabled: boolean;
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* `nxe-radio-group`: single choice among a few options, as the WAI-ARIA radio group pattern.
|
|
896
|
+
*
|
|
897
|
+
* A signal-CVA editor (extends {@link NxeFormControlBase}) working with `[(value)]`, `[(ngModel)]`
|
|
898
|
+
* and Reactive Forms. The options are `items`; `displayExpr` says what each shows (default: the
|
|
899
|
+
* item itself, for a list of strings), `valueExpr` what it puts in the control (default: the item
|
|
900
|
+
* itself) and `disabledExpr` (default `'disabled'`) which are not selectable. An
|
|
901
|
+
* `<ng-template nxeRadioItem>` replaces the text with your own content.
|
|
902
|
+
*
|
|
903
|
+
* Keyboard: the group is one tab stop, on the selected radio (or the first enabled one). Arrow keys
|
|
904
|
+
* move to the next or previous enabled radio, wrap around, and select it; Space selects the focused
|
|
905
|
+
* one. Left and Right are swapped in right-to-left text. A read-only group moves focus but never
|
|
906
|
+
* changes the value.
|
|
907
|
+
*
|
|
908
|
+
* The inner `role="radiogroup"` element carries the `inputId`, `aria-label` and `aria-labelledby`,
|
|
909
|
+
* so an `nxe-form-field` label names the group and its `aria-invalid` / `aria-describedby` land on
|
|
910
|
+
* it. Provides {@link NXE_VALIDATION_TARGET} for a projected `nxe-validator`.
|
|
911
|
+
*/
|
|
912
|
+
declare class NxeRadioGroupComponent extends NxeFormControlBase<unknown> {
|
|
913
|
+
/** The options. */
|
|
914
|
+
readonly items: _angular_core.InputSignal<readonly unknown[]>;
|
|
915
|
+
/** Text of an item; unset, the item itself. */
|
|
916
|
+
readonly displayExpr: _angular_core.InputSignal<NxeExpr>;
|
|
917
|
+
/** The value an item stands for; unset, the item itself. */
|
|
918
|
+
readonly valueExpr: _angular_core.InputSignal<NxeExpr>;
|
|
919
|
+
/** Truthy for an item that cannot be chosen. */
|
|
920
|
+
readonly disabledExpr: _angular_core.InputSignal<NxeExpr>;
|
|
921
|
+
/** `vertical` stacks the radios, `horizontal` puts them in a row that wraps. */
|
|
922
|
+
readonly layout: _angular_core.InputSignal<NxeRadioGroupLayout>;
|
|
923
|
+
/** Custom radio content. */
|
|
924
|
+
readonly itemTemplate: _angular_core.Signal<NxeRadioItemDirective | undefined>;
|
|
925
|
+
protected readonly entries: _angular_core.Signal<readonly RadioEntry[]>;
|
|
926
|
+
/** Index of the checked radio, or -1. */
|
|
927
|
+
protected readonly selectedIndex: _angular_core.Signal<number>;
|
|
928
|
+
/** The one radio in the tab order: the checked one when it can be reached, else the first enabled. */
|
|
929
|
+
protected readonly tabbableIndex: _angular_core.Signal<number>;
|
|
930
|
+
protected onItemClick(index: number, event: Event): void;
|
|
931
|
+
protected onItemKeydown(index: number, event: KeyboardEvent): void;
|
|
932
|
+
/** Leaving the group, not moving between its radios, is what touches the control. */
|
|
933
|
+
protected onGroupFocusOut(event: FocusEvent): void;
|
|
934
|
+
/** Focus (and, unless read-only, select) the next enabled radio in `step` direction, wrapping. */
|
|
935
|
+
private move;
|
|
936
|
+
private select;
|
|
937
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeRadioGroupComponent, never>;
|
|
938
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeRadioGroupComponent, "nxe-radio-group", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "displayExpr": { "alias": "displayExpr"; "required": false; "isSignal": true; }; "valueExpr": { "alias": "valueExpr"; "required": false; "isSignal": true; }; "disabledExpr": { "alias": "disabledExpr"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; }, {}, ["itemTemplate"], ["*"], true, never>;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/** Switch size; `medium` is the default. */
|
|
942
|
+
type NxeSwitchSize = 'small' | 'medium' | 'large';
|
|
943
|
+
/**
|
|
944
|
+
* `nxe-switch`: an on/off setting that takes effect as soon as it is flipped.
|
|
945
|
+
*
|
|
946
|
+
* A signal-CVA editor (extends {@link NxeFormControlBase}) over `boolean`; `null` and unset read as
|
|
947
|
+
* off. Works with `[(value)]`, `[(ngModel)]` and Reactive Forms. The host is the control:
|
|
948
|
+
* `role="switch"`, `aria-checked`, one tab stop; click and Space toggle it. A read-only switch is
|
|
949
|
+
* focusable but never flips; a disabled one leaves the tab order and dims.
|
|
950
|
+
*
|
|
951
|
+
* `text` is the label beside the track and names the switch (inside an `nxe-form-field` the field's
|
|
952
|
+
* label does instead). `onText` and `offText` are optional words drawn inside the track; they are
|
|
953
|
+
* decoration, hidden from assistive tech, because `aria-checked` already says which state it is in.
|
|
954
|
+
*/
|
|
955
|
+
declare class NxeSwitchComponent extends NxeFormControlBase<boolean> {
|
|
956
|
+
/** Label beside the track. */
|
|
957
|
+
readonly text: _angular_core.InputSignal<string | undefined>;
|
|
958
|
+
/** Word shown inside the track while on. */
|
|
959
|
+
readonly onText: _angular_core.InputSignal<string | undefined>;
|
|
960
|
+
/** Word shown inside the track while off. */
|
|
961
|
+
readonly offText: _angular_core.InputSignal<string | undefined>;
|
|
962
|
+
/** Track size. */
|
|
963
|
+
readonly size: _angular_core.InputSignal<NxeSwitchSize>;
|
|
964
|
+
readonly checked: _angular_core.Signal<boolean>;
|
|
965
|
+
protected toggle(event: Event): void;
|
|
966
|
+
protected onSpace(event: Event): void;
|
|
967
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeSwitchComponent, never>;
|
|
968
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeSwitchComponent, "nxe-switch", never, { "text": { "alias": "text"; "required": false; "isSignal": true; }; "onText": { "alias": "onText"; "required": false; "isSignal": true; }; "offText": { "alias": "offText"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/** Which characters a code may hold. */
|
|
972
|
+
type NxeOtpMode = 'numeric' | 'alphanumeric';
|
|
973
|
+
/**
|
|
974
|
+
* `nxe-otp-box`: a one-time code (2FA sign-in, e-mail verification, recovery code) drawn as one
|
|
975
|
+
* cell per character.
|
|
976
|
+
*
|
|
977
|
+
* It is ONE control, not N: a single transparent `<input>` lies over the cells and they only draw
|
|
978
|
+
* its text. That is what keeps a screen reader on one named field with one value, gives native
|
|
979
|
+
* paste, and lets the browser fill the whole code at once from an SMS or password manager
|
|
980
|
+
* (`autocomplete="one-time-code"`). Typing fills the next cell, Backspace empties the last one, and
|
|
981
|
+
* the caret is kept at the end, so the arrow keys do nothing. Pasting a code of `length` characters
|
|
982
|
+
* (or more) replaces the value, with separators such as a dash or space dropped; a shorter paste is
|
|
983
|
+
* appended.
|
|
984
|
+
*
|
|
985
|
+
* A signal-CVA over `string` (extends {@link NxeFormControlBase}); the value follows every
|
|
986
|
+
* keystroke, so a `minLength` validator sees a partial code and `completed` fires once with the full
|
|
987
|
+
* code. Name it with `aria-label`, `aria-labelledby` or an `nxe-form-field` label.
|
|
988
|
+
*/
|
|
989
|
+
declare class NxeOtpBoxComponent extends NxeFormControlBase<string> {
|
|
990
|
+
/** Number of characters in the code. */
|
|
991
|
+
readonly length: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
992
|
+
/** `numeric` (default) takes digits and opens the numeric keypad; `alphanumeric` takes letters and digits. */
|
|
993
|
+
readonly mode: _angular_core.InputSignal<NxeOtpMode>;
|
|
994
|
+
/** Focus the field when it first renders. */
|
|
995
|
+
readonly autoFocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
996
|
+
/** The full code, once, when the last cell is filled (typed, pasted or auto-filled). */
|
|
997
|
+
readonly completed: _angular_core.OutputEmitterRef<string>;
|
|
998
|
+
readonly focused: _angular_core.WritableSignal<boolean>;
|
|
999
|
+
private readonly field;
|
|
1000
|
+
protected readonly displayValue: _angular_core.Signal<string>;
|
|
1001
|
+
protected readonly cells: _angular_core.Signal<{
|
|
1002
|
+
index: number;
|
|
1003
|
+
char: string;
|
|
1004
|
+
active: boolean;
|
|
1005
|
+
}[]>;
|
|
1006
|
+
constructor();
|
|
1007
|
+
/** Drop what the mode does not allow and cut to `length`. */
|
|
1008
|
+
private clean;
|
|
1009
|
+
/** Typing, deleting and autofill: the field's text is the new value. */
|
|
1010
|
+
protected handleInput(event: Event): void;
|
|
1011
|
+
/** A whole code replaces the value; a fragment is appended. */
|
|
1012
|
+
protected onPaste(event: ClipboardEvent): void;
|
|
1013
|
+
/** Keys that would move the caret off the end do nothing: the cells have no caret to move. */
|
|
1014
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
1015
|
+
protected onFocus(): void;
|
|
1016
|
+
protected onBlur(): void;
|
|
1017
|
+
/** A click or a drag could put the caret mid-code or select it; it always belongs at the end. */
|
|
1018
|
+
protected keepCaretAtEnd(): void;
|
|
1019
|
+
private apply;
|
|
1020
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeOtpBoxComponent, never>;
|
|
1021
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeOtpBoxComponent, "nxe-otp-box", never, { "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "autoFocus": { "alias": "autoFocus"; "required": false; "isSignal": true; }; }, { "completed": "completed"; }, never, ["*"], true, never>;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
export { NXE_DATE_RANGE_DISPLAY_FORMAT, NXE_DATE_RANGE_NOW, NXE_DATE_RANGE_VALUE_FORMAT, NXE_DEFAULT_ERROR_MESSAGES, NXE_ERROR_MESSAGES, NXE_FALLBACK_ERROR_KEY, NxeButtonComponent, NxeCheckBoxComponent, NxeDateBoxComponent, NxeDateRangeBoxComponent, NxeFormFieldComponent, NxeNumberBoxComponent, NxeOtpBoxComponent, NxeRadioGroupComponent, NxeRadioItemDirective, NxeScrollViewComponent, NxeSwitchComponent, NxeTextAreaComponent, NxeTextBoxComponent, nxeDateRangePresets, provideNxeErrorMessages };
|
|
1025
|
+
export type { NxeButtonClickEvent, NxeButtonSize, NxeButtonStylingMode, NxeButtonType, NxeButtonValidationGroup, NxeDateBoxType, NxeDateRange, NxeDateRangeBound, NxeDateRangeBounds, NxeDateRangePreset, NxeErrorMessage, NxeErrorMessages, NxeOtpMode, NxeRadioGroupLayout, NxeRadioItemContext, NxeSwitchSize, NxeTextBoxMode };
|