@sdcorejs/angular 20.1.5 → 20.2.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 +12 -4
- package/assets/scss/core/menu.scss +18 -0
- package/assets/scss/core/utilities/_misc.scss +15 -0
- package/assets/scss/sd-core.scss +1 -0
- package/components/anchor/index.d.ts +3 -1
- package/components/badge/index.d.ts +1 -0
- package/components/ckeditor-styles/index.d.ts +1 -1
- package/components/form-generic/index.d.ts +44 -33
- package/components/import-excel/index.d.ts +1 -0
- package/components/index.d.ts +6 -1
- package/components/mini-editor/index.d.ts +1 -1
- package/components/modal/index.d.ts +3 -2
- package/components/modal-resizable/index.d.ts +92 -0
- package/components/org-chart/index.d.ts +6 -0
- package/components/preview/index.d.ts +1 -0
- package/components/query-bar/index.d.ts +55 -17
- package/components/query-builder/index.d.ts +150 -98
- package/components/section/index.d.ts +3 -0
- package/components/tab-router/index.d.ts +19 -19
- package/components/table/index.d.ts +252 -110
- package/components/tree/index.d.ts +48 -30
- package/components/upload-file/index.d.ts +6 -3
- package/configurations/index.d.ts +1 -2
- package/fesm2022/sdcorejs-angular-components-anchor.mjs +37 -13
- package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-badge.mjs +15 -2
- package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-button.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs +1 -1
- package/fesm2022/sdcorejs-angular-components-ckeditor-styles.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-code-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-data-state.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-editor.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +324 -192
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-history.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-history.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs +13 -5
- package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-inform.mjs +3 -3
- package/fesm2022/sdcorejs-angular-components-inform.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +164 -8
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal.mjs +30 -18
- package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs +60 -13
- package/fesm2022/sdcorejs-angular-components-org-chart.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +58 -19
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +192 -30
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +187 -127
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +16 -2
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +83 -24
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-splitter.mjs +57 -21
- package/fesm2022/sdcorejs-angular-components-splitter.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs +68 -20
- package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +3 -2
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +557 -255
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tree.mjs +80 -17
- package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +48 -13
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +6 -1
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-configurations.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-directives.mjs +45 -8
- package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +40 -29
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +5 -5
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +67 -50
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +57 -43
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +234 -64
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +209 -42
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +131 -27
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +40 -16
- package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +16 -5
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +24 -9
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +58 -10
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-models.mjs +279 -6
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +4 -4
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +136 -38
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +18 -3
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +51 -62
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs +57 -12
- package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-time.mjs +16 -5
- package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +100 -9
- package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms.mjs +91 -46
- package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-handlers.mjs +18 -3
- package/fesm2022/sdcorejs-angular-handlers.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +510 -68
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-interceptors.mjs +87 -29
- package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-auth.mjs +25 -15
- package/fesm2022/sdcorejs-angular-modules-auth.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-icon.mjs +2 -2
- package/fesm2022/sdcorejs-angular-modules-icon.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs +32 -3
- package/fesm2022/sdcorejs-angular-modules-keycloak.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-layout.mjs +441 -135
- package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-modules-permission.mjs +177 -40
- package/fesm2022/sdcorejs-angular-modules-permission.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-pipes.mjs +62 -28
- package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-api.mjs +123 -13
- package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-cache.mjs +53 -3
- package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +25 -73
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-excel.mjs +12 -10
- package/fesm2022/sdcorejs-angular-services-excel.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-loading.mjs +75 -84
- package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-notify.mjs +46 -5
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-storage.mjs +4 -0
- package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services.mjs +0 -1
- package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-utilities-extensions.mjs +225 -80
- package/fesm2022/sdcorejs-angular-utilities-extensions.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-utilities-models.mjs +1 -63
- package/fesm2022/sdcorejs-angular-utilities-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular.mjs +17 -10
- package/fesm2022/sdcorejs-angular.mjs.map +1 -1
- package/forms/autocomplete/index.d.ts +5 -2
- package/forms/chip-calendar/index.d.ts +10 -0
- package/forms/date/index.d.ts +21 -3
- package/forms/date-range/index.d.ts +14 -2
- package/forms/datetime/index.d.ts +13 -2
- package/forms/entity-picker/index.d.ts +9 -3
- package/forms/index.d.ts +22 -13
- package/forms/input/index.d.ts +3 -0
- package/forms/input-color/index.d.ts +4 -0
- package/forms/input-number/index.d.ts +3 -0
- package/forms/models/index.d.ts +146 -5
- package/forms/select/index.d.ts +27 -4
- package/forms/switch/index.d.ts +7 -1
- package/forms/textarea/index.d.ts +5 -3
- package/forms/time-range/index.d.ts +22 -1
- package/forms/tree-select/index.d.ts +36 -5
- package/i18n/index.d.ts +99 -16
- package/index.d.ts +11 -2
- package/interceptors/index.d.ts +13 -3
- package/modules/auth/index.d.ts +1 -1
- package/modules/keycloak/index.d.ts +1 -0
- package/modules/layout/index.d.ts +103 -28
- package/modules/permission/index.d.ts +66 -4
- package/package.json +40 -25
- package/pipes/index.d.ts +27 -5
- package/services/api/index.d.ts +21 -1
- package/services/cache/index.d.ts +11 -1
- package/services/index.d.ts +0 -1
- package/services/notify/index.d.ts +1 -1
- package/utilities/extensions/index.d.ts +83 -61
- package/utilities/models/index.d.ts +2 -76
- package/components/base/index.d.ts +0 -11
- package/components/document-builder/index.d.ts +0 -252
- package/fesm2022/sdcorejs-angular-components-base.mjs +0 -23
- package/fesm2022/sdcorejs-angular-components-base.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs +0 -5038
- package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-models.mjs +0 -6
- package/fesm2022/sdcorejs-angular-models.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-services-docx.mjs +0 -291
- package/fesm2022/sdcorejs-angular-services-docx.mjs.map +0 -1
- package/fesm2022/sdcorejs-angular-services-license.mjs +0 -97
- package/fesm2022/sdcorejs-angular-services-license.mjs.map +0 -1
- package/models/index.d.ts +0 -2
- package/services/docx/index.d.ts +0 -27
- package/services/license/index.d.ts +0 -12
package/forms/models/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Signal, Provider } from '@angular/core';
|
|
2
3
|
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
|
3
4
|
import { FormControl, FormControlState, ValidatorFn, FormControlOptions, AsyncValidatorFn, AbstractControl, FormGroup, NgForm } from '@angular/forms';
|
|
4
5
|
import { Subject } from 'rxjs';
|
|
6
|
+
import { DateFnsAdapter } from '@angular/material-date-fns-adapter';
|
|
7
|
+
import { MatDateFormats } from '@angular/material/core';
|
|
5
8
|
|
|
6
9
|
interface ISdFormConfiguration {
|
|
7
10
|
appearance?: MatFormFieldAppearance;
|
|
@@ -43,7 +46,7 @@ type SdCustomValidator = (value: any) => string | Promise<string>;
|
|
|
43
46
|
declare const SdInlineErrorValidator: ValidatorFn;
|
|
44
47
|
declare const HandleSdCustomValidator: (func: SdCustomValidator) => AsyncValidatorFn;
|
|
45
48
|
|
|
46
|
-
interface SdSelectionData<T =
|
|
49
|
+
interface SdSelectionData<T = unknown> {
|
|
47
50
|
multiple?: boolean;
|
|
48
51
|
values: any[];
|
|
49
52
|
selectedItems: T[];
|
|
@@ -57,7 +60,7 @@ interface SdSearchReq<TData extends string | number = string> {
|
|
|
57
60
|
searchFields?: string[];
|
|
58
61
|
value?: TData | TData[];
|
|
59
62
|
}
|
|
60
|
-
type SdSearch<T =
|
|
63
|
+
type SdSearch<T = unknown> = (args: SdSearchReq) => Promise<T[]>;
|
|
61
64
|
|
|
62
65
|
interface SdFormControlSnapshot<T> {
|
|
63
66
|
value: T | undefined;
|
|
@@ -119,6 +122,109 @@ interface SdViewedInlineApi {
|
|
|
119
122
|
*/
|
|
120
123
|
declare function sdViewedInline(viewed: Signal<SdViewed>, open?: () => void, disabled?: Signal<boolean>): SdViewedInlineApi;
|
|
121
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Output serialization strategy for the temporal form controls (`<sd-date>`, `<sd-datetime>`,
|
|
127
|
+
* `<sd-date-range>`).
|
|
128
|
+
*
|
|
129
|
+
* This names how a committed value leaves the component — through `model` / `modelChange` /
|
|
130
|
+
* `sdChange` and the registered `FormGroup` field. It does **not** touch what the field displays,
|
|
131
|
+
* and it is **not** an Angular input-coercion `transform`.
|
|
132
|
+
*/
|
|
133
|
+
type SdTemporalValueTransform = 'ISOString' | 'UTCString';
|
|
134
|
+
/** Every supported strategy, derived from the strategy map so the two can never drift. */
|
|
135
|
+
declare const SD_TEMPORAL_VALUE_TRANSFORMS: readonly SdTemporalValueTransform[];
|
|
136
|
+
declare function sdIsTemporalValueTransform(value: unknown): value is SdTemporalValueTransform;
|
|
137
|
+
/**
|
|
138
|
+
* Serializes a committed value with the active strategy.
|
|
139
|
+
*
|
|
140
|
+
* Returns `null` for anything that is not a usable `Date`, so an invalid value can never reach a
|
|
141
|
+
* serializer and produce the string `"Invalid Date"`. Callers treat `null` as "keep the existing
|
|
142
|
+
* representation".
|
|
143
|
+
*/
|
|
144
|
+
declare function sdSerializeTemporalValue(value: Date | null | undefined, transform: SdTemporalValueTransform | null | undefined): string | null;
|
|
145
|
+
/** Local midnight of the given day. Date-only controls serialize this instant, never the raw value. */
|
|
146
|
+
declare function sdLocalStartOfDay(value: Date): Date;
|
|
147
|
+
/**
|
|
148
|
+
* Parses the wire formats these transforms emit, so a component can read back its own output.
|
|
149
|
+
*
|
|
150
|
+
* Deliberately narrow: only ISO 8601 and the RFC-1123 shape `toUTCString()` produces are accepted.
|
|
151
|
+
* Handing the whole job to `new Date(text)` would make every loosely date-shaped string parse
|
|
152
|
+
* differently per browser, and would swallow the legacy canonical formats the components already
|
|
153
|
+
* parse with their own strict parsers. Returns `null` when the text is not one of these.
|
|
154
|
+
*/
|
|
155
|
+
declare function sdParseTransformedTemporal(value: unknown): Date | null;
|
|
156
|
+
|
|
157
|
+
interface ɵSdModelFacingControlOptions<TModel> {
|
|
158
|
+
/** Whether the model-facing control should be the one registered in the parent form. */
|
|
159
|
+
readonly active: Signal<boolean>;
|
|
160
|
+
/** The component's public model. */
|
|
161
|
+
readonly model: Signal<TModel>;
|
|
162
|
+
/** Applies an external write that arrived through the registered control. */
|
|
163
|
+
readonly writeModel: (value: TModel) => void;
|
|
164
|
+
/** The internal UI control whose validity, disabled and interaction state must be mirrored. */
|
|
165
|
+
readonly source: Signal<AbstractControl>;
|
|
166
|
+
/** Compares two model values; defaults to `Object.is`. */
|
|
167
|
+
readonly modelEquals?: (left: TModel, right: TModel) => boolean;
|
|
168
|
+
}
|
|
169
|
+
interface ɵSdModelFacingControl<TModel> {
|
|
170
|
+
/** The control itself. Holds the public model value, never the editor representation. */
|
|
171
|
+
readonly control: SdFormControl;
|
|
172
|
+
/** Feed straight into `ɵsdFormControlConnector`'s `registeredControl`. */
|
|
173
|
+
readonly registered: Signal<AbstractControl | null>;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* A second control that carries the **public model** so it can be registered in the parent form in
|
|
177
|
+
* place of the editor-facing control.
|
|
178
|
+
*
|
|
179
|
+
* why: `<sd-date>` and friends bind their control directly to the Material editor, so that control
|
|
180
|
+
* necessarily holds a `Date` or a display string. That is invisible until `transform` is set — at
|
|
181
|
+
* which point the consumer is told `form.get(name).value` equals `model`, and finding a raw `Date`
|
|
182
|
+
* there instead makes the promise false. Rather than reshaping the editor binding (which would
|
|
183
|
+
* change behaviour for every existing consumer), this mirrors the model into a control of its own
|
|
184
|
+
* and hands *that* one to the form.
|
|
185
|
+
*
|
|
186
|
+
* Both directions are wired, and neither can feed back on the other:
|
|
187
|
+
* - model changes are pushed in with `emitEvent: false`, so they raise no `valueChanges`;
|
|
188
|
+
* - a write that arrives on this control goes to `writeModel`, exactly like a write on the editor
|
|
189
|
+
* control would, so `modelChange` / `sdChange` still fire once.
|
|
190
|
+
*
|
|
191
|
+
* Validity, disabled and touched/dirty are mirrored from `source`, so registering this control does
|
|
192
|
+
* not quietly drop the editor's validators (min/max, parse errors, required) from the parent form.
|
|
193
|
+
*
|
|
194
|
+
* Must be called from an injection context.
|
|
195
|
+
*/
|
|
196
|
+
declare function ɵsdModelFacingControl<TModel>(options: ɵSdModelFacingControlOptions<TModel>): ɵSdModelFacingControl<TModel>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @internal Macrotask timers owned by a component/directive injector.
|
|
200
|
+
*
|
|
201
|
+
* Every pending handle is cleared when the host is destroyed, so a deferred focus,
|
|
202
|
+
* panel-open or emit can never run against a torn-down view.
|
|
203
|
+
*/
|
|
204
|
+
interface ɵSdTimerScope {
|
|
205
|
+
/**
|
|
206
|
+
* `setTimeout` with the same observable timing, minus the leak: the handle is tracked
|
|
207
|
+
* and cleared on destroy. Scheduling after destroy is a no-op.
|
|
208
|
+
*/
|
|
209
|
+
schedule(handler: () => void, delayMs?: number): void;
|
|
210
|
+
/** Cancels every pending timer without waiting for destroy. */
|
|
211
|
+
clear(): void;
|
|
212
|
+
/** Number of timers still pending. Test/diagnostics only. */
|
|
213
|
+
readonly pending: number;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* @internal Creates a destroy-scoped timer bag. MUST be called from an injection context
|
|
217
|
+
* (class field initializer or constructor) because it resolves `DestroyRef`.
|
|
218
|
+
*
|
|
219
|
+
* why: gần như mọi form control đều hoãn focus / mở panel bằng `setTimeout(..., 100)` để chờ
|
|
220
|
+
* Material dựng xong DOM. Handle không được giữ lại nên callback vẫn chạy sau khi host view đã
|
|
221
|
+
* destroy — route đổi nhanh hoặc chip bị gỡ giữa lúc focus là đủ để `detectChanges()` ném
|
|
222
|
+
* `ViewDestroyedError`, hoặc để một output bắn ra sau khi consumer đã unsubscribe. Gom vào một
|
|
223
|
+
* scope duy nhất để nơi dùng chỉ cần đổi `setTimeout(fn, ms)` → `#timers.schedule(fn, ms)`,
|
|
224
|
+
* KHÔNG đổi độ trễ (đây là fix vòng đời, không phải fix hành vi).
|
|
225
|
+
*/
|
|
226
|
+
declare function ɵsdTimerScope(): ɵSdTimerScope;
|
|
227
|
+
|
|
122
228
|
type ɵSdFormControlParent = FormGroup | NgForm | {
|
|
123
229
|
readonly form: unknown;
|
|
124
230
|
} | null | undefined;
|
|
@@ -129,6 +235,18 @@ interface ɵSdFormControlConnectorBaseOptions<TControl> {
|
|
|
129
235
|
readonly name: Signal<string | null | undefined>;
|
|
130
236
|
/** Canonical control registered in the parent form. */
|
|
131
237
|
readonly control: Signal<AbstractControl<TControl>>;
|
|
238
|
+
/**
|
|
239
|
+
* Control to register in the parent form **instead of** `control`, when the two must differ.
|
|
240
|
+
*
|
|
241
|
+
* why: `<sd-date>` / `<sd-datetime>` / `<sd-date-range>` bind `control` straight to the Material
|
|
242
|
+
* editor, so it necessarily holds the editor's own representation (a `Date`, or the display
|
|
243
|
+
* string) — not the public model. That is fine until `transform` is set, at which point the
|
|
244
|
+
* consumer is promised that `form.get(name).value` matches `model` and the `sdChange` payload.
|
|
245
|
+
* Yielding a model-facing control here moves only the *registration*; validators, disabled, state
|
|
246
|
+
* and the model binding all stay on `control`, so a `null`/absent signal keeps today's behaviour
|
|
247
|
+
* exactly. The component owning both controls is responsible for mirroring value and validity.
|
|
248
|
+
*/
|
|
249
|
+
readonly registeredControl?: Signal<AbstractControl | null | undefined>;
|
|
132
250
|
readonly validators?: Signal<ValidatorFn | readonly ValidatorFn[] | null | undefined>;
|
|
133
251
|
readonly asyncValidators?: Signal<AsyncValidatorFn | readonly AsyncValidatorFn[] | null | undefined>;
|
|
134
252
|
/** Adds/removes Validators.required while preserving validators supplied above. */
|
|
@@ -202,5 +320,28 @@ declare function ɵsdCoerceFormGroup(value: unknown): FormGroup | undefined;
|
|
|
202
320
|
*/
|
|
203
321
|
declare function ɵsdFormControlConnector<TModel, TControl>(options: ɵSdFormControlConnectorOptions<TModel, TControl>): ɵSdFormControlConnector<TControl>;
|
|
204
322
|
|
|
205
|
-
|
|
206
|
-
|
|
323
|
+
/**
|
|
324
|
+
* DateAdapter từ chối mọi chuỗi người dùng chưa gõ xong.
|
|
325
|
+
*
|
|
326
|
+
* WHY cần đến mức này: `<input matInput [matDatepicker]>` khiến Material tự
|
|
327
|
+
* `parse()` lại ô nhập SAU MỖI PHÍM GÕ rồi ghi thẳng kết quả vào form control.
|
|
328
|
+
* Adapter mặc định quá dễ dãi trên hai đường:
|
|
329
|
+
*
|
|
330
|
+
* 1. `date-fns.parse` nhận năm thiếu chữ số → `11/12/2` thành năm 0002,
|
|
331
|
+
* `11/12/20` thành năm 0020. Ô nhập vừa gõ dở đã bị coi là hợp lệ (cờ lỗi
|
|
332
|
+
* bị xoá) và control ôm một ngày rác.
|
|
333
|
+
* 2. `parseISO` coi chuỗi 2 chữ số là thế kỷ → xoá lùi còn `11` ra năm 1100.
|
|
334
|
+
*
|
|
335
|
+
* Cả hai đường đều bị chặn ở đây: control chỉ nhận giá trị khi người dùng thực
|
|
336
|
+
* sự gõ xong.
|
|
337
|
+
*/
|
|
338
|
+
declare class SdStrictDateFnsAdapter extends DateFnsAdapter {
|
|
339
|
+
parse(value: unknown, parseFormat: string | string[]): Date | null;
|
|
340
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdStrictDateFnsAdapter, never>;
|
|
341
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<SdStrictDateFnsAdapter>;
|
|
342
|
+
}
|
|
343
|
+
/** `provideDateFnsAdapter` + ép dùng adapter parse chặt ở trên. */
|
|
344
|
+
declare function provideSdStrictDateFnsAdapter(formats: MatDateFormats): Provider[];
|
|
345
|
+
|
|
346
|
+
export { HandleSdCustomValidator, SD_FORM_CONFIGURATION, SD_TEMPORAL_VALUE_TRANSFORMS, SdFormControl, SdInlineErrorValidator, SdStrictDateFnsAdapter, provideSdStrictDateFnsAdapter, sdFormControlState, sdIsTemporalValueTransform, sdLocalStartOfDay, sdParseTransformedTemporal, sdSerializeTemporalValue, sdViewedInline, sdViewedTransform, ɵsdCoerceFormGroup, ɵsdFormControlConnector, ɵsdModelFacingControl, ɵsdTimerScope };
|
|
347
|
+
export type { ISdFormConfiguration, SdCustomValidator, SdFormControlSnapshot, SdSearch, SdSearchReq, SdSelectionData, SdTemporalValueTransform, SdViewed, SdViewedInlineApi, SdViewedInput, ɵSdFormControlConnector, ɵSdFormControlConnectorOptions, ɵSdFormControlConnectorState, ɵSdFormControlParent, ɵSdModelFacingControl, ɵSdModelFacingControlOptions, ɵSdTimerScope };
|
package/forms/select/index.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ declare class SdSelectFooterActionDirective {
|
|
|
25
25
|
declare class SdSelect<T extends object | string | number = Record<string, unknown>> implements OnInit {
|
|
26
26
|
#private;
|
|
27
27
|
id: string;
|
|
28
|
+
/** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
|
|
29
|
+
* phải đọc được từ chính control, không chỉ hiện ra màn hình. */
|
|
30
|
+
readonly errorId: string;
|
|
28
31
|
matInputRef: Signal<MatInput | undefined>;
|
|
29
32
|
selectRef: Signal<MatSelect | undefined>;
|
|
30
33
|
sdLabelTemplate: Signal<TemplateRef<any> | undefined>;
|
|
@@ -62,8 +65,8 @@ declare class SdSelect<T extends object | string | number = Record<string, unkno
|
|
|
62
65
|
label: _angular_core.InputSignal<string | undefined>;
|
|
63
66
|
helperText: _angular_core.InputSignal<string | undefined>;
|
|
64
67
|
placeholder: _angular_core.InputSignal<string | undefined>;
|
|
65
|
-
valueField: _angular_core.InputSignal<T extends object ? { [Key in keyof T & string]: T[Key] extends string | number | boolean | Function | Date | null | undefined ? Key : T[Key] extends any[] ? Key : T[Key] extends object ? Key | `${Key}.${T[Key] extends infer T_1 ? T_1 extends T[Key] ? T_1 extends object ? { [Key_1 in keyof T_1 & string]: T_1[Key_1] extends string | number | boolean | Function | Date | null | undefined ? Key_1 : T_1[Key_1] extends any[] ? Key_1 : T_1[Key_1] extends object ? Key_1 | `${Key_1}.${T_1[Key_1] extends infer T_2 ? T_2 extends T_1[Key_1] ? T_2 extends object ? { [Key_2 in keyof T_2 & string]: T_2[Key_2] extends string | number | boolean | Function | Date | null | undefined ? Key_2 : T_2[Key_2] extends any[] ? Key_2 : T_2[Key_2] extends object ? Key_2 | `${Key_2}.${T_2[Key_2] extends infer T_3 ? T_3 extends T_2[Key_2] ? T_3 extends object ? { [Key_3 in keyof T_3 & string]: T_3[Key_3] extends string | number | boolean | Function | Date | null | undefined ? Key_3 : T_3[Key_3] extends any[] ? Key_3 : T_3[Key_3] extends object ? Key_3 : Key_3; }[keyof T_3 & string] : string : never : never}` : Key_2; }[keyof T_2 & string] : string : never : never}` : Key_1; }[keyof T_1 & string] : string : never : never}` : Key; }[keyof T & string] : string>;
|
|
66
|
-
displayField: _angular_core.InputSignal<T extends object ? { [Key in keyof T & string]: T[Key] extends string | number | boolean | Function | Date | null | undefined ? Key : T[Key] extends any[] ? Key : T[Key] extends object ? Key | `${Key}.${T[Key] extends infer T_1 ? T_1 extends T[Key] ? T_1 extends object ? { [Key_1 in keyof T_1 & string]: T_1[Key_1] extends string | number | boolean | Function | Date | null | undefined ? Key_1 : T_1[Key_1] extends any[] ? Key_1 : T_1[Key_1] extends object ? Key_1 | `${Key_1}.${T_1[Key_1] extends infer T_2 ? T_2 extends T_1[Key_1] ? T_2 extends object ? { [Key_2 in keyof T_2 & string]: T_2[Key_2] extends string | number | boolean | Function | Date | null | undefined ? Key_2 : T_2[Key_2] extends any[] ? Key_2 : T_2[Key_2] extends object ? Key_2 | `${Key_2}.${T_2[Key_2] extends infer T_3 ? T_3 extends T_2[Key_2] ? T_3 extends object ? { [Key_3 in keyof T_3 & string]: T_3[Key_3] extends string | number | boolean | Function | Date | null | undefined ? Key_3 : T_3[Key_3] extends any[] ? Key_3 : T_3[Key_3] extends object ? Key_3 : Key_3; }[keyof T_3 & string] : string : never : never}` : Key_2; }[keyof T_2 & string] : string : never : never}` : Key_1; }[keyof T_1 & string] : string : never : never}` : Key; }[keyof T & string] : string>;
|
|
68
|
+
valueField: _angular_core.InputSignal<"" | (T extends object ? { [Key in keyof T & string]: T[Key] extends string | number | boolean | Function | Date | null | undefined ? Key : T[Key] extends any[] ? Key : T[Key] extends object ? Key | `${Key}.${T[Key] extends infer T_1 ? T_1 extends T[Key] ? T_1 extends object ? { [Key_1 in keyof T_1 & string]: T_1[Key_1] extends string | number | boolean | Function | Date | null | undefined ? Key_1 : T_1[Key_1] extends any[] ? Key_1 : T_1[Key_1] extends object ? Key_1 | `${Key_1}.${T_1[Key_1] extends infer T_2 ? T_2 extends T_1[Key_1] ? T_2 extends object ? { [Key_2 in keyof T_2 & string]: T_2[Key_2] extends string | number | boolean | Function | Date | null | undefined ? Key_2 : T_2[Key_2] extends any[] ? Key_2 : T_2[Key_2] extends object ? Key_2 | `${Key_2}.${T_2[Key_2] extends infer T_3 ? T_3 extends T_2[Key_2] ? T_3 extends object ? { [Key_3 in keyof T_3 & string]: T_3[Key_3] extends string | number | boolean | Function | Date | null | undefined ? Key_3 : T_3[Key_3] extends any[] ? Key_3 : T_3[Key_3] extends object ? Key_3 : Key_3; }[keyof T_3 & string] : string : never : never}` : Key_2; }[keyof T_2 & string] : string : never : never}` : Key_1; }[keyof T_1 & string] : string : never : never}` : Key; }[keyof T & string] : string)>;
|
|
69
|
+
displayField: _angular_core.InputSignal<"" | (T extends object ? { [Key in keyof T & string]: T[Key] extends string | number | boolean | Function | Date | null | undefined ? Key : T[Key] extends any[] ? Key : T[Key] extends object ? Key | `${Key}.${T[Key] extends infer T_1 ? T_1 extends T[Key] ? T_1 extends object ? { [Key_1 in keyof T_1 & string]: T_1[Key_1] extends string | number | boolean | Function | Date | null | undefined ? Key_1 : T_1[Key_1] extends any[] ? Key_1 : T_1[Key_1] extends object ? Key_1 | `${Key_1}.${T_1[Key_1] extends infer T_2 ? T_2 extends T_1[Key_1] ? T_2 extends object ? { [Key_2 in keyof T_2 & string]: T_2[Key_2] extends string | number | boolean | Function | Date | null | undefined ? Key_2 : T_2[Key_2] extends any[] ? Key_2 : T_2[Key_2] extends object ? Key_2 | `${Key_2}.${T_2[Key_2] extends infer T_3 ? T_3 extends T_2[Key_2] ? T_3 extends object ? { [Key_3 in keyof T_3 & string]: T_3[Key_3] extends string | number | boolean | Function | Date | null | undefined ? Key_3 : T_3[Key_3] extends any[] ? Key_3 : T_3[Key_3] extends object ? Key_3 : Key_3; }[keyof T_3 & string] : string : never : never}` : Key_2; }[keyof T_2 & string] : string : never : never}` : Key_1; }[keyof T_1 & string] : string : never : never}` : Key; }[keyof T & string] : string)>;
|
|
67
70
|
disabledField: _angular_core.InputSignal<"" | (T extends object ? { [Key in keyof T & string]: T[Key] extends string | number | boolean | Function | Date | null | undefined ? Key : T[Key] extends any[] ? Key : T[Key] extends object ? Key | `${Key}.${T[Key] extends infer T_1 ? T_1 extends T[Key] ? T_1 extends object ? { [Key_1 in keyof T_1 & string]: T_1[Key_1] extends string | number | boolean | Function | Date | null | undefined ? Key_1 : T_1[Key_1] extends any[] ? Key_1 : T_1[Key_1] extends object ? Key_1 | `${Key_1}.${T_1[Key_1] extends infer T_2 ? T_2 extends T_1[Key_1] ? T_2 extends object ? { [Key_2 in keyof T_2 & string]: T_2[Key_2] extends string | number | boolean | Function | Date | null | undefined ? Key_2 : T_2[Key_2] extends any[] ? Key_2 : T_2[Key_2] extends object ? Key_2 | `${Key_2}.${T_2[Key_2] extends infer T_3 ? T_3 extends T_2[Key_2] ? T_3 extends object ? { [Key_3 in keyof T_3 & string]: T_3[Key_3] extends string | number | boolean | Function | Date | null | undefined ? Key_3 : T_3[Key_3] extends any[] ? Key_3 : T_3[Key_3] extends object ? Key_3 : Key_3; }[keyof T_3 & string] : string : never : never}` : Key_2; }[keyof T_2 & string] : string : never : never}` : Key_1; }[keyof T_1 & string] : string : never : never}` : Key; }[keyof T & string] : string)>;
|
|
68
71
|
cacheChecksum: _angular_core.InputSignal<any>;
|
|
69
72
|
limit: _angular_core.InputSignal<number>;
|
|
@@ -75,6 +78,11 @@ declare class SdSelect<T extends object | string | number = Record<string, unkno
|
|
|
75
78
|
/** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (bare editor). */
|
|
76
79
|
viewed: _angular_core.InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
77
80
|
multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
81
|
+
/**
|
|
82
|
+
* Hiện option "Tất cả" đầu panel (chỉ multiple + items là mảng tĩnh/Signal — ẩn với
|
|
83
|
+
* SdSearch lazy vì dataset không xác định). Opt-in, default `false`.
|
|
84
|
+
*/
|
|
85
|
+
showSelectAll: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
78
86
|
/**
|
|
79
87
|
* Whether the `viewed='inline'` text face shows a hover clear-× to empty the value.
|
|
80
88
|
* Default `true`. Set `false` where the HOST owns removal (e.g. `<sd-query-bar>` chips,
|
|
@@ -99,7 +107,7 @@ declare class SdSelect<T extends object | string | number = Record<string, unkno
|
|
|
99
107
|
items: _angular_core.InputSignal<SdSearch | T[] | Signal<T[]> | null | undefined>;
|
|
100
108
|
valueModel: _angular_core.ModelSignal<string | number | boolean | (string | number)[] | null | undefined>;
|
|
101
109
|
sdChange: _angular_core.OutputEmitterRef<any>;
|
|
102
|
-
sdSelection: _angular_core.OutputEmitterRef<SdSelectionData<
|
|
110
|
+
sdSelection: _angular_core.OutputEmitterRef<SdSelectionData<unknown>>;
|
|
103
111
|
formControl: SdFormControl;
|
|
104
112
|
inputControl: FormControl<string | null>;
|
|
105
113
|
loading: _angular_core.WritableSignal<boolean>;
|
|
@@ -120,6 +128,15 @@ declare class SdSelect<T extends object | string | number = Record<string, unkno
|
|
|
120
128
|
normalizedValue: Signal<string | number | boolean | (string | number | boolean)[] | null | undefined>;
|
|
121
129
|
filtered: Signal<boolean>;
|
|
122
130
|
delayTime: Signal<0 | 500>;
|
|
131
|
+
/**
|
|
132
|
+
* Scope của "Tất cả": item enabled khớp search text hiện tại, tính trên MẢNG NGUỒN
|
|
133
|
+
* `actualItems()`.
|
|
134
|
+
*/
|
|
135
|
+
readonly selectAllScope: Signal<T[]>;
|
|
136
|
+
/** Row "Tất cả" chỉ render khi opt-in + multiple + items tĩnh + scope có item để thao tác. */
|
|
137
|
+
readonly selectAllVisible: Signal<boolean>;
|
|
138
|
+
/** Trạng thái checkbox "Tất cả", tính trên items ENABLED trong scope (item disabled bỏ qua). */
|
|
139
|
+
readonly selectAllState: Signal<"checked" | "indeterminate" | "unchecked">;
|
|
123
140
|
itemValue: (item: T) => unknown;
|
|
124
141
|
itemDisplay: (item: T) => string;
|
|
125
142
|
itemDisabled: (item: T) => boolean;
|
|
@@ -130,6 +147,12 @@ declare class SdSelect<T extends object | string | number = Record<string, unkno
|
|
|
130
147
|
constructor();
|
|
131
148
|
ngOnInit(): void;
|
|
132
149
|
onSelectionChange: (change: MatSelectChange) => void;
|
|
150
|
+
/**
|
|
151
|
+
* Toggle "Tất cả" theo scope hiện tại (items enabled khớp search):
|
|
152
|
+
* - Đang `checked` → BỎ chọn các value trong scope (giữ value ngoài scope, kể cả item disabled đã chọn).
|
|
153
|
+
* - Ngược lại → CHỌN THÊM toàn bộ scope, union với selection hiện có (additive khi đang search).
|
|
154
|
+
*/
|
|
155
|
+
toggleSelectAll: () => void;
|
|
133
156
|
reValidate: () => void;
|
|
134
157
|
clear: ($event?: any) => void;
|
|
135
158
|
onClick: () => void;
|
|
@@ -140,7 +163,7 @@ declare class SdSelect<T extends object | string | number = Record<string, unkno
|
|
|
140
163
|
open: () => void;
|
|
141
164
|
onOpenedChange: (isOpened: boolean) => void;
|
|
142
165
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdSelect<any>, never>;
|
|
143
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSelect<any>, "sd-select", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required":
|
|
166
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdSelect<any>, "sd-select", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": false; "isSignal": true; }; "disabledField": { "alias": "disabledField"; "required": false; "isSignal": true; }; "cacheChecksum": { "alias": "cacheChecksum"; "required": false; "isSignal": true; }; "limit": { "alias": "limit"; "required": false; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "minWidthPanel": { "alias": "minWidthPanel"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "showSelectAll": { "alias": "showSelectAll"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "validator": { "alias": "validator"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; "sdSelection": "sdSelection"; }, ["sdLabelTemplate", "sdValueTemplate", "sdSelectedTemplate", "itemDef", "sdViewDef", "footerActions"], ["[sdLabel]"], true, never>;
|
|
144
167
|
}
|
|
145
168
|
|
|
146
169
|
export { SdSelect, SdSelectFooterActionDirective };
|
package/forms/switch/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import * as _sdcorejs_angular_forms_models from '@sdcorejs/angular/forms/models';
|
|
2
|
+
import { SdFormControl, ɵSdFormControlParent as _SdFormControlParent, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
1
3
|
import * as _angular_core from '@angular/core';
|
|
2
4
|
import { OnInit, OnDestroy } from '@angular/core';
|
|
3
|
-
import { SdFormControl, ɵSdFormControlParent as _SdFormControlParent, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
4
5
|
import { Color } from '@sdcorejs/utils/models';
|
|
5
6
|
|
|
6
7
|
declare class SdSwitch implements OnInit, OnDestroy {
|
|
@@ -26,6 +27,11 @@ declare class SdSwitch implements OnInit, OnDestroy {
|
|
|
26
27
|
readonly dataEmpty: _angular_core.Signal<"true" | "false">;
|
|
27
28
|
readonly dataValue: _angular_core.Signal<string>;
|
|
28
29
|
readonly dataRequired: _angular_core.Signal<"true" | "false">;
|
|
30
|
+
readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
31
|
+
/** Shared reactive form policy — `validationError` is already interaction-gated (touched/dirty). */
|
|
32
|
+
readonly connectorState: _angular_core.Signal<_sdcorejs_angular_forms_models.ɵSdFormControlConnectorState<boolean | null | undefined>>;
|
|
33
|
+
/** Message to render inline; `undefined` while untouched, or when `hideInlineError` is set. */
|
|
34
|
+
readonly visibleErrorMessage: _angular_core.Signal<string | undefined>;
|
|
29
35
|
ngOnInit(): void;
|
|
30
36
|
ngOnDestroy(): void;
|
|
31
37
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdSwitch, never>;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnInit,
|
|
2
|
+
import { OnInit, OnDestroy, ElementRef } from '@angular/core';
|
|
3
3
|
import { FormGroup } from '@angular/forms';
|
|
4
4
|
import { MatFormFieldAppearance, FloatLabelType } from '@angular/material/form-field';
|
|
5
5
|
import { SdViewDefDirective, SdLabelDefDirective, SdSuffixDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
6
6
|
import { SdViewed, SdViewedInput, SdCustomValidator, SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
7
7
|
import { Size } from '@sdcorejs/utils/models';
|
|
8
8
|
|
|
9
|
-
declare class SdTextarea implements OnInit,
|
|
9
|
+
declare class SdTextarea implements OnInit, OnDestroy {
|
|
10
10
|
#private;
|
|
11
11
|
id: string;
|
|
12
|
+
/** why: id ổn định của <mat-error> để control trỏ `aria-describedby` sang — thông báo lỗi
|
|
13
|
+
* phải đọc được từ chính control, không chỉ hiện ra màn hình. */
|
|
14
|
+
readonly errorId: string;
|
|
12
15
|
textareaRef: _angular_core.Signal<ElementRef<HTMLTextAreaElement> | undefined>;
|
|
13
16
|
sdViewDef: _angular_core.Signal<SdViewDefDirective<any, any> | undefined>;
|
|
14
17
|
sdLabelDef: _angular_core.Signal<SdLabelDefDirective | undefined>;
|
|
@@ -59,7 +62,6 @@ declare class SdTextarea implements OnInit, AfterViewInit, OnDestroy {
|
|
|
59
62
|
isFocused: boolean;
|
|
60
63
|
constructor();
|
|
61
64
|
ngOnInit(): void;
|
|
62
|
-
ngAfterViewInit(): void;
|
|
63
65
|
ngOnDestroy(): void;
|
|
64
66
|
onFocus: () => void;
|
|
65
67
|
onBlur: () => void;
|
|
@@ -75,8 +75,29 @@ declare class SdTimeRange {
|
|
|
75
75
|
readonly isReadonly: _angular_core.Signal<boolean>;
|
|
76
76
|
readonly viewTemplate: _angular_core.Signal<TemplateRef<unknown> | undefined>;
|
|
77
77
|
readonly displayValue: _angular_core.Signal<string>;
|
|
78
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Endpoint invalid ĐÃ gate theo tương tác — CHỈ dùng cho hiển thị (message, `data-invalid`).
|
|
80
|
+
* `connectorState().invalid` của `sd-time` là `invalid && (touched || dirty)`.
|
|
81
|
+
*/
|
|
79
82
|
readonly endpointInvalid: _angular_core.Signal<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* Endpoint invalid THÔ — không gate theo tương tác. Dùng cho VALIDATOR của control tổng.
|
|
85
|
+
* why: endpoint không còn được đăng ký vào FormGroup của consumer, nên validity của chúng chỉ
|
|
86
|
+
* tới được form cha qua control tổng. Nếu đường đó cũng gate theo `touched || dirty` thì một
|
|
87
|
+
* endpoint invalid do ghi programmatic (chưa ai chạm vào) sẽ để form cha VALID — sai contract
|
|
88
|
+
* đã ghi trong `sd-time-range.md`.
|
|
89
|
+
* `formControl.invalid` là property thường nên tự nó không phát tín hiệu; đọc `connectorState()`
|
|
90
|
+
* một nhịp để computed có dependency reactive theo `events` của endpoint control.
|
|
91
|
+
*/
|
|
92
|
+
readonly endpointInvalidRaw: _angular_core.Signal<boolean>;
|
|
93
|
+
/**
|
|
94
|
+
* Message đã gate theo tương tác — thứ template được phép hiển thị.
|
|
95
|
+
* why: `errorMessage()` thô bung lỗi ngay lần paint đầu với `[required]`, khi người dùng chưa
|
|
96
|
+
* chạm vào ô nào. `connectorState().validationError` gate theo control tổng; range còn có 2
|
|
97
|
+
* endpoint có thể invalid trong khi control tổng chưa dirty (text sai không tới được model tổng),
|
|
98
|
+
* nên phải cộng thêm nhánh endpoint — `endpointInvalid` tự nó đã gate theo touched/dirty.
|
|
99
|
+
*/
|
|
100
|
+
readonly visibleError: _angular_core.Signal<string | undefined>;
|
|
80
101
|
readonly dataDisabled: _angular_core.Signal<"true" | "false">;
|
|
81
102
|
readonly dataInvalid: _angular_core.Signal<"true" | "false">;
|
|
82
103
|
readonly dataEmpty: _angular_core.Signal<"true" | "false">;
|
|
@@ -2,9 +2,12 @@ import * as _sdcorejs_angular_forms_models from '@sdcorejs/angular/forms/models'
|
|
|
2
2
|
import { ɵSdFormControlParent as _SdFormControlParent, SdViewed, SdViewedInput, SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
3
3
|
import * as _angular_core from '@angular/core';
|
|
4
4
|
import { ElementRef, TemplateRef } from '@angular/core';
|
|
5
|
-
import { FormGroup } from '@angular/forms';
|
|
5
|
+
import { FormGroup, FormControl } from '@angular/forms';
|
|
6
|
+
import { ErrorStateMatcher } from '@angular/material/core';
|
|
7
|
+
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
|
6
8
|
import { SdModal } from '@sdcorejs/angular/components/modal';
|
|
7
9
|
import { SdTree, SdTreeItemContext, SdTreeDataSource, SdTreeItem, SdTreeOption, SdTreeLoadErrorEvent, SdTreeComponentOption, SdTreeSelectionEvent } from '@sdcorejs/angular/components/tree';
|
|
10
|
+
import { Size } from '@sdcorejs/utils/models';
|
|
8
11
|
|
|
9
12
|
type SdTreeSelectModel<TKey> = TKey | TKey[] | null | undefined;
|
|
10
13
|
type SdTreeSelectTemplateContext<T> = SdTreeItemContext<T>;
|
|
@@ -16,18 +19,24 @@ declare class SdTreeSelectNodeTemplateDirective<T> {
|
|
|
16
19
|
}
|
|
17
20
|
declare class SdTreeSelect<T = unknown, TKey = string | number> {
|
|
18
21
|
#private;
|
|
19
|
-
readonly trigger: _angular_core.Signal<ElementRef<
|
|
22
|
+
readonly trigger: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
20
23
|
readonly modal: _angular_core.Signal<SdModal | undefined>;
|
|
21
24
|
readonly treeComponent: _angular_core.Signal<SdTree<T> | undefined>;
|
|
22
25
|
readonly nodeTemplate: _angular_core.Signal<SdTreeSelectNodeTemplateDirective<any> | undefined>;
|
|
26
|
+
readonly errorId: string;
|
|
23
27
|
readonly autoIdInput: _angular_core.InputSignal<string | null | undefined>;
|
|
24
28
|
readonly autoId: _angular_core.Signal<string | undefined>;
|
|
25
29
|
readonly name: _angular_core.InputSignal<string>;
|
|
26
30
|
readonly form: _angular_core.InputSignalWithTransform<FormGroup<any> | undefined, _SdFormControlParent>;
|
|
27
31
|
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
32
|
+
readonly helperText: _angular_core.InputSignal<string | undefined>;
|
|
28
33
|
readonly placeholder: _angular_core.InputSignal<string | null | undefined>;
|
|
29
34
|
readonly modalTitle: _angular_core.InputSignal<string | null | undefined>;
|
|
30
35
|
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
36
|
+
readonly size: _angular_core.InputSignal<Size>;
|
|
37
|
+
readonly appearanceInput: _angular_core.InputSignal<MatFormFieldAppearance | undefined>;
|
|
38
|
+
readonly appearance: _angular_core.Signal<MatFormFieldAppearance>;
|
|
39
|
+
readonly hideInlineError: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
31
40
|
readonly items: _angular_core.InputSignal<SdTreeDataSource<SdTreeItem<T>>>;
|
|
32
41
|
readonly tree: _angular_core.InputSignal<SdTreeOption<T>>;
|
|
33
42
|
readonly valueField: _angular_core.InputSignal<(T extends object ? { [Key in keyof T & string]: T[Key] extends string | number | boolean | Function | Date | null | undefined ? Key : T[Key] extends any[] ? Key : T[Key] extends object ? Key | `${Key}.${T[Key] extends infer T_1 ? T_1 extends T[Key] ? T_1 extends object ? { [Key_1 in keyof T_1 & string]: T_1[Key_1] extends string | number | boolean | Function | Date | null | undefined ? Key_1 : T_1[Key_1] extends any[] ? Key_1 : T_1[Key_1] extends object ? Key_1 | `${Key_1}.${T_1[Key_1] extends infer T_2 ? T_2 extends T_1[Key_1] ? T_2 extends object ? { [Key_2 in keyof T_2 & string]: T_2[Key_2] extends string | number | boolean | Function | Date | null | undefined ? Key_2 : T_2[Key_2] extends any[] ? Key_2 : T_2[Key_2] extends object ? Key_2 | `${Key_2}.${T_2[Key_2] extends infer T_3 ? T_3 extends T_2[Key_2] ? T_3 extends object ? { [Key_3 in keyof T_3 & string]: T_3[Key_3] extends string | number | boolean | Function | Date | null | undefined ? Key_3 : T_3[Key_3] extends any[] ? Key_3 : T_3[Key_3] extends object ? Key_3 : Key_3; }[keyof T_3 & string] : string : never : never}` : Key_2; }[keyof T_2 & string] : string : never : never}` : Key_1; }[keyof T_1 & string] : string : never : never}` : Key; }[keyof T & string] : string) | undefined>;
|
|
@@ -39,15 +48,36 @@ declare class SdTreeSelect<T = unknown, TKey = string | number> {
|
|
|
39
48
|
readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
40
49
|
readonly cascade: _angular_core.InputSignal<"independent" | "descendants">;
|
|
41
50
|
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
51
|
+
/** Component-local error text. Set it to force the control invalid and render the message. */
|
|
52
|
+
readonly inlineError: _angular_core.InputSignal<string | undefined>;
|
|
42
53
|
readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
43
54
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
44
55
|
readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
45
56
|
readonly viewed: _angular_core.InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
46
57
|
readonly model: _angular_core.ModelSignal<SdTreeSelectModel<TKey>>;
|
|
47
58
|
readonly sdChange: _angular_core.OutputEmitterRef<SdTreeSelectModel<TKey>>;
|
|
48
|
-
readonly
|
|
59
|
+
readonly loadError: _angular_core.OutputEmitterRef<SdTreeLoadErrorEvent<T>>;
|
|
49
60
|
readonly formControl: SdFormControl;
|
|
61
|
+
readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
50
62
|
readonly connectorState: _angular_core.Signal<_sdcorejs_angular_forms_models.ɵSdFormControlConnectorState<SdTreeSelectModel<TKey>>>;
|
|
63
|
+
/** Interaction-gated validation message; `undefined` until the control is touched/dirty. */
|
|
64
|
+
readonly visibleErrorMessage: _angular_core.Signal<string | undefined>;
|
|
65
|
+
/**
|
|
66
|
+
* Text-only control backing the readonly trigger; `formControl` above holds the real keys.
|
|
67
|
+
*
|
|
68
|
+
* why: phải là một `FormControl` THẬT chứ không phải `[value]`. `MatInput.ngDoCheck` chỉ gọi
|
|
69
|
+
* `updateErrorState()` khi có `NgControl` — không có nó thì `errorState` đứng yên ở `false`, mà
|
|
70
|
+
* `<mat-error>`, viền đỏ và `aria-invalid` đều bám vào cờ đó, nên field bắt buộc bỏ trống lại im
|
|
71
|
+
* lặng y như bug cũ. Trạng thái disabled cũng chảy qua control này (MatInput tự đồng bộ
|
|
72
|
+
* `disabled` từ `ngControl` mỗi vòng CD, nên bind `[disabled]` trên template sẽ bị ghi đè).
|
|
73
|
+
*/
|
|
74
|
+
readonly displayControl: FormControl<string>;
|
|
75
|
+
/**
|
|
76
|
+
* why: MatInput đã có `NgControl`, nhưng control đó là ô TEXT — nó không biết gì về `required`
|
|
77
|
+
* hay validator của tree-select. Matcher nối thẳng `errorState` của Material vào message đã gate
|
|
78
|
+
* theo tương tác của connector.
|
|
79
|
+
*/
|
|
80
|
+
readonly errorStateMatcher: ErrorStateMatcher;
|
|
51
81
|
readonly draftKeys: _angular_core.WritableSignal<TKey[]>;
|
|
52
82
|
readonly modelKeys: _angular_core.Signal<TKey[]>;
|
|
53
83
|
readonly effectivePlaceholder: _angular_core.Signal<string>;
|
|
@@ -57,7 +87,8 @@ declare class SdTreeSelect<T = unknown, TKey = string | number> {
|
|
|
57
87
|
readonly draftEntities: _angular_core.Signal<T[]>;
|
|
58
88
|
readonly displayText: _angular_core.Signal<string>;
|
|
59
89
|
readonly treeOption: _angular_core.Signal<SdTreeComponentOption<T>>;
|
|
60
|
-
|
|
90
|
+
constructor();
|
|
91
|
+
open(event?: Event): void;
|
|
61
92
|
applySelection(): void;
|
|
62
93
|
cancel(): void;
|
|
63
94
|
clear(event?: Event): void;
|
|
@@ -68,7 +99,7 @@ declare class SdTreeSelect<T = unknown, TKey = string | number> {
|
|
|
68
99
|
keyOf(item: T): TKey;
|
|
69
100
|
displayEntity(item: T): string;
|
|
70
101
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdTreeSelect<any, any>, never>;
|
|
71
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdTreeSelect<any, any>, "sd-tree-select", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "modalTitle": { "alias": "modalTitle"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "tree": { "alias": "tree"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "keySelector": { "alias": "keySelector"; "required": false; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "disabledNode": { "alias": "disabledNode"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "cascade": { "alias": "cascade"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "model": "modelChange"; "sdChange": "sdChange"; "
|
|
102
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdTreeSelect<any, any>, "sd-tree-select", never, { "autoIdInput": { "alias": "autoId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "modalTitle": { "alias": "modalTitle"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "tree": { "alias": "tree"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "keySelector": { "alias": "keySelector"; "required": false; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "disabledNode": { "alias": "disabledNode"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "cascade": { "alias": "cascade"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "viewed": { "alias": "viewed"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; }, { "model": "modelChange"; "sdChange": "sdChange"; "loadError": "loadError"; }, ["nodeTemplate"], ["[sdLabel]"], true, never>;
|
|
72
103
|
}
|
|
73
104
|
declare function normalizeTreeSelectKeys<TKey>(value: SdTreeSelectModel<TKey>, multiple: boolean): TKey[];
|
|
74
105
|
|