@sdcorejs/angular 19.0.1 → 19.0.4
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 +22 -4
- package/assets/scss/core/_inline-edit.scss +105 -0
- package/assets/scss/core/form.scss +15 -0
- package/components/autoid-inspector/src/models/autoid-element.model.d.ts +11 -0
- package/components/autoid-inspector/src/models/autoid-export-format.model.d.ts +19 -0
- package/components/autoid-inspector/src/services/autoid-export.service.d.ts +7 -1
- package/components/autoid-inspector/src/services/autoid-scanner.service.d.ts +15 -2
- package/components/button/src/button.component.d.ts +1 -2
- package/components/form-generic/src/components/form-builder/form-builder.component.d.ts +13 -15
- package/components/form-generic/src/components/form-render/form-render.component.d.ts +1 -2
- package/components/form-generic/src/components/sd-feel-expression/sd-feel-expression.component.d.ts +1 -2
- package/components/index.d.ts +1 -0
- package/components/modal-resizable/index.d.ts +1 -0
- package/components/modal-resizable/src/modal-resizable.component.d.ts +29 -0
- package/components/query-bar/src/components/inline-chip/inline-chip.component.d.ts +11 -22
- package/components/query-bar/src/components/inline-value-chip/inline-value-chip.component.d.ts +3 -7
- package/components/query-builder/index.d.ts +2 -0
- package/components/query-builder/src/query-builder.component.d.ts +98 -22
- package/components/query-builder/src/query-builder.model.d.ts +118 -0
- package/components/query-builder/src/query-builder.serializer.d.ts +32 -0
- package/components/section/src/section.component.d.ts +1 -2
- package/components/side-drawer/src/side-drawer.component.d.ts +1 -2
- package/components/stepper/src/stepper.component.d.ts +1 -2
- package/components/tab/src/tab-group.component.d.ts +1 -2
- package/components/table/src/components/config/config.component.d.ts +3 -1
- package/components/table/src/components/selector-action/selector-action.component.d.ts +3 -1
- package/components/table/src/models/table-option-tree.model.d.ts +96 -8
- package/components/table/src/services/tree/tree.util.d.ts +43 -2
- package/components/table/src/table.component.d.ts +1 -2
- package/components/upload-file/src/upload-file.component.d.ts +2 -0
- package/components/view/src/view.component.d.ts +33 -0
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs +97 -10
- package/fesm2022/sdcorejs-angular-components-autoid-inspector.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-avatar.mjs +2 -2
- package/fesm2022/sdcorejs-angular-components-avatar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-button.mjs +3 -5
- package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs +106 -197
- package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs +158 -0
- package/fesm2022/sdcorejs-angular-components-modal-resizable.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-components-operator.mjs +3 -1
- package/fesm2022/sdcorejs-angular-components-operator.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-preview.mjs +4 -4
- package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs +41 -87
- package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs +669 -57
- package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-section.mjs +2 -4
- package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +3 -5
- package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -4
- package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-tab.mjs +2 -4
- package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-table.mjs +235 -110
- package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -4
- package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components-view.mjs +43 -11
- package/fesm2022/sdcorejs-angular-components-view.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-components.mjs +1 -0
- package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +32 -7
- package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +9 -4
- package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +10 -5
- package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-chip.mjs +10 -5
- package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs +18 -9
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +20 -8
- package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs +20 -8
- package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs +167 -0
- package/fesm2022/sdcorejs-angular-forms-inline-text.mjs.map +1 -0
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs +5 -3
- package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs +41 -8
- package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-input.mjs +35 -9
- package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-models.mjs +32 -2
- package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-radio.mjs +9 -4
- package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-select.mjs +33 -9
- package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-switch.mjs +9 -4
- package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs +15 -5
- package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-i18n.mjs +20 -0
- package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs +1 -1
- package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-services-notify.mjs +40 -9
- package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
- package/forms/autocomplete/src/autocomplete.component.d.ts +16 -3
- package/forms/checkbox/src/checkbox.component.d.ts +5 -1
- package/forms/chip/src/chip.component.d.ts +5 -2
- package/forms/chip-calendar/src/chip-calendar.component.d.ts +5 -2
- package/forms/date/src/date.component.d.ts +14 -5
- package/forms/date-range/src/date-range.component.d.ts +12 -5
- package/forms/datetime/src/datetime.component.d.ts +14 -5
- package/forms/inline-text/index.d.ts +1 -0
- package/forms/inline-text/src/inline-text.component.d.ts +76 -0
- package/forms/input/src/input.component.d.ts +14 -2
- package/forms/input-color/src/input-color.component.d.ts +3 -1
- package/forms/input-number/src/input-number.component.d.ts +14 -2
- package/forms/models/index.d.ts +1 -0
- package/forms/models/src/sd-viewed.d.ts +38 -0
- package/forms/radio/src/radio.component.d.ts +5 -2
- package/forms/select/src/select.component.d.ts +23 -5
- package/forms/switch/src/switch.component.d.ts +5 -2
- package/forms/textarea/src/textarea.component.d.ts +9 -2
- package/i18n/src/en.d.ts +4 -0
- package/package.json +9 -1
- package/services/notify/src/components/toast/toast.component.d.ts +16 -1
- package/services/notify/src/notify.model.d.ts +17 -0
|
@@ -3,6 +3,7 @@ import { FormControl, FormGroup } from '@angular/forms';
|
|
|
3
3
|
import { MatDatepickerInputEvent, MatDateRangePicker } from '@angular/material/datepicker';
|
|
4
4
|
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field';
|
|
5
5
|
import { SdLabelDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
6
|
+
import { SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
6
7
|
import { Size } from '@sdcorejs/utils/models';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
8
9
|
interface Daterange {
|
|
@@ -37,10 +38,16 @@ export declare class SdDateRange implements OnDestroy, OnInit {
|
|
|
37
38
|
readonly errorMessage: import("@angular/core").Signal<string | undefined>;
|
|
38
39
|
required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
39
40
|
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
|
|
41
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (range picker). */
|
|
42
|
+
viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
43
|
+
/** In `viewed='inline'`, show a hover clear-× on the text face. Set `false` when the host owns removal (chips). */
|
|
44
|
+
clearable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
45
|
+
/** `true` when `viewed === 'inline'`. */
|
|
46
|
+
readonly isInline: import("@angular/core").Signal<boolean>;
|
|
47
|
+
/** `true` when `viewed === true` (static view, no editor). */
|
|
48
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
49
|
+
/** Open the range picker from the inline text face. No-op unless `viewed='inline'`. */
|
|
50
|
+
enterInlineEdit: () => void;
|
|
44
51
|
/** Optional <ng-template #sdValue> projected by consumer to override the viewed text. */
|
|
45
52
|
sdValueTemplate: import("@angular/core").Signal<TemplateRef<unknown> | undefined>;
|
|
46
53
|
/**
|
|
@@ -76,6 +83,6 @@ export declare class SdDateRange implements OnDestroy, OnInit {
|
|
|
76
83
|
onClosePicker: () => void;
|
|
77
84
|
onOpenPicker: (event: MouseEvent) => void;
|
|
78
85
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdDateRange, never>;
|
|
79
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SdDateRange, "sd-date-range", 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; }; "hideInlineError": { "alias": "hideInlineError"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "
|
|
86
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdDateRange, "sd-date-range", 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; }; "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; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; }, ["sdLabelDef", "sdValueTemplate"], never, true, never>;
|
|
80
87
|
}
|
|
81
88
|
export {};
|
|
@@ -2,7 +2,7 @@ import { ElementRef, OnDestroy, OnInit, TemplateRef } from '@angular/core';
|
|
|
2
2
|
import { FormGroup } from '@angular/forms';
|
|
3
3
|
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field';
|
|
4
4
|
import { SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
5
|
-
import { SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
5
|
+
import { SdFormControl, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
6
6
|
import { Size } from '@sdcorejs/utils/models';
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
8
|
export declare class SdDatetime implements OnDestroy, OnInit {
|
|
@@ -34,11 +34,20 @@ export declare class SdDatetime implements OnDestroy, OnInit {
|
|
|
34
34
|
hideInlineError: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
35
35
|
required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
36
36
|
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
37
|
-
|
|
37
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (datetime overlay). */
|
|
38
|
+
viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
38
39
|
/** Hiển thị thêm cột giây trong picker. Mặc định: chỉ HH:MM. */
|
|
39
40
|
showSeconds: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
40
|
-
/**
|
|
41
|
-
|
|
41
|
+
/** In `viewed='inline'`, show a hover clear-× on the text face. Set `false` when the host owns removal (chips). */
|
|
42
|
+
clearable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
43
|
+
/** `true` when `viewed === 'inline'`. */
|
|
44
|
+
readonly isInline: import("@angular/core").Signal<boolean>;
|
|
45
|
+
/** `true` when `viewed === true` (static view, no editor). */
|
|
46
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
47
|
+
/** Open the datetime overlay from the inline text face. No-op unless `viewed='inline'`. */
|
|
48
|
+
enterInlineEdit: () => void;
|
|
49
|
+
/** View display template: `sdViewDef` overrides the projected `#sdValue` (unified). */
|
|
50
|
+
readonly viewTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
42
51
|
inlineError: import("@angular/core").InputSignal<string | undefined>;
|
|
43
52
|
/**
|
|
44
53
|
* Tổng hợp error message để hiển thị trong tooltip khi hideInlineError = true.
|
|
@@ -85,5 +94,5 @@ export declare class SdDatetime implements OnDestroy, OnInit {
|
|
|
85
94
|
onConfirmInput: (event: any) => void;
|
|
86
95
|
clear: ($event: any) => void;
|
|
87
96
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdDatetime, never>;
|
|
88
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SdDatetime, "sd-datetime", 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; }; "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; }; "showSeconds": { "alias": "showSeconds"; "required": false; "isSignal": true; }; "
|
|
97
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdDatetime, "sd-datetime", 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; }; "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; }; "showSeconds": { "alias": "showSeconds"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "inlineError": { "alias": "inlineError"; "required": false; "isSignal": true; }; "hyperlink": { "alias": "hyperlink"; "required": false; "isSignal": true; }; "appearanceInput": { "alias": "appearance"; "required": false; "isSignal": true; }; "floatLabel": { "alias": "floatLabel"; "required": false; "isSignal": true; }; "minInput": { "alias": "min"; "required": false; "isSignal": true; }; "minDateInput": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxInput": { "alias": "max"; "required": false; "isSignal": true; }; "maxDateInput": { "alias": "maxDate"; "required": false; "isSignal": true; }; "valueModel": { "alias": "model"; "required": false; "isSignal": true; }; }, { "valueModel": "modelChange"; "sdChange": "sdChange"; "sdFocus": "sdFocus"; }, ["sdLabelTemplate", "sdValueTemplate", "sdViewDef"], ["[sdLabel]"], true, never>;
|
|
89
98
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/inline-text.component';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/** Visual / `data-state` of the inline input. `'auto'` derives from focus + value. */
|
|
4
|
+
export type SdInlineTextState = 'auto' | 'pending' | 'active' | 'focus' | 'error';
|
|
5
|
+
/** `'standalone'` draws its own affordance (hover bg + focus ring); `'seamless'` defers all chrome to the host. */
|
|
6
|
+
export type SdInlineTextChrome = 'standalone' | 'seamless';
|
|
7
|
+
/**
|
|
8
|
+
* Borderless, content-hugging text input — the seamless primitive shared by
|
|
9
|
+
* `sd-input` / `sd-input-number` (`viewed='inline'`) and the query-bar / query-builder chips.
|
|
10
|
+
*
|
|
11
|
+
* why: a native `<input>` inside `mat-form-field` cannot hug its content, so inline-edit
|
|
12
|
+
* looked like a full-width input rather than text. This primitive renders a raw `<input>`
|
|
13
|
+
* sized via the native `size` attribute (clamped) so the click/hover target tracks the value.
|
|
14
|
+
*
|
|
15
|
+
* It is intentionally unopinionated about commit/parse/format: it forwards the raw DOM events
|
|
16
|
+
* (focus / blur / keydown / paste / composition / Enter / Escape) so each consumer keeps its own
|
|
17
|
+
* logic (e.g. sd-input-number's vi-VN formatting). Two binding modes:
|
|
18
|
+
* - **uncontrolled** via `[(value)]` — used by the chips' signal drafts;
|
|
19
|
+
* - **controlled** via `[control]` (an external `SdFormControl`) — used by the form controls.
|
|
20
|
+
*/
|
|
21
|
+
export declare class SdInlineText {
|
|
22
|
+
/** Uncontrolled value (two-way). Ignored when `[control]` is provided. */
|
|
23
|
+
readonly value: import("@angular/core").ModelSignal<string>;
|
|
24
|
+
/** Optional external FormControl (controlled mode) — used by sd-input / sd-input-number. */
|
|
25
|
+
readonly control: import("@angular/core").InputSignal<SdFormControl | undefined>;
|
|
26
|
+
readonly placeholder: import("@angular/core").InputSignal<string>;
|
|
27
|
+
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
28
|
+
/** Show a hover/value-gated clear-× (default `true`). */
|
|
29
|
+
readonly clearable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
30
|
+
/** `'auto'` derives state from focus + value; pass an explicit value (e.g. `'error'`) to override. */
|
|
31
|
+
readonly state: import("@angular/core").InputSignal<SdInlineTextState>;
|
|
32
|
+
readonly chrome: import("@angular/core").InputSignal<SdInlineTextChrome>;
|
|
33
|
+
readonly autoId: import("@angular/core").InputSignal<string | undefined>;
|
|
34
|
+
readonly autofocus: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
35
|
+
/** Lower bound (chars) so short/empty values keep a clickable target. */
|
|
36
|
+
readonly minSize: import("@angular/core").InputSignal<number>;
|
|
37
|
+
readonly cleared: import("@angular/core").OutputEmitterRef<void>;
|
|
38
|
+
readonly keyupEnter: import("@angular/core").OutputEmitterRef<void>;
|
|
39
|
+
readonly keydownEscape: import("@angular/core").OutputEmitterRef<void>;
|
|
40
|
+
readonly sdFocus: import("@angular/core").OutputEmitterRef<FocusEvent>;
|
|
41
|
+
readonly sdBlur: import("@angular/core").OutputEmitterRef<FocusEvent>;
|
|
42
|
+
readonly sdKeydown: import("@angular/core").OutputEmitterRef<KeyboardEvent>;
|
|
43
|
+
readonly sdPaste: import("@angular/core").OutputEmitterRef<ClipboardEvent>;
|
|
44
|
+
readonly sdCompositionStart: import("@angular/core").OutputEmitterRef<CompositionEvent>;
|
|
45
|
+
readonly sdCompositionEnd: import("@angular/core").OutputEmitterRef<CompositionEvent>;
|
|
46
|
+
private readonly inputRef;
|
|
47
|
+
/** Bumped on input/blur/composition + bound-control changes so size/state methods re-eval under OnPush. */
|
|
48
|
+
protected readonly tick: import("@angular/core").WritableSignal<number>;
|
|
49
|
+
protected readonly focused: import("@angular/core").WritableSignal<boolean>;
|
|
50
|
+
constructor();
|
|
51
|
+
/**
|
|
52
|
+
* Current text — from the bound control in controlled mode, else the value model.
|
|
53
|
+
* why: `tick` is a tracked dependency so the computed re-runs when a bound control's
|
|
54
|
+
* value changes programmatically (control.value itself is not a signal).
|
|
55
|
+
*/
|
|
56
|
+
protected readonly currentText: import("@angular/core").Signal<string>;
|
|
57
|
+
protected readonly hasValue: import("@angular/core").Signal<boolean>;
|
|
58
|
+
protected readonly sizeOf: import("@angular/core").Signal<number>;
|
|
59
|
+
protected readonly showClear: import("@angular/core").Signal<boolean>;
|
|
60
|
+
protected readonly effectiveState: import("@angular/core").Signal<SdInlineTextState>;
|
|
61
|
+
protected onInput(ev: Event): void;
|
|
62
|
+
protected onFocus(ev: FocusEvent): void;
|
|
63
|
+
protected onBlur(ev: FocusEvent): void;
|
|
64
|
+
protected onKeyup(ev: KeyboardEvent): void;
|
|
65
|
+
protected onKeydown(ev: KeyboardEvent): void;
|
|
66
|
+
protected onPaste(ev: ClipboardEvent): void;
|
|
67
|
+
protected onCompositionStart(ev: CompositionEvent): void;
|
|
68
|
+
protected onCompositionEnd(ev: CompositionEvent): void;
|
|
69
|
+
protected clear(ev: Event): void;
|
|
70
|
+
/** Focus the native input. */
|
|
71
|
+
focus(): void;
|
|
72
|
+
/** Blur the native input. */
|
|
73
|
+
blur(): void;
|
|
74
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SdInlineText, never>;
|
|
75
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SdInlineText, "sd-inline-text", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "control": { "alias": "control"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "chrome": { "alias": "chrome"; "required": false; "isSignal": true; }; "autoId": { "alias": "autoId"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; "minSize": { "alias": "minSize"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "cleared": "cleared"; "keyupEnter": "keyupEnter"; "keydownEscape": "keydownEscape"; "sdFocus": "sdFocus"; "sdBlur": "sdBlur"; "sdKeydown": "sdKeydown"; "sdPaste": "sdPaste"; "sdCompositionStart": "sdCompositionStart"; "sdCompositionEnd": "sdCompositionEnd"; }, never, never, true, never>;
|
|
76
|
+
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { AfterViewInit, ElementRef, EventEmitter, OnDestroy, OnInit, TemplateRef } from '@angular/core';
|
|
2
2
|
import { FormGroup } from '@angular/forms';
|
|
3
3
|
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field';
|
|
4
|
+
import { SdInlineText } from '@sdcorejs/angular/forms/inline-text';
|
|
4
5
|
import { SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
5
|
-
import { SdCustomValidator, SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
6
|
+
import { SdCustomValidator, SdFormControl, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
6
7
|
import { Size } from '@sdcorejs/utils/models';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
8
9
|
export declare class SdInput implements OnDestroy, OnInit, AfterViewInit {
|
|
9
10
|
#private;
|
|
10
11
|
id: string;
|
|
11
12
|
control: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
13
|
+
/** The inline primitive — only present when `viewed='inline'`; drives focus/blur in that mode. */
|
|
14
|
+
inlineRef: import("@angular/core").Signal<SdInlineText | undefined>;
|
|
12
15
|
sdLabelTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
13
16
|
sdValueTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
14
17
|
sdSuffixDef: import("@angular/core").Signal<SdSuffixDefDirective | undefined>;
|
|
@@ -39,7 +42,16 @@ export declare class SdInput implements OnDestroy, OnInit, AfterViewInit {
|
|
|
39
42
|
required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
40
43
|
readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
41
44
|
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
42
|
-
|
|
45
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` borderless inline-edit (no panel — the input IS the face). */
|
|
46
|
+
viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
47
|
+
/** `true` when `viewed === 'inline'`. */
|
|
48
|
+
readonly isInline: import("@angular/core").Signal<boolean>;
|
|
49
|
+
/** `true` when `viewed === true` (static view, no input). */
|
|
50
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
51
|
+
/** Focus the inline input. No-op unless `viewed='inline'`. */
|
|
52
|
+
enterInlineEdit: () => void;
|
|
53
|
+
/** View display template: `sdViewDef` overrides the projected `#sdValue` for the static view (unified). */
|
|
54
|
+
readonly viewTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
43
55
|
minlength: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
44
56
|
maxlength: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
45
57
|
pattern: import("@angular/core").InputSignal<string | null | undefined>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ElementRef } from '@angular/core';
|
|
2
2
|
import { MatFormFieldAppearance } from '@angular/material/form-field';
|
|
3
|
+
import { SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
3
4
|
import { Size } from '@sdcorejs/utils/models';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
export declare const SD_INPUT_COLOR_HEX_PATTERN = "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$";
|
|
@@ -17,7 +18,8 @@ export declare class SdInputColor {
|
|
|
17
18
|
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
18
19
|
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
19
20
|
readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
20
|
-
|
|
21
|
+
/** Display mode — forwarded to the inner `<sd-input>`. `'inline'` = borderless inline-edit; disabled `'inline'` → static. */
|
|
22
|
+
readonly viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
21
23
|
readonly valueModel: import("@angular/core").ModelSignal<string | null | undefined>;
|
|
22
24
|
readonly sdChange: import("@angular/core").OutputEmitterRef<string | null | undefined>;
|
|
23
25
|
readonly picker: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
@@ -2,8 +2,9 @@ import { AfterViewInit, ElementRef, EventEmitter, OnDestroy, OnInit, TemplateRef
|
|
|
2
2
|
import { FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
|
|
3
3
|
import { ErrorStateMatcher } from '@angular/material/core';
|
|
4
4
|
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field';
|
|
5
|
+
import { SdInlineText } from '@sdcorejs/angular/forms/inline-text';
|
|
5
6
|
import { SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
6
|
-
import { SdCustomValidator, SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
7
|
+
import { SdCustomValidator, SdFormControl, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
7
8
|
import { Size } from '@sdcorejs/utils/models';
|
|
8
9
|
import * as i0 from "@angular/core";
|
|
9
10
|
declare class SdInputNumberErrotStateMatcher implements ErrorStateMatcher {
|
|
@@ -15,6 +16,8 @@ export declare class SdInputNumber implements OnDestroy, OnInit, AfterViewInit {
|
|
|
15
16
|
#private;
|
|
16
17
|
id: string;
|
|
17
18
|
control: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
19
|
+
/** The inline primitive — only present when `viewed='inline'`; drives focus/blur in that mode. */
|
|
20
|
+
inlineRef: import("@angular/core").Signal<SdInlineText | undefined>;
|
|
18
21
|
sdLabelTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
19
22
|
sdValueTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
20
23
|
sdViewDef: import("@angular/core").Signal<SdViewDefDirective<any, any> | undefined>;
|
|
@@ -42,7 +45,16 @@ export declare class SdInputNumber implements OnDestroy, OnInit, AfterViewInit {
|
|
|
42
45
|
required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
43
46
|
readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
44
47
|
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
45
|
-
|
|
48
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` borderless inline-edit (input IS the face). */
|
|
49
|
+
viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
50
|
+
/** `true` when `viewed === 'inline'`. */
|
|
51
|
+
readonly isInline: import("@angular/core").Signal<boolean>;
|
|
52
|
+
/** `true` when `viewed === true` (static view, no input). */
|
|
53
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
54
|
+
/** Focus the inline input. No-op unless `viewed='inline'`. */
|
|
55
|
+
enterInlineEdit: () => void;
|
|
56
|
+
/** View display template: `sdViewDef` overrides the projected `#sdValue` for the static view (unified). */
|
|
57
|
+
readonly viewTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
46
58
|
type: import("@angular/core").InputSignal<"negative" | "positive" | undefined>;
|
|
47
59
|
precision: import("@angular/core").InputSignal<number>;
|
|
48
60
|
format: import("@angular/core").InputSignal<"1,234,567.89" | "1.234.567,89" | undefined>;
|
package/forms/models/index.d.ts
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Signal } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Three display states shared by sd-form-controls:
|
|
4
|
+
* - `false` → full edit chrome (input / dropdown).
|
|
5
|
+
* - `true` → static read-only view (`<sd-view>` text), no editor.
|
|
6
|
+
* - `'inline'` → the editor is STILL rendered (so its panel works), but its chrome is
|
|
7
|
+
* hidden; the `<sd-view>` text is the visible face / trigger. Click the text to open
|
|
8
|
+
* the picker's panel. The text is retained while the panel is open — it only changes
|
|
9
|
+
* when a new value is committed (JIRA-style click-to-edit).
|
|
10
|
+
*/
|
|
11
|
+
export type SdViewed = boolean | 'inline';
|
|
12
|
+
export type SdViewedInput = SdViewed | '' | null | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* `viewed` input transform. Keeps `booleanAttribute` coercion so a bare attribute
|
|
15
|
+
* (`<sd-select viewed>`) still resolves to `true`, but intercepts the literal
|
|
16
|
+
* `'inline'` first — `booleanAttribute('inline')` would otherwise coerce it to `true`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function sdViewedTransform(v: SdViewedInput): SdViewed;
|
|
19
|
+
export interface SdViewedInlineApi {
|
|
20
|
+
/** `viewed() === 'inline'` — editor rendered but chrome hidden; sd-view text is the trigger face. */
|
|
21
|
+
readonly isInline: Signal<boolean>;
|
|
22
|
+
/** `viewed() === true` — static read-only view (no editor rendered). */
|
|
23
|
+
readonly isViewed: Signal<boolean>;
|
|
24
|
+
/** Open the picker from the inline text face. No-op unless `'inline'`. */
|
|
25
|
+
enterInlineEdit(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Compose the tri-state `viewed` semantics into a control. `open` opens the control's
|
|
29
|
+
* native picker (mat-select panel / mat-calendar / overlay). In `'inline'` mode the editor
|
|
30
|
+
* is always rendered (chrome hidden via CSS), so `open()` can fire immediately on click —
|
|
31
|
+
* no render-swap, the view text never disappears.
|
|
32
|
+
*
|
|
33
|
+
* @param viewed the control's `viewed` input signal.
|
|
34
|
+
* @param open opens the control's picker; called by `enterInlineEdit`.
|
|
35
|
+
* @param disabled the control's disabled state. why: a disabled `'inline'` field must behave
|
|
36
|
+
* like `viewed=true` (static, NOT click-to-edit) — you can't edit a disabled control.
|
|
37
|
+
*/
|
|
38
|
+
export declare function sdViewedInline(viewed: Signal<SdViewed>, open?: () => void, disabled?: Signal<boolean>): SdViewedInlineApi;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AfterViewInit, OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { FormGroup } from '@angular/forms';
|
|
3
3
|
import { SdLabelDefDirective, SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
4
|
-
import { SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
4
|
+
import { SdFormControl, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
5
5
|
import { Color } from '@sdcorejs/utils/models';
|
|
6
6
|
import * as i0 from "@angular/core";
|
|
7
7
|
export declare class SdRadio implements OnInit, AfterViewInit, OnDestroy {
|
|
@@ -20,7 +20,10 @@ export declare class SdRadio implements OnInit, AfterViewInit, OnDestroy {
|
|
|
20
20
|
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
21
21
|
readonly inlineError: import("@angular/core").InputSignalWithTransform<string | undefined, string | null | undefined>;
|
|
22
22
|
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
23
|
-
|
|
23
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` interactive (disabled `'inline'` → static). */
|
|
24
|
+
readonly viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
25
|
+
/** `true` when the static read-only view should render. */
|
|
26
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
24
27
|
readonly color: import("@angular/core").InputSignalWithTransform<Color, Color | null | undefined>;
|
|
25
28
|
readonly hyperlink: import("@angular/core").InputSignalWithTransform<string | undefined, string | null | undefined>;
|
|
26
29
|
readonly model: import("@angular/core").ModelSignal<string | number | boolean | null | undefined>;
|
|
@@ -5,7 +5,7 @@ import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-f
|
|
|
5
5
|
import { MatInput } from '@angular/material/input';
|
|
6
6
|
import { MatSelect, MatSelectChange } from '@angular/material/select';
|
|
7
7
|
import { SdItemDefDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
8
|
-
import { SdCustomValidator, SdFormControl, SdSearch, SdSelectionData } from '@sdcorejs/angular/forms/models';
|
|
8
|
+
import { SdCustomValidator, SdFormControl, SdSearch, SdSelectionData, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
9
9
|
import { Size } from '@sdcorejs/utils/models';
|
|
10
10
|
import * as i0 from "@angular/core";
|
|
11
11
|
export declare class SdSelect<T extends object | string | number = Record<string, unknown>> implements OnInit {
|
|
@@ -17,6 +17,13 @@ export declare class SdSelect<T extends object | string | number = Record<string
|
|
|
17
17
|
sdValueTemplate: Signal<TemplateRef<any> | undefined>;
|
|
18
18
|
itemDef: Signal<SdItemDefDefDirective<any> | undefined>;
|
|
19
19
|
sdViewDef: Signal<SdViewDefDirective<any, any> | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* View display template. `sdViewDef` is now just a custom override of the view rendering —
|
|
22
|
+
* it replaces the projected `#sdValue` template when present (fed into `<sd-view>`'s
|
|
23
|
+
* `valueTemplate`), so there is ONE rendering path. No more `.sd-view` class / focus-swap;
|
|
24
|
+
* click-to-edit is governed by `viewed='inline'`.
|
|
25
|
+
*/
|
|
26
|
+
readonly viewTemplate: Signal<TemplateRef<any> | undefined>;
|
|
20
27
|
autoIdInput: import("@angular/core").InputSignal<string | null | undefined>;
|
|
21
28
|
autoId: Signal<string | undefined>;
|
|
22
29
|
readonly dataDisabled: Signal<"true" | "false">;
|
|
@@ -42,10 +49,21 @@ export declare class SdSelect<T extends object | string | number = Record<string
|
|
|
42
49
|
hideInlineError: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
43
50
|
required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
44
51
|
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
45
|
-
|
|
52
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` view + click-to-edit (bare editor). */
|
|
53
|
+
viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
46
54
|
multiple: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
47
|
-
/**
|
|
48
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Whether the `viewed='inline'` text face shows a hover clear-× to empty the value.
|
|
57
|
+
* Default `true`. Set `false` where the HOST owns removal (e.g. `<sd-query-bar>` chips,
|
|
58
|
+
* whose own `×` removes the whole filter) so the chip isn't cluttered with two ×.
|
|
59
|
+
*/
|
|
60
|
+
clearable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
61
|
+
/** `true` when `viewed === 'inline'` — editor mounted but chrome hidden; sd-view text is the trigger face. */
|
|
62
|
+
readonly isInline: Signal<boolean>;
|
|
63
|
+
/** `true` when `viewed === true` — static read-only view, no editor mounted. */
|
|
64
|
+
readonly isViewed: Signal<boolean>;
|
|
65
|
+
/** Open the picker from the inline text face. No-op unless `viewed='inline'`. */
|
|
66
|
+
enterInlineEdit: () => void;
|
|
49
67
|
validator: import("@angular/core").InputSignal<SdCustomValidator | undefined>;
|
|
50
68
|
inlineError: import("@angular/core").InputSignal<string | undefined>;
|
|
51
69
|
/**
|
|
@@ -89,5 +107,5 @@ export declare class SdSelect<T extends object | string | number = Record<string
|
|
|
89
107
|
open: () => void;
|
|
90
108
|
onOpenedChange: (isOpened: boolean) => void;
|
|
91
109
|
static ɵfac: i0.ɵɵFactoryDeclaration<SdSelect<any>, never>;
|
|
92
|
-
static ɵcmp: i0.ɵɵ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": true; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": true; "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; }; "
|
|
110
|
+
static ɵcmp: i0.ɵɵ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": true; "isSignal": true; }; "displayField": { "alias": "displayField"; "required": true; "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; }; "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", "itemDef", "sdViewDef"], ["[sdLabel]"], true, never>;
|
|
93
111
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AfterViewInit, OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { FormGroup } from '@angular/forms';
|
|
3
|
-
import { SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
3
|
+
import { SdFormControl, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
4
4
|
import { Color } from '@sdcorejs/utils/models';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
export declare class SdSwitch implements OnInit, AfterViewInit, OnDestroy {
|
|
@@ -13,7 +13,10 @@ export declare class SdSwitch implements OnInit, AfterViewInit, OnDestroy {
|
|
|
13
13
|
readonly label: import("@angular/core").InputSignalWithTransform<string | undefined, string | null | undefined>;
|
|
14
14
|
readonly color: import("@angular/core").InputSignalWithTransform<Color, Color | null | undefined>;
|
|
15
15
|
readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
16
|
-
|
|
16
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` interactive (disabled `'inline'` → static). */
|
|
17
|
+
readonly viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
18
|
+
/** `true` when the static read-only view should render. */
|
|
19
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
17
20
|
readonly hideInlineError: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
18
21
|
readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
19
22
|
readonly model: import("@angular/core").ModelSignal<boolean | null | undefined>;
|
|
@@ -2,7 +2,7 @@ import { AfterViewInit, ElementRef, OnDestroy, OnInit } from '@angular/core';
|
|
|
2
2
|
import { FormGroup } from '@angular/forms';
|
|
3
3
|
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field';
|
|
4
4
|
import { SdLabelDefDirective, SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
5
|
-
import { SdCustomValidator, SdFormControl } from '@sdcorejs/angular/forms/models';
|
|
5
|
+
import { SdCustomValidator, SdFormControl, SdViewed, SdViewedInput } from '@sdcorejs/angular/forms/models';
|
|
6
6
|
import { Size } from '@sdcorejs/utils/models';
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
8
|
export declare class SdTextarea implements OnInit, AfterViewInit, OnDestroy {
|
|
@@ -32,8 +32,15 @@ export declare class SdTextarea implements OnInit, AfterViewInit, OnDestroy {
|
|
|
32
32
|
hideInlineError: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
33
33
|
required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
34
34
|
disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
35
|
-
|
|
35
|
+
/** Display mode: `false` edit · `true` static view · `'inline'` borderless inline-edit (textarea reads like text). */
|
|
36
|
+
viewed: import("@angular/core").InputSignalWithTransform<SdViewed, SdViewedInput>;
|
|
36
37
|
autoHeight: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
|
|
38
|
+
/** `true` when `viewed === 'inline'`. */
|
|
39
|
+
readonly isInline: import("@angular/core").Signal<boolean>;
|
|
40
|
+
/** `true` when `viewed === true` (static view, no editor). */
|
|
41
|
+
readonly isViewed: import("@angular/core").Signal<boolean>;
|
|
42
|
+
/** Focus the inline textarea. No-op unless `viewed='inline'`. */
|
|
43
|
+
enterInlineEdit: () => void;
|
|
37
44
|
maxlength: import("@angular/core").InputSignalWithTransform<number | null, unknown>;
|
|
38
45
|
pattern: import("@angular/core").InputSignalWithTransform<string | undefined, string | null | undefined>;
|
|
39
46
|
validator: import("@angular/core").InputSignal<SdCustomValidator | undefined>;
|
package/i18n/src/en.d.ts
CHANGED
|
@@ -62,7 +62,9 @@ export declare const EN_MESSAGES: {
|
|
|
62
62
|
readonly 'core.operator.contain.display': "Contains";
|
|
63
63
|
readonly 'core.operator.not-contain.display': "Does not contain";
|
|
64
64
|
readonly 'core.operator.start-with.display': "Starts with";
|
|
65
|
+
readonly 'core.operator.not-start-with.display': "Does not start with";
|
|
65
66
|
readonly 'core.operator.end-with.display': "Ends with";
|
|
67
|
+
readonly 'core.operator.not-end-with.display': "Does not end with";
|
|
66
68
|
readonly 'core.operator.in.display': "In";
|
|
67
69
|
readonly 'core.operator.not-in.display': "Not in";
|
|
68
70
|
readonly 'core.operator.between.display': "Between";
|
|
@@ -262,6 +264,8 @@ export declare const EN_MESSAGES: {
|
|
|
262
264
|
readonly 'core.component.form-builder.empty-hint': "Build your form by dragging fields from the left panel, or press";
|
|
263
265
|
readonly 'core.component.form-builder.conditional': "Conditional";
|
|
264
266
|
readonly 'core.component.form-builder.group-drop-here': "Drop a field here to add it to this group";
|
|
267
|
+
readonly 'core.component.form-builder.edit-group': "Edit group";
|
|
268
|
+
readonly 'core.component.form-builder.group-empty-hint': "Click Details to add fields to this group";
|
|
265
269
|
readonly 'core.component.form-builder.hidden': "Hidden";
|
|
266
270
|
readonly 'core.component.form-builder.read-only': "Read only";
|
|
267
271
|
readonly 'core.component.form-builder.untitled': "Untitled";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdcorejs/angular",
|
|
3
|
-
"version": "19.0.
|
|
3
|
+
"version": "19.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
@@ -149,6 +149,10 @@
|
|
|
149
149
|
"types": "./components/modal/index.d.ts",
|
|
150
150
|
"default": "./fesm2022/sdcorejs-angular-components-modal.mjs"
|
|
151
151
|
},
|
|
152
|
+
"./components/modal-resizable": {
|
|
153
|
+
"types": "./components/modal-resizable/index.d.ts",
|
|
154
|
+
"default": "./fesm2022/sdcorejs-angular-components-modal-resizable.mjs"
|
|
155
|
+
},
|
|
152
156
|
"./components/operator": {
|
|
153
157
|
"types": "./components/operator/index.d.ts",
|
|
154
158
|
"default": "./fesm2022/sdcorejs-angular-components-operator.mjs"
|
|
@@ -237,6 +241,10 @@
|
|
|
237
241
|
"types": "./forms/directives/index.d.ts",
|
|
238
242
|
"default": "./fesm2022/sdcorejs-angular-forms-directives.mjs"
|
|
239
243
|
},
|
|
244
|
+
"./forms/inline-text": {
|
|
245
|
+
"types": "./forms/inline-text/index.d.ts",
|
|
246
|
+
"default": "./fesm2022/sdcorejs-angular-forms-inline-text.mjs"
|
|
247
|
+
},
|
|
240
248
|
"./forms/input": {
|
|
241
249
|
"types": "./forms/input/index.d.ts",
|
|
242
250
|
"default": "./fesm2022/sdcorejs-angular-forms-input.mjs"
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import { OnInit, OnDestroy } from '@angular/core';
|
|
2
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
2
3
|
import { ToastData } from '../../notify.model';
|
|
3
4
|
import { SdNotifyService } from '../../notify.service';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
export declare class ToastComponent implements OnInit, OnDestroy {
|
|
6
7
|
private notifyService;
|
|
8
|
+
private sanitizer;
|
|
7
9
|
data: ToastData;
|
|
8
10
|
isExpanded: import("@angular/core").WritableSignal<boolean>;
|
|
9
11
|
readonly MAX_SHOW = 2;
|
|
10
12
|
private timer;
|
|
11
13
|
private start;
|
|
12
14
|
private remaining;
|
|
13
|
-
constructor(notifyService: SdNotifyService);
|
|
15
|
+
constructor(notifyService: SdNotifyService, sanitizer: DomSanitizer);
|
|
16
|
+
/**
|
|
17
|
+
* Sanitize HTML tường minh trước khi render qua `[innerHTML]` — strip
|
|
18
|
+
* `<script>`, event handler (`on*`), `javascript:` URL. Chỉ chạy ở nhánh
|
|
19
|
+
* `data.html === true`; nhánh mặc định render text (auto-escape) nên không
|
|
20
|
+
* có sink này. // why: phơi rõ việc sanitize cho review/scanner bảo mật.
|
|
21
|
+
*/
|
|
22
|
+
sanitizeHtml(value: string): string;
|
|
23
|
+
/** Message ở dạng chuỗi đơn (chỉ dùng khi !isMultiMessage). */
|
|
24
|
+
get singleMessage(): string;
|
|
14
25
|
ngOnInit(): void;
|
|
15
26
|
ngOnDestroy(): void;
|
|
16
27
|
pauseTimer(): void;
|
|
@@ -23,6 +34,10 @@ export declare class ToastComponent implements OnInit, OnDestroy {
|
|
|
23
34
|
get displayMessages(): string[];
|
|
24
35
|
get restCount(): number;
|
|
25
36
|
get hasMore(): boolean;
|
|
37
|
+
/** autoid theo loại toast để E2E chọn trực tiếp, vd `services-notify-toast-success`. */
|
|
38
|
+
get autoId(): string;
|
|
39
|
+
/** Gộp message (mảng nối ' | ') để phơi ra data-message cho E2E. */
|
|
40
|
+
get dataMessage(): string;
|
|
26
41
|
static ɵfac: i0.ɵɵFactoryDeclaration<ToastComponent, never>;
|
|
27
42
|
static ɵcmp: i0.ɵɵComponentDeclaration<ToastComponent, "toast", never, { "data": { "alias": "data"; "required": true; }; }, {}, never, never, true, never>;
|
|
28
43
|
}
|
|
@@ -7,10 +7,27 @@ export interface ToastData {
|
|
|
7
7
|
duration: number;
|
|
8
8
|
actionLabel?: string;
|
|
9
9
|
onAction?: () => void;
|
|
10
|
+
/**
|
|
11
|
+
* Render `message` dưới dạng HTML thay vì text.
|
|
12
|
+
* - `false` (mặc định): message render dạng TEXT (auto-escape) — an toàn tuyệt đối.
|
|
13
|
+
* - `true`: message render dạng HTML, đã được `DomSanitizer.sanitize(HTML)`
|
|
14
|
+
* (strip `<script>`, event handler, `javascript:` URL). CHỈ dùng cho markup
|
|
15
|
+
* TIN CẬY (do dev tự viết); KHÔNG truyền data người dùng vào đây.
|
|
16
|
+
*/
|
|
17
|
+
html?: boolean;
|
|
10
18
|
}
|
|
11
19
|
export interface NotifyOption {
|
|
12
20
|
duration?: number;
|
|
13
21
|
title?: string;
|
|
14
22
|
actionLabel?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Callback khi bấm nút action — do APP tự cung cấp (không phải input không tin cậy).
|
|
25
|
+
* Chỉ được gọi khi user bấm `actionLabel`.
|
|
26
|
+
*/
|
|
15
27
|
onAction?: () => void;
|
|
28
|
+
/**
|
|
29
|
+
* Render message dạng HTML đã sanitize (mặc định `false` = text an toàn).
|
|
30
|
+
* Chỉ dùng cho markup tin cậy. Xem `ToastData.html`.
|
|
31
|
+
*/
|
|
32
|
+
html?: boolean;
|
|
16
33
|
}
|