@sdcorejs/angular 20.1.6 → 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 +10 -0
- 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 +251 -109
- 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 +27 -17
- 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 +542 -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 +232 -61
- package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
- package/fesm2022/sdcorejs-angular-forms-date.mjs +96 -24
- 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 +227 -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 +490 -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 +332 -111
- 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 +13 -2
- 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 +119 -4
- 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 +95 -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 +94 -28
- package/modules/permission/index.d.ts +66 -4
- package/package.json +32 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdcorejs-angular-forms-models.mjs","sources":["../../../projects/sdcorejs-angular/forms/models/src/sd-form.configuration.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-form-control.model.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-custom-validator.model.ts","../../../projects/sdcorejs-angular/forms/models/src/form-control-state.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-viewed.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-form-control-connector.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-strict-date-adapter.ts","../../../projects/sdcorejs-angular/forms/models/sdcorejs-angular-forms-models.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { MatFormFieldAppearance } from '@angular/material/form-field';\n\nexport interface ISdFormConfiguration {\n appearance?: MatFormFieldAppearance;\n}\n\nexport const SD_FORM_CONFIGURATION = new InjectionToken<ISdFormConfiguration>('sd.form.configuration');\n","import { FormControl, AsyncValidatorFn, ValidatorFn, FormControlOptions, FormControlState } from '@angular/forms';\nimport { Subject } from 'rxjs';\n\nexport class SdFormControl extends FormControl {\n sdChanges: Subject<boolean> = new Subject<boolean>();\n untouchChanges: Subject<boolean> = new Subject<boolean>();\n touchChanges: Subject<boolean> = new Subject<boolean>();\n pristineChanges: Subject<boolean> = new Subject<boolean>();\n constructor(\n formState?: FormControlState<any>,\n validatorOrOpts?: ValidatorFn | ValidatorFn[] | FormControlOptions | null,\n asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null\n ) {\n super(formState, validatorOrOpts, asyncValidator);\n }\n\n override markAsUntouched(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void {\n super.markAsUntouched(opts);\n this.untouchChanges.next(true);\n this.sdChanges.next(true);\n }\n\n override markAsTouched(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void {\n super.markAsTouched(opts);\n this.touchChanges.next(true);\n this.sdChanges.next(true);\n }\n\n override markAsPristine(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void {\n super.markAsPristine(opts);\n this.pristineChanges.next(true);\n this.sdChanges.next(true);\n }\n}\n","import { AbstractControl, AsyncValidatorFn, ValidatorFn } from '@angular/forms';\n\nexport type SdCustomValidator = (value: any) => string | Promise<string>;\n\n/**\n * Inline-error sentinel validator. Returns `{ inlineError: true }` so the form\n * template can render `<mat-error>{{ inlineError }}</mat-error>` whenever the\n * host component has a non-empty `[inlineError]` input. The error message\n * itself is read from the input — this validator only flags the state.\n *\n * why: each form component (input, textarea, select, checkbox, radio, switch,\n * date, datetime, input-number, autocomplete) previously declared the same\n * private `customInlineErrorValidator()` method. Centralized here so adding\n * another form component does not silently re-introduce the duplicate.\n */\nexport const SdInlineErrorValidator: ValidatorFn = (): Record<string, unknown> | null => ({ inlineError: true });\n\nexport const HandleSdCustomValidator = (func: SdCustomValidator): AsyncValidatorFn => {\n return async (c: AbstractControl): Promise<Record<string, any> | null> => {\n const value = c.value === 0 ? c.value : c.value || null;\n if (func && typeof func === 'function') {\n const result = func(value);\n if (result instanceof Promise) {\n const message = await result;\n if (message) {\n return {\n customValidator: message,\n };\n }\n return null;\n }\n if (result) {\n return {\n customValidator: result,\n };\n }\n return null;\n }\n return null;\n };\n};\n","import { DestroyRef, EffectRef, Signal, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { startWith } from 'rxjs/operators';\n\nexport interface SdFormControlSnapshot<T> {\n value: T | undefined;\n disabled: boolean;\n invalid: boolean;\n touched: boolean;\n}\n\n/**\n * Wrap an AbstractControl Signal into a reactive snapshot signal.\n *\n * Re-emits on every value, status, touched, or dirty change so\n * downstream consumers can derive `data-disabled`, `data-value`,\n * `data-empty`, and `data-invalid` host-binding attributes from a\n * single, lazily evaluated signal.\n *\n * \"invalid\" is intentionally gated on `touched || dirty` so validation\n * errors are not surfaced until the user has interacted with the field.\n *\n * Must be called inside an Angular injection context (constructor,\n * field initialiser, or `runInInjectionContext`).\n */\nexport function sdFormControlState<T = unknown>(control: Signal<AbstractControl<T> | null | undefined>): Signal<SdFormControlSnapshot<T>> {\n // A tick counter incremented on every control event (value, status,\n // touched, dirty). Written only from the effect below — never inside\n // a computed() — satisfying Angular's no-side-effect-in-reactive rule.\n const tick = signal(0);\n const destroyRef = inject(DestroyRef);\n\n // Holds the active RxJS subscription so it can be torn down when the\n // control instance changes or the host component is destroyed.\n let subscription: Subscription | null = null;\n\n // An effect re-runs whenever the control Signal changes, tears down the\n // old subscription and creates a fresh one for the incoming control.\n // `AbstractControl.events` (Angular 14+) covers value, status, touched,\n // and dirty changes — a superset of valueChanges + statusChanges.\n const effectRef: EffectRef = effect(() => {\n const c = control(); // tracked — effect re-runs on change\n // effect() runs asynchronously; the old subscription is torn down on the next\n // scheduled run, not synchronously on signal change. A one-tick window of\n // double-subscription is harmless due to computed() memoization.\n subscription?.unsubscribe();\n subscription = null;\n\n if (c) {\n subscription = c.events.pipe(startWith(null)).subscribe(() => {\n // Increment outside reactive context to avoid Angular's\n // \"signal written from computed / template\" error.\n untracked(() => tick.update(n => n + 1));\n });\n }\n });\n\n // Clean up effect and subscription when host component is destroyed.\n destroyRef.onDestroy(() => {\n effectRef.destroy();\n subscription?.unsubscribe();\n });\n\n return computed((): SdFormControlSnapshot<T> => {\n const _control = control();\n tick(); // reactive dependency — recomputes on every control event\n\n if (!_control) {\n return { value: undefined, disabled: false, invalid: false, touched: false };\n }\n\n return {\n value: _control.value as T,\n disabled: _control.disabled,\n invalid: _control.invalid && (_control.touched || _control.dirty),\n touched: _control.touched,\n };\n });\n}\n","import { booleanAttribute, computed, Signal } from '@angular/core';\n\n/**\n * Three display states shared by sd-form-controls:\n * - `false` → full edit chrome (input / dropdown).\n * - `true` → static read-only view (`<sd-view>` text), no editor.\n * - `'inline'` → the editor is STILL rendered (so its panel works), but its chrome is\n * hidden; the `<sd-view>` text is the visible face / trigger. Click the text to open\n * the picker's panel. The text is retained while the panel is open — it only changes\n * when a new value is committed (JIRA-style click-to-edit).\n */\nexport type SdViewed = boolean | 'inline';\nexport type SdViewedInput = SdViewed | '' | null | undefined;\n\n/**\n * `viewed` input transform. Keeps `booleanAttribute` coercion so a bare attribute\n * (`<sd-select viewed>`) still resolves to `true`, but intercepts the literal\n * `'inline'` first — `booleanAttribute('inline')` would otherwise coerce it to `true`.\n */\nexport function sdViewedTransform(v: SdViewedInput): SdViewed {\n return v === 'inline' ? 'inline' : booleanAttribute(v);\n}\n\nexport interface SdViewedInlineApi {\n /** `viewed() === 'inline'` — editor rendered but chrome hidden; sd-view text is the trigger face. */\n readonly isInline: Signal<boolean>;\n /** `viewed() === true` — static read-only view (no editor rendered). */\n readonly isViewed: Signal<boolean>;\n /** Open the picker from the inline text face. No-op unless `'inline'`. */\n enterInlineEdit(): void;\n}\n\n/**\n * Compose the tri-state `viewed` semantics into a control. `open` opens the control's\n * native picker (mat-select panel / mat-calendar / overlay). In `'inline'` mode the editor\n * is always rendered (chrome hidden via CSS), so `open()` can fire immediately on click —\n * no render-swap, the view text never disappears.\n *\n * @param viewed the control's `viewed` input signal.\n * @param open opens the control's picker; called by `enterInlineEdit`.\n * @param disabled the control's disabled state. why: a disabled `'inline'` field must behave\n * like `viewed=true` (static, NOT click-to-edit) — you can't edit a disabled control.\n */\nexport function sdViewedInline(viewed: Signal<SdViewed>, open?: () => void, disabled?: Signal<boolean>): SdViewedInlineApi {\n // why: disabled biến 'inline' thành static view (isInline=false, isViewed=true) — không cho sửa.\n const isInline = computed(() => viewed() === 'inline' && !disabled?.());\n const isViewed = computed(() => viewed() === true || (viewed() === 'inline' && !!disabled?.()));\n const enterInlineEdit = (): void => {\n if (isInline()) open?.();\n };\n return { isInline, isViewed, enterInlineEdit };\n}\n","import { Signal, computed, effect, untracked } from '@angular/core';\nimport { AbstractControl, AsyncValidatorFn, FormGroup, NgForm, ValidatorFn, Validators } from '@angular/forms';\n\nimport { sdFormControlState } from './form-control-state';\nimport { SdViewed } from './sd-viewed';\n\nexport type ɵSdFormControlParent = FormGroup | NgForm | { readonly form: unknown } | null | undefined;\n\ninterface ɵSdFormControlConnectorBaseOptions<TControl> {\n /** Parent form source. NgForm and wrapper values are unwrapped on every rebind. */\n readonly form: Signal<ɵSdFormControlParent>;\n /** Registration name. Empty names intentionally leave the control unregistered. */\n readonly name: Signal<string | null | undefined>;\n /** Canonical control registered in the parent form. */\n readonly control: Signal<AbstractControl<TControl>>;\n readonly validators?: Signal<ValidatorFn | readonly ValidatorFn[] | null | undefined>;\n readonly asyncValidators?: Signal<AsyncValidatorFn | readonly AsyncValidatorFn[] | null | undefined>;\n /** Adds/removes Validators.required while preserving validators supplied above. */\n readonly required?: Signal<boolean | null | undefined>;\n readonly disabled?: Signal<boolean | null | undefined>;\n /** UI-only read-only policy. This never disables the Angular control. */\n readonly readonly?: Signal<boolean | null | undefined>;\n /** Exact SDCoreJS display policy. This never disables the Angular control. */\n readonly viewed?: Signal<SdViewed | null | undefined>;\n /** Component-local validation message. Visibility is interaction-gated in state. */\n readonly validationError?: Signal<string | null | undefined>;\n}\n\ninterface ɵSdFormControlRegistrationOptions<TControl> extends ɵSdFormControlConnectorBaseOptions<TControl> {\n readonly model?: never;\n readonly writeModel?: never;\n readonly modelToControl?: never;\n readonly controlToModel?: never;\n readonly modelEquals?: never;\n readonly controlEquals?: never;\n}\n\ninterface ɵSdFormControlIdentityOptions<TValue> extends ɵSdFormControlConnectorBaseOptions<TValue> {\n readonly model: Signal<TValue>;\n readonly writeModel: (value: TValue) => void;\n readonly modelToControl?: never;\n readonly controlToModel?: never;\n readonly modelEquals?: (left: TValue, right: TValue) => boolean;\n readonly controlEquals?: (left: TValue, right: TValue) => boolean;\n}\n\ninterface ɵSdFormControlAdaptedOptions<TModel, TControl> extends ɵSdFormControlConnectorBaseOptions<TControl> {\n readonly model: Signal<TModel>;\n readonly writeModel: (value: TModel) => void;\n readonly modelToControl: (value: TModel) => TControl;\n readonly controlToModel: (value: TControl) => TModel;\n readonly modelEquals?: (left: TModel, right: TModel) => boolean;\n readonly controlEquals?: (left: TControl, right: TControl) => boolean;\n}\n\ntype ɵSdTypesExactlyMatch<TLeft, TRight> = [TLeft] extends [TRight] ? ([TRight] extends [TLeft] ? true : false) : false;\n\n/**\n * @internal Unstable connector contract for cross-entrypoint SDCoreJS controls.\n * Consumers must use registration-only, same-type identity binding, or provide\n * both adapters when model and control representations differ.\n */\nexport type ɵSdFormControlConnectorOptions<TModel, TControl> =\n | ɵSdFormControlRegistrationOptions<TControl>\n | ɵSdFormControlAdaptedOptions<TModel, TControl>\n | (ɵSdTypesExactlyMatch<TModel, TControl> extends true ? ɵSdFormControlIdentityOptions<TModel> : never);\n\ntype ɵSdFormControlBindingOptions<TModel, TControl> =\n | ɵSdFormControlIdentityOptions<TControl>\n | ɵSdFormControlAdaptedOptions<TModel, TControl>;\n\ntype ɵSdFormControlImplementationOptions<TModel, TControl> =\n | ɵSdFormControlRegistrationOptions<TControl>\n | ɵSdFormControlBindingOptions<TModel, TControl>;\n\nexport interface ɵSdFormControlConnectorState<TControl> {\n readonly value: TControl | undefined;\n readonly disabled: boolean;\n readonly invalid: boolean;\n readonly touched: boolean;\n readonly dirty: boolean;\n readonly required: boolean;\n readonly readonly: boolean;\n readonly viewed: SdViewed;\n readonly isViewed: boolean;\n readonly isInline: boolean;\n readonly showValidationError: boolean;\n readonly validationError: string | undefined;\n}\n\nexport interface ɵSdFormControlConnector<TControl = unknown> {\n readonly state: Signal<ɵSdFormControlConnectorState<TControl>>;\n markAsTouched(): void;\n markAsUntouched(): void;\n markAsDirty(): void;\n markAsPristine(): void;\n}\n\n/** Coerces the form shapes accepted by SDCoreJS controls into one FormGroup. */\nexport function ɵsdCoerceFormGroup(value: unknown): FormGroup | undefined {\n if (value instanceof NgForm) return value.form;\n if (value instanceof FormGroup) return value;\n if (typeof value !== 'object' || value === null || !('form' in value)) return undefined;\n\n const wrappedForm = (value as { readonly form: unknown }).form;\n return wrappedForm instanceof FormGroup ? wrappedForm : undefined;\n}\n\nfunction normalizeValidatorList<TValidator extends ValidatorFn | AsyncValidatorFn>(\n value: TValidator | readonly TValidator[] | null | undefined\n): TValidator[] {\n if (!value) return [];\n return typeof value === 'function' ? [value] : [...value];\n}\n\nfunction hasModelBinding<TModel, TControl>(\n options: ɵSdFormControlImplementationOptions<TModel, TControl>\n): options is ɵSdFormControlBindingOptions<TModel, TControl> {\n return options.model !== undefined && options.writeModel !== undefined;\n}\n\nfunction readControlValue<TModel, TControl>(options: ɵSdFormControlBindingOptions<TModel, TControl>): TControl {\n if (options.modelToControl) return options.modelToControl(options.model());\n return options.model();\n}\n\nfunction writeModelValue<TModel, TControl>(options: ɵSdFormControlBindingOptions<TModel, TControl>, controlValue: TControl): void {\n if (options.controlToModel) {\n const modelValue = options.controlToModel(controlValue);\n if (!(options.modelEquals ?? Object.is)(options.model(), modelValue)) options.writeModel(modelValue);\n return;\n }\n\n if (!(options.modelEquals ?? Object.is)(options.model(), controlValue)) options.writeModel(controlValue);\n}\n\n/**\n * Connects the signal-based SDCoreJS model contract to an Angular control.\n * Registration and subscriptions are rebound transactionally, and cleanup only\n * removes a control while the connector still owns that exact registration.\n */\nexport function ɵsdFormControlConnector<TModel, TControl>(\n options: ɵSdFormControlConnectorOptions<TModel, TControl>\n): ɵSdFormControlConnector<TControl>;\nexport function ɵsdFormControlConnector<TModel, TControl>(\n options: ɵSdFormControlImplementationOptions<TModel, TControl>\n): ɵSdFormControlConnector<TControl> {\n const controlEquals = options.controlEquals ?? Object.is;\n const controlState = sdFormControlState(options.control);\n const state = computed((): ɵSdFormControlConnectorState<TControl> => {\n const snapshot = controlState();\n const required = !!options.required?.();\n const readonly = !!options.readonly?.();\n const viewed = options.viewed?.() ?? false;\n const validationError = options.validationError?.() || undefined;\n const showValidationError = snapshot.invalid && validationError !== undefined;\n\n return {\n ...snapshot,\n dirty: options.control().dirty,\n required,\n readonly,\n viewed,\n isViewed: viewed === true,\n isInline: viewed === 'inline',\n showValidationError,\n validationError: showValidationError ? validationError : undefined,\n };\n });\n\n effect(onCleanup => {\n const formGroup = ɵsdCoerceFormGroup(options.form());\n const name = options.name();\n const control = options.control();\n\n if (!formGroup || !name) return;\n\n const current = formGroup.get(name);\n const ownsRegistration = !current;\n if (ownsRegistration) formGroup.addControl(name, control);\n\n onCleanup(() => {\n if (ownsRegistration && formGroup.get(name) === control) formGroup.removeControl(name);\n });\n });\n\n if (hasModelBinding(options)) {\n effect(() => {\n const control = options.control();\n const controlValue = readControlValue(options);\n\n untracked(() => {\n if (!controlEquals(control.value, controlValue)) {\n control.setValue(controlValue, { emitEvent: false });\n }\n });\n });\n }\n\n if (hasModelBinding(options)) {\n effect(onCleanup => {\n const control = options.control();\n const subscription = control.valueChanges.subscribe(controlValue => {\n writeModelValue(options, controlValue);\n });\n onCleanup(() => subscription.unsubscribe());\n });\n }\n\n if (options.validators || options.asyncValidators || options.required) {\n effect(onCleanup => {\n const control = options.control();\n const requestedValidators = normalizeValidatorList(options.validators?.());\n if (options.required?.()) requestedValidators.push(Validators.required);\n const validatorsToAdd = [...new Set(requestedValidators)].filter(validator => !control.hasValidator(validator));\n const asyncValidatorsToAdd = [...new Set(normalizeValidatorList(options.asyncValidators?.()))].filter(\n validator => !control.hasAsyncValidator(validator)\n );\n\n untracked(() => {\n if (validatorsToAdd.length > 0) control.addValidators(validatorsToAdd);\n if (asyncValidatorsToAdd.length > 0) control.addAsyncValidators(asyncValidatorsToAdd);\n control.updateValueAndValidity({ emitEvent: false });\n });\n\n onCleanup(() => {\n untracked(() => {\n if (validatorsToAdd.length > 0) control.removeValidators(validatorsToAdd);\n if (asyncValidatorsToAdd.length > 0) control.removeAsyncValidators(asyncValidatorsToAdd);\n control.updateValueAndValidity({ emitEvent: false });\n });\n });\n });\n }\n\n if (options.disabled) {\n effect(onCleanup => {\n const control = options.control();\n const disabled = !!options.disabled!();\n const previousDisabled = control.disabled;\n let appliedDisabled: boolean | undefined;\n\n untracked(() => {\n if (disabled !== control.disabled) {\n appliedDisabled = disabled;\n if (disabled) control.disable({ emitEvent: false });\n else control.enable({ emitEvent: false });\n }\n });\n\n onCleanup(() => {\n if (appliedDisabled === undefined || control.disabled !== appliedDisabled) return;\n\n untracked(() => {\n if (previousDisabled) control.disable({ emitEvent: false });\n else control.enable({ emitEvent: false });\n });\n });\n });\n }\n\n return {\n state,\n markAsTouched: () => options.control().markAsTouched(),\n markAsUntouched: () => options.control().markAsUntouched(),\n markAsDirty: () => options.control().markAsDirty(),\n markAsPristine: () => options.control().markAsPristine(),\n };\n}\n","import { Injectable, Provider } from '@angular/core';\nimport { DateFnsAdapter, provideDateFnsAdapter } from '@angular/material-date-fns-adapter';\nimport { DateAdapter, MatDateFormats } from '@angular/material/core';\nimport { isValid as isValidDate, parse as parseDate } from 'date-fns';\n\n/**\n * DateAdapter từ chối mọi chuỗi người dùng chưa gõ xong.\n *\n * WHY cần đến mức này: `<input matInput [matDatepicker]>` khiến Material tự\n * `parse()` lại ô nhập SAU MỖI PHÍM GÕ rồi ghi thẳng kết quả vào form control.\n * Adapter mặc định quá dễ dãi trên hai đường:\n *\n * 1. `date-fns.parse` nhận năm thiếu chữ số → `11/12/2` thành năm 0002,\n * `11/12/20` thành năm 0020. Ô nhập vừa gõ dở đã bị coi là hợp lệ (cờ lỗi\n * bị xoá) và control ôm một ngày rác.\n * 2. `parseISO` coi chuỗi 2 chữ số là thế kỷ → xoá lùi còn `11` ra năm 1100.\n *\n * Cả hai đường đều bị chặn ở đây: control chỉ nhận giá trị khi người dùng thực\n * sự gõ xong.\n */\n@Injectable()\nexport class SdStrictDateFnsAdapter extends DateFnsAdapter {\n override parse(value: unknown, parseFormat: string | string[]): Date | null {\n if (typeof value !== 'string') return super.parse(value, parseFormat);\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n // Cố tình KHÔNG gọi super.parse: chỗ đó có ISO fallback (đường số 2 ở trên).\n for (const currentFormat of Array.isArray(parseFormat) ? parseFormat : [parseFormat]) {\n const parsed = parseDate(trimmed, currentFormat, new Date(), { locale: this.locale });\n if (!isValidDate(parsed)) continue;\n // Round-trip: chuỗi phải khớp 1-1 với format, nên năm thiếu chữ số bị loại.\n if (this.format(parsed, currentFormat) === trimmed) return parsed;\n }\n\n return null;\n }\n}\n\n/** `provideDateFnsAdapter` + ép dùng adapter parse chặt ở trên. */\nexport function provideSdStrictDateFnsAdapter(formats: MatDateFormats): Provider[] {\n return [\n provideDateFnsAdapter(formats),\n // Phải đứng SAU provideDateFnsAdapter để ghi đè DateAdapter mà nó đăng ký.\n { provide: DateAdapter, useClass: SdStrictDateFnsAdapter },\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["parseDate","isValidDate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sdcorejs-angular-forms-models.mjs","sources":["../../../projects/sdcorejs-angular/forms/models/src/sd-form.configuration.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-form-control.model.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-custom-validator.model.ts","../../../projects/sdcorejs-angular/forms/models/src/form-control-state.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-viewed.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-temporal-transform.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-model-facing-control.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-timer-scope.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-form-control-connector.ts","../../../projects/sdcorejs-angular/forms/models/src/sd-strict-date-adapter.ts","../../../projects/sdcorejs-angular/forms/models/sdcorejs-angular-forms-models.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { MatFormFieldAppearance } from '@angular/material/form-field';\n\nexport interface ISdFormConfiguration {\n appearance?: MatFormFieldAppearance;\n}\n\nexport const SD_FORM_CONFIGURATION = new InjectionToken<ISdFormConfiguration>('sd.form.configuration');\n","import { FormControl, AsyncValidatorFn, ValidatorFn, FormControlOptions, FormControlState } from '@angular/forms';\nimport { Subject } from 'rxjs';\n\nexport class SdFormControl extends FormControl {\n sdChanges: Subject<boolean> = new Subject<boolean>();\n untouchChanges: Subject<boolean> = new Subject<boolean>();\n touchChanges: Subject<boolean> = new Subject<boolean>();\n pristineChanges: Subject<boolean> = new Subject<boolean>();\n constructor(\n formState?: FormControlState<any>,\n validatorOrOpts?: ValidatorFn | ValidatorFn[] | FormControlOptions | null,\n asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null\n ) {\n super(formState, validatorOrOpts, asyncValidator);\n }\n\n override markAsUntouched(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void {\n super.markAsUntouched(opts);\n this.untouchChanges.next(true);\n this.sdChanges.next(true);\n }\n\n override markAsTouched(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void {\n super.markAsTouched(opts);\n this.touchChanges.next(true);\n this.sdChanges.next(true);\n }\n\n override markAsPristine(opts?: { onlySelf?: boolean; emitEvent?: boolean }): void {\n super.markAsPristine(opts);\n this.pristineChanges.next(true);\n this.sdChanges.next(true);\n }\n}\n","import { AbstractControl, AsyncValidatorFn, ValidatorFn } from '@angular/forms';\n\nexport type SdCustomValidator = (value: any) => string | Promise<string>;\n\n/**\n * Inline-error sentinel validator. Returns `{ inlineError: true }` so the form\n * template can render `<mat-error>{{ inlineError }}</mat-error>` whenever the\n * host component has a non-empty `[inlineError]` input. The error message\n * itself is read from the input — this validator only flags the state.\n *\n * why: each form component (input, textarea, select, checkbox, radio, switch,\n * date, datetime, input-number, autocomplete) previously declared the same\n * private `customInlineErrorValidator()` method. Centralized here so adding\n * another form component does not silently re-introduce the duplicate.\n */\nexport const SdInlineErrorValidator: ValidatorFn = (): Record<string, unknown> | null => ({ inlineError: true });\n\nexport const HandleSdCustomValidator = (func: SdCustomValidator): AsyncValidatorFn => {\n return async (c: AbstractControl): Promise<Record<string, any> | null> => {\n const value = c.value === 0 ? c.value : c.value || null;\n if (func && typeof func === 'function') {\n const result = func(value);\n if (result instanceof Promise) {\n const message = await result;\n if (message) {\n return {\n customValidator: message,\n };\n }\n return null;\n }\n if (result) {\n return {\n customValidator: result,\n };\n }\n return null;\n }\n return null;\n };\n};\n","import { DestroyRef, EffectRef, Signal, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { startWith } from 'rxjs/operators';\n\nexport interface SdFormControlSnapshot<T> {\n value: T | undefined;\n disabled: boolean;\n invalid: boolean;\n touched: boolean;\n}\n\n/**\n * Wrap an AbstractControl Signal into a reactive snapshot signal.\n *\n * Re-emits on every value, status, touched, or dirty change so\n * downstream consumers can derive `data-disabled`, `data-value`,\n * `data-empty`, and `data-invalid` host-binding attributes from a\n * single, lazily evaluated signal.\n *\n * \"invalid\" is intentionally gated on `touched || dirty` so validation\n * errors are not surfaced until the user has interacted with the field.\n *\n * Must be called inside an Angular injection context (constructor,\n * field initialiser, or `runInInjectionContext`).\n */\nexport function sdFormControlState<T = unknown>(control: Signal<AbstractControl<T> | null | undefined>): Signal<SdFormControlSnapshot<T>> {\n // A tick counter incremented on every control event (value, status,\n // touched, dirty). Written only from the effect below — never inside\n // a computed() — satisfying Angular's no-side-effect-in-reactive rule.\n const tick = signal(0);\n const destroyRef = inject(DestroyRef);\n\n // Holds the active RxJS subscription so it can be torn down when the\n // control instance changes or the host component is destroyed.\n let subscription: Subscription | null = null;\n\n // An effect re-runs whenever the control Signal changes, tears down the\n // old subscription and creates a fresh one for the incoming control.\n // `AbstractControl.events` (Angular 14+) covers value, status, touched,\n // and dirty changes — a superset of valueChanges + statusChanges.\n const effectRef: EffectRef = effect(() => {\n const c = control(); // tracked — effect re-runs on change\n // effect() runs asynchronously; the old subscription is torn down on the next\n // scheduled run, not synchronously on signal change. A one-tick window of\n // double-subscription is harmless due to computed() memoization.\n subscription?.unsubscribe();\n subscription = null;\n\n if (c) {\n subscription = c.events.pipe(startWith(null)).subscribe(() => {\n // Increment outside reactive context to avoid Angular's\n // \"signal written from computed / template\" error.\n untracked(() => tick.update(n => n + 1));\n });\n }\n });\n\n // Clean up effect and subscription when host component is destroyed.\n destroyRef.onDestroy(() => {\n effectRef.destroy();\n subscription?.unsubscribe();\n });\n\n return computed((): SdFormControlSnapshot<T> => {\n const _control = control();\n tick(); // reactive dependency — recomputes on every control event\n\n if (!_control) {\n return { value: undefined, disabled: false, invalid: false, touched: false };\n }\n\n return {\n value: _control.value as T,\n disabled: _control.disabled,\n invalid: _control.invalid && (_control.touched || _control.dirty),\n touched: _control.touched,\n };\n });\n}\n","import { booleanAttribute, computed, Signal } from '@angular/core';\n\n/**\n * Three display states shared by sd-form-controls:\n * - `false` → full edit chrome (input / dropdown).\n * - `true` → static read-only view (`<sd-view>` text), no editor.\n * - `'inline'` → the editor is STILL rendered (so its panel works), but its chrome is\n * hidden; the `<sd-view>` text is the visible face / trigger. Click the text to open\n * the picker's panel. The text is retained while the panel is open — it only changes\n * when a new value is committed (JIRA-style click-to-edit).\n */\nexport type SdViewed = boolean | 'inline';\nexport type SdViewedInput = SdViewed | '' | null | undefined;\n\n/**\n * `viewed` input transform. Keeps `booleanAttribute` coercion so a bare attribute\n * (`<sd-select viewed>`) still resolves to `true`, but intercepts the literal\n * `'inline'` first — `booleanAttribute('inline')` would otherwise coerce it to `true`.\n */\nexport function sdViewedTransform(v: SdViewedInput): SdViewed {\n return v === 'inline' ? 'inline' : booleanAttribute(v);\n}\n\nexport interface SdViewedInlineApi {\n /** `viewed() === 'inline'` — editor rendered but chrome hidden; sd-view text is the trigger face. */\n readonly isInline: Signal<boolean>;\n /** `viewed() === true` — static read-only view (no editor rendered). */\n readonly isViewed: Signal<boolean>;\n /** Open the picker from the inline text face. No-op unless `'inline'`. */\n enterInlineEdit(): void;\n}\n\n/**\n * Compose the tri-state `viewed` semantics into a control. `open` opens the control's\n * native picker (mat-select panel / mat-calendar / overlay). In `'inline'` mode the editor\n * is always rendered (chrome hidden via CSS), so `open()` can fire immediately on click —\n * no render-swap, the view text never disappears.\n *\n * @param viewed the control's `viewed` input signal.\n * @param open opens the control's picker; called by `enterInlineEdit`.\n * @param disabled the control's disabled state. why: a disabled `'inline'` field must behave\n * like `viewed=true` (static, NOT click-to-edit) — you can't edit a disabled control.\n */\nexport function sdViewedInline(viewed: Signal<SdViewed>, open?: () => void, disabled?: Signal<boolean>): SdViewedInlineApi {\n // why: disabled biến 'inline' thành static view (isInline=false, isViewed=true) — không cho sửa.\n const isInline = computed(() => viewed() === 'inline' && !disabled?.());\n const isViewed = computed(() => viewed() === true || (viewed() === 'inline' && !!disabled?.()));\n const enterInlineEdit = (): void => {\n if (isInline()) open?.();\n };\n return { isInline, isViewed, enterInlineEdit };\n}\n","/**\n * Output serialization strategy for the temporal form controls (`<sd-date>`, `<sd-datetime>`,\n * `<sd-date-range>`).\n *\n * This names how a committed value leaves the component — through `model` / `modelChange` /\n * `sdChange` and the registered `FormGroup` field. It does **not** touch what the field displays,\n * and it is **not** an Angular input-coercion `transform`.\n */\nexport type SdTemporalValueTransform = 'ISOString' | 'UTCString';\n\n/**\n * why: một `Record` khoá bằng chính union — thêm literal mới vào `SdTemporalValueTransform` mà quên\n * serializer là lỗi compile ngay tại đây, không phải một `switch` thiếu nhánh chạy im lặng ở runtime.\n * Ba component chỉ gọi `sdSerializeTemporalValue`, nên không có bản sao logic nào rải rác.\n */\nconst SD_TEMPORAL_TRANSFORM_STRATEGIES: Record<SdTemporalValueTransform, (value: Date) => string> = {\n ISOString: value => value.toISOString(),\n UTCString: value => value.toUTCString(),\n};\n\n/** Every supported strategy, derived from the strategy map so the two can never drift. */\nexport const SD_TEMPORAL_VALUE_TRANSFORMS = Object.keys(SD_TEMPORAL_TRANSFORM_STRATEGIES) as readonly SdTemporalValueTransform[];\n\nexport function sdIsTemporalValueTransform(value: unknown): value is SdTemporalValueTransform {\n return typeof value === 'string' && value in SD_TEMPORAL_TRANSFORM_STRATEGIES;\n}\n\nfunction isValidDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime());\n}\n\n/**\n * Serializes a committed value with the active strategy.\n *\n * Returns `null` for anything that is not a usable `Date`, so an invalid value can never reach a\n * serializer and produce the string `\"Invalid Date\"`. Callers treat `null` as \"keep the existing\n * representation\".\n */\nexport function sdSerializeTemporalValue(\n value: Date | null | undefined,\n transform: SdTemporalValueTransform | null | undefined\n): string | null {\n if (!transform || !isValidDate(value)) return null;\n return SD_TEMPORAL_TRANSFORM_STRATEGIES[transform](value);\n}\n\n/** Local midnight of the given day. Date-only controls serialize this instant, never the raw value. */\nexport function sdLocalStartOfDay(value: Date): Date {\n return new Date(value.getFullYear(), value.getMonth(), value.getDate(), 0, 0, 0, 0);\n}\n\n// why: ISO 8601 với phần giờ tuỳ chọn. Nhánh date-only được tách riêng bên dưới vì\n// `new Date('2026-08-15')` được JS hiểu là NỬA ĐÊM UTC — ở múi giờ âm nó lùi về ngày hôm trước,\n// tức là chỉ render thôi đã đổi mất ngày trên lịch của người dùng.\nconst ISO_DATE_ONLY = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst ISO_DATE_TIME = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/;\n// RFC 1123, đúng shape mà `Date.prototype.toUTCString()` phát ra: `Sat, 15 Aug 2026 03:20:30 GMT`.\nconst RFC_1123_UTC = /^[A-Za-z]{3},\\s\\d{1,2}\\s[A-Za-z]{3}\\s\\d{4}\\s\\d{2}:\\d{2}:\\d{2}\\sGMT$/;\n\n/**\n * Parses the wire formats these transforms emit, so a component can read back its own output.\n *\n * Deliberately narrow: only ISO 8601 and the RFC-1123 shape `toUTCString()` produces are accepted.\n * Handing the whole job to `new Date(text)` would make every loosely date-shaped string parse\n * differently per browser, and would swallow the legacy canonical formats the components already\n * parse with their own strict parsers. Returns `null` when the text is not one of these.\n */\nexport function sdParseTransformedTemporal(value: unknown): Date | null {\n if (typeof value !== 'string') return null;\n\n const text = value.trim();\n if (!text) return null;\n\n const dateOnly = ISO_DATE_ONLY.exec(text);\n if (dateOnly) {\n const [, year, month, day] = dateOnly;\n const parsed = new Date(Number(year), Number(month) - 1, Number(day), 0, 0, 0, 0);\n return isValidDate(parsed) ? parsed : null;\n }\n\n if (!ISO_DATE_TIME.test(text) && !RFC_1123_UTC.test(text)) return null;\n\n const parsed = new Date(text);\n return isValidDate(parsed) ? parsed : null;\n}\n","import { Signal, computed, effect, untracked } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\nimport { sdFormControlState } from './form-control-state';\nimport { SdFormControl } from './sd-form-control.model';\n\nexport interface ɵSdModelFacingControlOptions<TModel> {\n /** Whether the model-facing control should be the one registered in the parent form. */\n readonly active: Signal<boolean>;\n /** The component's public model. */\n readonly model: Signal<TModel>;\n /** Applies an external write that arrived through the registered control. */\n readonly writeModel: (value: TModel) => void;\n /** The internal UI control whose validity, disabled and interaction state must be mirrored. */\n readonly source: Signal<AbstractControl>;\n /** Compares two model values; defaults to `Object.is`. */\n readonly modelEquals?: (left: TModel, right: TModel) => boolean;\n}\n\nexport interface ɵSdModelFacingControl<TModel> {\n /** The control itself. Holds the public model value, never the editor representation. */\n readonly control: SdFormControl;\n /** Feed straight into `ɵsdFormControlConnector`'s `registeredControl`. */\n readonly registered: Signal<AbstractControl | null>;\n}\n\n/**\n * A second control that carries the **public model** so it can be registered in the parent form in\n * place of the editor-facing control.\n *\n * why: `<sd-date>` and friends bind their control directly to the Material editor, so that control\n * necessarily holds a `Date` or a display string. That is invisible until `transform` is set — at\n * which point the consumer is told `form.get(name).value` equals `model`, and finding a raw `Date`\n * there instead makes the promise false. Rather than reshaping the editor binding (which would\n * change behaviour for every existing consumer), this mirrors the model into a control of its own\n * and hands *that* one to the form.\n *\n * Both directions are wired, and neither can feed back on the other:\n * - model changes are pushed in with `emitEvent: false`, so they raise no `valueChanges`;\n * - a write that arrives on this control goes to `writeModel`, exactly like a write on the editor\n * control would, so `modelChange` / `sdChange` still fire once.\n *\n * Validity, disabled and touched/dirty are mirrored from `source`, so registering this control does\n * not quietly drop the editor's validators (min/max, parse errors, required) from the parent form.\n *\n * Must be called from an injection context.\n */\nexport function ɵsdModelFacingControl<TModel>(options: ɵSdModelFacingControlOptions<TModel>): ɵSdModelFacingControl<TModel> {\n const control = new SdFormControl();\n const modelEquals = options.modelEquals ?? Object.is;\n const sourceState = sdFormControlState(options.source);\n\n // Model → control. `emitEvent: false` is what keeps a user commit from bouncing back as a second\n // `modelChange`; the value is already the committed one by the time it lands here.\n effect(() => {\n const value = options.model() as unknown;\n untracked(() => {\n if (!modelEquals(control.value as TModel, value as TModel)) {\n control.setValue(value, { emitEvent: false });\n }\n });\n });\n\n // Control → model, for writes the consumer makes through the registered control.\n effect(onCleanup => {\n const subscription = control.valueChanges.subscribe(value => {\n if (!modelEquals(options.model(), value as TModel)) options.writeModel(value as TModel);\n });\n onCleanup(() => subscription.unsubscribe());\n });\n\n // why: control này KHÔNG mang validator nào của riêng nó — nó chỉ phản chiếu. Nếu không copy\n // `errors` sang, đăng ký nó vào form cha sẽ làm `form.valid` bỏ qua required/min/max/parse của\n // editor, tức là form submit được trong khi field đang đỏ.\n effect(() => {\n const snapshot = sourceState();\n const source = options.source();\n untracked(() => {\n const errors = source.errors;\n const currentErrors = control.errors;\n const changed = JSON.stringify(errors ?? null) !== JSON.stringify(currentErrors ?? null);\n if (changed) control.setErrors(errors, { emitEvent: false });\n\n if (snapshot.disabled !== control.disabled) {\n if (snapshot.disabled) control.disable({ emitEvent: false });\n else control.enable({ emitEvent: false });\n }\n\n if (source.touched && !control.touched) control.markAsTouched({ emitEvent: false } as never);\n if (!source.touched && control.touched) control.markAsUntouched({ emitEvent: false } as never);\n if (source.dirty && !control.dirty) control.markAsDirty({ onlySelf: true });\n if (!source.dirty && control.dirty) control.markAsPristine({ emitEvent: false } as never);\n });\n });\n\n return { control, registered: computed(() => (options.active() ? control : null)) };\n}\n","import { DestroyRef, inject } from '@angular/core';\n\n/**\n * @internal Macrotask timers owned by a component/directive injector.\n *\n * Every pending handle is cleared when the host is destroyed, so a deferred focus,\n * panel-open or emit can never run against a torn-down view.\n */\nexport interface ɵSdTimerScope {\n /**\n * `setTimeout` with the same observable timing, minus the leak: the handle is tracked\n * and cleared on destroy. Scheduling after destroy is a no-op.\n */\n schedule(handler: () => void, delayMs?: number): void;\n /** Cancels every pending timer without waiting for destroy. */\n clear(): void;\n /** Number of timers still pending. Test/diagnostics only. */\n readonly pending: number;\n}\n\n/**\n * @internal Creates a destroy-scoped timer bag. MUST be called from an injection context\n * (class field initializer or constructor) because it resolves `DestroyRef`.\n *\n * why: gần như mọi form control đều hoãn focus / mở panel bằng `setTimeout(..., 100)` để chờ\n * Material dựng xong DOM. Handle không được giữ lại nên callback vẫn chạy sau khi host view đã\n * destroy — route đổi nhanh hoặc chip bị gỡ giữa lúc focus là đủ để `detectChanges()` ném\n * `ViewDestroyedError`, hoặc để một output bắn ra sau khi consumer đã unsubscribe. Gom vào một\n * scope duy nhất để nơi dùng chỉ cần đổi `setTimeout(fn, ms)` → `#timers.schedule(fn, ms)`,\n * KHÔNG đổi độ trễ (đây là fix vòng đời, không phải fix hành vi).\n */\nexport function ɵsdTimerScope(): ɵSdTimerScope {\n const handles = new Set<ReturnType<typeof setTimeout>>();\n let destroyed = false;\n\n const clear = (): void => {\n handles.forEach(handle => clearTimeout(handle));\n handles.clear();\n };\n\n inject(DestroyRef).onDestroy(() => {\n destroyed = true;\n clear();\n });\n\n return {\n schedule(handler: () => void, delayMs = 0): void {\n if (destroyed) return;\n // why: `handles.delete` chạy TRƯỚC handler — handler có thể tự schedule tiếp, xoá sau\n // sẽ vứt nhầm handle mới nếu runtime tái sử dụng id (Node trả object nên an toàn, browser\n // trả number thì không).\n const handle = setTimeout(() => {\n handles.delete(handle);\n handler();\n }, delayMs);\n handles.add(handle);\n },\n clear,\n get pending(): number {\n return handles.size;\n },\n };\n}\n","import { Signal, computed, effect, isDevMode, untracked } from '@angular/core';\nimport { AbstractControl, AsyncValidatorFn, FormGroup, NgForm, ValidatorFn, Validators } from '@angular/forms';\n\nimport { sdFormControlState } from './form-control-state';\nimport { SdViewed } from './sd-viewed';\n\nexport type ɵSdFormControlParent = FormGroup | NgForm | { readonly form: unknown } | null | undefined;\n\ninterface ɵSdFormControlConnectorBaseOptions<TControl> {\n /** Parent form source. NgForm and wrapper values are unwrapped on every rebind. */\n readonly form: Signal<ɵSdFormControlParent>;\n /** Registration name. Empty names intentionally leave the control unregistered. */\n readonly name: Signal<string | null | undefined>;\n /** Canonical control registered in the parent form. */\n readonly control: Signal<AbstractControl<TControl>>;\n /**\n * Control to register in the parent form **instead of** `control`, when the two must differ.\n *\n * why: `<sd-date>` / `<sd-datetime>` / `<sd-date-range>` bind `control` straight to the Material\n * editor, so it necessarily holds the editor's own representation (a `Date`, or the display\n * string) — not the public model. That is fine until `transform` is set, at which point the\n * consumer is promised that `form.get(name).value` matches `model` and the `sdChange` payload.\n * Yielding a model-facing control here moves only the *registration*; validators, disabled, state\n * and the model binding all stay on `control`, so a `null`/absent signal keeps today's behaviour\n * exactly. The component owning both controls is responsible for mirroring value and validity.\n */\n readonly registeredControl?: Signal<AbstractControl | null | undefined>;\n readonly validators?: Signal<ValidatorFn | readonly ValidatorFn[] | null | undefined>;\n readonly asyncValidators?: Signal<AsyncValidatorFn | readonly AsyncValidatorFn[] | null | undefined>;\n /** Adds/removes Validators.required while preserving validators supplied above. */\n readonly required?: Signal<boolean | null | undefined>;\n readonly disabled?: Signal<boolean | null | undefined>;\n /** UI-only read-only policy. This never disables the Angular control. */\n readonly readonly?: Signal<boolean | null | undefined>;\n /** Exact SDCoreJS display policy. This never disables the Angular control. */\n readonly viewed?: Signal<SdViewed | null | undefined>;\n /** Component-local validation message. Visibility is interaction-gated in state. */\n readonly validationError?: Signal<string | null | undefined>;\n}\n\ninterface ɵSdFormControlRegistrationOptions<TControl> extends ɵSdFormControlConnectorBaseOptions<TControl> {\n readonly model?: never;\n readonly writeModel?: never;\n readonly modelToControl?: never;\n readonly controlToModel?: never;\n readonly modelEquals?: never;\n readonly controlEquals?: never;\n}\n\ninterface ɵSdFormControlIdentityOptions<TValue> extends ɵSdFormControlConnectorBaseOptions<TValue> {\n readonly model: Signal<TValue>;\n readonly writeModel: (value: TValue) => void;\n readonly modelToControl?: never;\n readonly controlToModel?: never;\n readonly modelEquals?: (left: TValue, right: TValue) => boolean;\n readonly controlEquals?: (left: TValue, right: TValue) => boolean;\n}\n\ninterface ɵSdFormControlAdaptedOptions<TModel, TControl> extends ɵSdFormControlConnectorBaseOptions<TControl> {\n readonly model: Signal<TModel>;\n readonly writeModel: (value: TModel) => void;\n readonly modelToControl: (value: TModel) => TControl;\n readonly controlToModel: (value: TControl) => TModel;\n readonly modelEquals?: (left: TModel, right: TModel) => boolean;\n readonly controlEquals?: (left: TControl, right: TControl) => boolean;\n}\n\ntype ɵSdTypesExactlyMatch<TLeft, TRight> = [TLeft] extends [TRight] ? ([TRight] extends [TLeft] ? true : false) : false;\n\n/**\n * @internal Unstable connector contract for cross-entrypoint SDCoreJS controls.\n * Consumers must use registration-only, same-type identity binding, or provide\n * both adapters when model and control representations differ.\n */\nexport type ɵSdFormControlConnectorOptions<TModel, TControl> =\n | ɵSdFormControlRegistrationOptions<TControl>\n | ɵSdFormControlAdaptedOptions<TModel, TControl>\n | (ɵSdTypesExactlyMatch<TModel, TControl> extends true ? ɵSdFormControlIdentityOptions<TModel> : never);\n\ntype ɵSdFormControlBindingOptions<TModel, TControl> =\n | ɵSdFormControlIdentityOptions<TControl>\n | ɵSdFormControlAdaptedOptions<TModel, TControl>;\n\ntype ɵSdFormControlImplementationOptions<TModel, TControl> =\n | ɵSdFormControlRegistrationOptions<TControl>\n | ɵSdFormControlBindingOptions<TModel, TControl>;\n\nexport interface ɵSdFormControlConnectorState<TControl> {\n readonly value: TControl | undefined;\n readonly disabled: boolean;\n readonly invalid: boolean;\n readonly touched: boolean;\n readonly dirty: boolean;\n readonly required: boolean;\n readonly readonly: boolean;\n readonly viewed: SdViewed;\n readonly isViewed: boolean;\n readonly isInline: boolean;\n readonly showValidationError: boolean;\n readonly validationError: string | undefined;\n}\n\nexport interface ɵSdFormControlConnector<TControl = unknown> {\n readonly state: Signal<ɵSdFormControlConnectorState<TControl>>;\n markAsTouched(): void;\n markAsUntouched(): void;\n markAsDirty(): void;\n markAsPristine(): void;\n}\n\n/** Coerces the form shapes accepted by SDCoreJS controls into one FormGroup. */\nexport function ɵsdCoerceFormGroup(value: unknown): FormGroup | undefined {\n if (value instanceof NgForm) return value.form;\n if (value instanceof FormGroup) return value;\n if (typeof value !== 'object' || value === null || !('form' in value)) return undefined;\n\n const wrappedForm = (value as { readonly form: unknown }).form;\n return wrappedForm instanceof FormGroup ? wrappedForm : undefined;\n}\n\nfunction normalizeValidatorList<TValidator extends ValidatorFn | AsyncValidatorFn>(\n value: TValidator | readonly TValidator[] | null | undefined\n): TValidator[] {\n if (!value) return [];\n return typeof value === 'function' ? [value] : [...value];\n}\n\nfunction hasModelBinding<TModel, TControl>(\n options: ɵSdFormControlImplementationOptions<TModel, TControl>\n): options is ɵSdFormControlBindingOptions<TModel, TControl> {\n return options.model !== undefined && options.writeModel !== undefined;\n}\n\nfunction readControlValue<TModel, TControl>(options: ɵSdFormControlBindingOptions<TModel, TControl>): TControl {\n if (options.modelToControl) return options.modelToControl(options.model());\n return options.model();\n}\n\nfunction writeModelValue<TModel, TControl>(options: ɵSdFormControlBindingOptions<TModel, TControl>, controlValue: TControl): void {\n if (options.controlToModel) {\n const modelValue = options.controlToModel(controlValue);\n if (!(options.modelEquals ?? Object.is)(options.model(), modelValue)) options.writeModel(modelValue);\n return;\n }\n\n if (!(options.modelEquals ?? Object.is)(options.model(), controlValue)) options.writeModel(controlValue);\n}\n\n/**\n * Connects the signal-based SDCoreJS model contract to an Angular control.\n * Registration and subscriptions are rebound transactionally, and cleanup only\n * removes a control while the connector still owns that exact registration.\n */\nexport function ɵsdFormControlConnector<TModel, TControl>(\n options: ɵSdFormControlConnectorOptions<TModel, TControl>\n): ɵSdFormControlConnector<TControl>;\nexport function ɵsdFormControlConnector<TModel, TControl>(\n options: ɵSdFormControlImplementationOptions<TModel, TControl>\n): ɵSdFormControlConnector<TControl> {\n const controlEquals = options.controlEquals ?? Object.is;\n const controlState = sdFormControlState(options.control);\n const state = computed((): ɵSdFormControlConnectorState<TControl> => {\n const snapshot = controlState();\n const required = !!options.required?.();\n const readonly = !!options.readonly?.();\n const viewed = options.viewed?.() ?? false;\n const validationError = options.validationError?.() || undefined;\n const showValidationError = snapshot.invalid && validationError !== undefined;\n\n return {\n ...snapshot,\n dirty: options.control().dirty,\n required,\n readonly,\n viewed,\n isViewed: viewed === true,\n isInline: viewed === 'inline',\n showValidationError,\n validationError: showValidationError ? validationError : undefined,\n };\n });\n\n effect(onCleanup => {\n const formGroup = ɵsdCoerceFormGroup(options.form());\n const name = options.name();\n // why: `?? options.control()` chứ không phải một nhánh riêng — không khai `registeredControl`\n // (hoặc trả null) là đi đúng đường cũ, nên mọi control hiện có giữ nguyên control đã đăng ký.\n const control = options.registeredControl?.() ?? options.control();\n\n if (!formGroup || !name) return;\n\n const current = formGroup.get(name);\n\n // why: trước đây là `const ownsRegistration = !current; if (ownsRegistration) addControl(...)`\n // — tức là khi FormGroup cha ĐÃ có control trùng `name`, control nội bộ của component không bao\n // giờ được đăng ký. Hậu quả im lặng: người dùng gõ vào field, nhưng `form.value[name]` không bao\n // giờ đổi, form submit rỗng và không có bất kỳ cảnh báo nào. Trùng `name` gần như luôn là lỗi\n // của consumer (khai control thủ công rồi lại truyền `[form]`+`name`, hoặc 2 control cùng tên).\n // Giờ: thay control bằng `setControl` để giá trị THỰC SỰ tới được form, cộng thêm lỗi dev-mode\n // chỉ đúng tên field để consumer gỡ khai báo thừa.\n // Ba trường hợp, và chỉ trường hợp thứ ba là thay đổi hành vi:\n // 1. chưa có gì ở `name` → tự đăng ký, TA sở hữu, gỡ khi cleanup.\n // 2. đã có ĐÚNG control này → consumer chủ động đăng ký hộ; ta KHÔNG sở hữu nên\n // không được gỡ khi destroy (nếu không sẽ xoá control\n // mà consumer đang chủ ý giữ).\n // 3. đã có control KHÁC → xung đột tên. Trước đây im lặng bỏ qua, nên giá trị người\n // dùng gõ không bao giờ tới được form và submit ra rỗng.\n const ownsRegistration = current == null;\n // why: control bị ta đẩy ra (nếu có) phải được GHI NHỚ để trả lại khi cleanup. Nếu không, đổi\n // `name` hoặc destroy component sẽ để control của ta nằm lại vĩnh viễn trong FormGroup của\n // consumer, còn control gốc của họ thì mất hẳn — tệ hơn cả bug ban đầu.\n const displaced = !ownsRegistration && current !== control ? current : undefined;\n if (ownsRegistration) {\n formGroup.addControl(name, control);\n } else if (current !== control) {\n if (isDevMode()) {\n console.error(\n `[sd-forms] FormGroup đã có control tên \"${name}\" và nó KHÔNG phải control của <sd-*> này. ` +\n `Control cũ bị thay thế để giá trị nhập vào thực sự tới được form — trước đây trường hợp này ` +\n `bị bỏ qua im lặng và form submit ra rỗng. Bỏ khai báo control \"${name}\" thủ công, hoặc đổi ` +\n `\\`name\\` của component.`\n );\n }\n formGroup.setControl(name, control);\n }\n\n onCleanup(() => {\n // Nếu ai đó đã đăng ký chồng lên sau ta thì không đụng vào.\n if (formGroup.get(name) !== control) return;\n if (displaced) {\n // Trả lại đúng control ban đầu của consumer.\n formGroup.setControl(name, displaced);\n } else if (ownsRegistration) {\n formGroup.removeControl(name);\n }\n // Trường hợp còn lại: consumer tự đăng ký ĐÚNG control này — ta không sở hữu nên không gỡ.\n });\n });\n\n if (hasModelBinding(options)) {\n effect(() => {\n const control = options.control();\n const controlValue = readControlValue(options);\n\n untracked(() => {\n if (!controlEquals(control.value, controlValue)) {\n control.setValue(controlValue, { emitEvent: false });\n }\n });\n });\n }\n\n if (hasModelBinding(options)) {\n effect(onCleanup => {\n const control = options.control();\n const subscription = control.valueChanges.subscribe(controlValue => {\n writeModelValue(options, controlValue);\n });\n onCleanup(() => subscription.unsubscribe());\n });\n }\n\n if (options.validators || options.asyncValidators || options.required) {\n effect(onCleanup => {\n const control = options.control();\n const requestedValidators = normalizeValidatorList(options.validators?.());\n if (options.required?.()) requestedValidators.push(Validators.required);\n const validatorsToAdd = [...new Set(requestedValidators)].filter(validator => !control.hasValidator(validator));\n const asyncValidatorsToAdd = [...new Set(normalizeValidatorList(options.asyncValidators?.()))].filter(\n validator => !control.hasAsyncValidator(validator)\n );\n\n untracked(() => {\n if (validatorsToAdd.length > 0) control.addValidators(validatorsToAdd);\n if (asyncValidatorsToAdd.length > 0) control.addAsyncValidators(asyncValidatorsToAdd);\n control.updateValueAndValidity({ emitEvent: false });\n });\n\n onCleanup(() => {\n untracked(() => {\n if (validatorsToAdd.length > 0) control.removeValidators(validatorsToAdd);\n if (asyncValidatorsToAdd.length > 0) control.removeAsyncValidators(asyncValidatorsToAdd);\n control.updateValueAndValidity({ emitEvent: false });\n });\n });\n });\n }\n\n if (options.disabled) {\n effect(onCleanup => {\n const control = options.control();\n const disabled = !!options.disabled!();\n const previousDisabled = control.disabled;\n let appliedDisabled: boolean | undefined;\n\n untracked(() => {\n if (disabled !== control.disabled) {\n appliedDisabled = disabled;\n if (disabled) control.disable({ emitEvent: false });\n else control.enable({ emitEvent: false });\n }\n });\n\n onCleanup(() => {\n if (appliedDisabled === undefined || control.disabled !== appliedDisabled) return;\n\n untracked(() => {\n if (previousDisabled) control.disable({ emitEvent: false });\n else control.enable({ emitEvent: false });\n });\n });\n });\n }\n\n return {\n state,\n markAsTouched: () => options.control().markAsTouched(),\n markAsUntouched: () => options.control().markAsUntouched(),\n markAsDirty: () => options.control().markAsDirty(),\n markAsPristine: () => options.control().markAsPristine(),\n };\n}\n","import { Injectable, Provider } from '@angular/core';\nimport { DateFnsAdapter, provideDateFnsAdapter } from '@angular/material-date-fns-adapter';\nimport { DateAdapter, MatDateFormats } from '@angular/material/core';\nimport { isValid as isValidDate, parse as parseDate } from 'date-fns';\n\n/**\n * DateAdapter từ chối mọi chuỗi người dùng chưa gõ xong.\n *\n * WHY cần đến mức này: `<input matInput [matDatepicker]>` khiến Material tự\n * `parse()` lại ô nhập SAU MỖI PHÍM GÕ rồi ghi thẳng kết quả vào form control.\n * Adapter mặc định quá dễ dãi trên hai đường:\n *\n * 1. `date-fns.parse` nhận năm thiếu chữ số → `11/12/2` thành năm 0002,\n * `11/12/20` thành năm 0020. Ô nhập vừa gõ dở đã bị coi là hợp lệ (cờ lỗi\n * bị xoá) và control ôm một ngày rác.\n * 2. `parseISO` coi chuỗi 2 chữ số là thế kỷ → xoá lùi còn `11` ra năm 1100.\n *\n * Cả hai đường đều bị chặn ở đây: control chỉ nhận giá trị khi người dùng thực\n * sự gõ xong.\n */\n@Injectable()\nexport class SdStrictDateFnsAdapter extends DateFnsAdapter {\n override parse(value: unknown, parseFormat: string | string[]): Date | null {\n if (typeof value !== 'string') return super.parse(value, parseFormat);\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n // Cố tình KHÔNG gọi super.parse: chỗ đó có ISO fallback (đường số 2 ở trên).\n for (const currentFormat of Array.isArray(parseFormat) ? parseFormat : [parseFormat]) {\n const parsed = parseDate(trimmed, currentFormat, new Date(), { locale: this.locale });\n if (!isValidDate(parsed)) continue;\n // Round-trip: chuỗi phải khớp 1-1 với format, nên năm thiếu chữ số bị loại.\n if (this.format(parsed, currentFormat) === trimmed) return parsed;\n }\n\n return null;\n }\n}\n\n/** `provideDateFnsAdapter` + ép dùng adapter parse chặt ở trên. */\nexport function provideSdStrictDateFnsAdapter(formats: MatDateFormats): Provider[] {\n return [\n provideDateFnsAdapter(formats),\n // Phải đứng SAU provideDateFnsAdapter để ghi đè DateAdapter mà nó đăng ký.\n { provide: DateAdapter, useClass: SdStrictDateFnsAdapter },\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["parseDate","isValidDate"],"mappings":";;;;;;;;;MAOa,qBAAqB,GAAG,IAAI,cAAc,CAAuB,uBAAuB;;ACJ/F,MAAO,aAAc,SAAQ,WAAW,CAAA;AAC5C,IAAA,SAAS,GAAqB,IAAI,OAAO,EAAW;AACpD,IAAA,cAAc,GAAqB,IAAI,OAAO,EAAW;AACzD,IAAA,YAAY,GAAqB,IAAI,OAAO,EAAW;AACvD,IAAA,eAAe,GAAqB,IAAI,OAAO,EAAW;AAC1D,IAAA,WAAA,CACE,SAAiC,EACjC,eAAyE,EACzE,cAA6D,EAAA;AAE7D,QAAA,KAAK,CAAC,SAAS,EAAE,eAAe,EAAE,cAAc,CAAC;IACnD;AAES,IAAA,eAAe,CAAC,IAAkD,EAAA;AACzE,QAAA,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC;AAC3B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9B,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B;AAES,IAAA,aAAa,CAAC,IAAkD,EAAA;AACvE,QAAA,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B;AAES,IAAA,cAAc,CAAC,IAAkD,EAAA;AACxE,QAAA,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;AAC/B,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B;AACD;;AC7BD;;;;;;;;;;AAUG;AACI,MAAM,sBAAsB,GAAgB,OAAuC,EAAE,WAAW,EAAE,IAAI,EAAE;AAExG,MAAM,uBAAuB,GAAG,CAAC,IAAuB,KAAsB;AACnF,IAAA,OAAO,OAAO,CAAkB,KAAyC;QACvE,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,IAAI;AACvD,QAAA,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE;AACtC,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;AAC1B,YAAA,IAAI,MAAM,YAAY,OAAO,EAAE;AAC7B,gBAAA,MAAM,OAAO,GAAG,MAAM,MAAM;gBAC5B,IAAI,OAAO,EAAE;oBACX,OAAO;AACL,wBAAA,eAAe,EAAE,OAAO;qBACzB;gBACH;AACA,gBAAA,OAAO,IAAI;YACb;YACA,IAAI,MAAM,EAAE;gBACV,OAAO;AACL,oBAAA,eAAe,EAAE,MAAM;iBACxB;YACH;AACA,YAAA,OAAO,IAAI;QACb;AACA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;;AC5BA;;;;;;;;;;;;;AAaG;AACG,SAAU,kBAAkB,CAAc,OAAsD,EAAA;;;;AAIpG,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,gDAAC;AACtB,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;;;IAIrC,IAAI,YAAY,GAAwB,IAAI;;;;;AAM5C,IAAA,MAAM,SAAS,GAAc,MAAM,CAAC,MAAK;AACvC,QAAA,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;;;;QAIpB,YAAY,EAAE,WAAW,EAAE;QAC3B,YAAY,GAAG,IAAI;QAEnB,IAAI,CAAC,EAAE;AACL,YAAA,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAK;;;AAG3D,gBAAA,SAAS,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1C,YAAA,CAAC,CAAC;QACJ;AACF,IAAA,CAAC,qDAAC;;AAGF,IAAA,UAAU,CAAC,SAAS,CAAC,MAAK;QACxB,SAAS,CAAC,OAAO,EAAE;QACnB,YAAY,EAAE,WAAW,EAAE;AAC7B,IAAA,CAAC,CAAC;IAEF,OAAO,QAAQ,CAAC,MAA+B;AAC7C,QAAA,MAAM,QAAQ,GAAG,OAAO,EAAE;QAC1B,IAAI,EAAE,CAAC;QAEP,IAAI,CAAC,QAAQ,EAAE;AACb,YAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;QAC9E;QAEA,OAAO;YACL,KAAK,EAAE,QAAQ,CAAC,KAAU;YAC1B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;AAC3B,YAAA,OAAO,EAAE,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC;YACjE,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B;AACH,IAAA,CAAC,CAAC;AACJ;;ACjEA;;;;AAIG;AACG,SAAU,iBAAiB,CAAC,CAAgB,EAAA;AAChD,IAAA,OAAO,CAAC,KAAK,QAAQ,GAAG,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC;AACxD;AAWA;;;;;;;;;;AAUG;SACa,cAAc,CAAC,MAAwB,EAAE,IAAiB,EAAE,QAA0B,EAAA;;AAEpG,IAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,MAAM,EAAE,KAAK,QAAQ,IAAI,CAAC,QAAQ,IAAI,oDAAC;IACvE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,MAAM,EAAE,KAAK,IAAI,KAAK,MAAM,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;IAC/F,MAAM,eAAe,GAAG,MAAW;AACjC,QAAA,IAAI,QAAQ,EAAE;YAAE,IAAI,IAAI;AAC1B,IAAA,CAAC;AACD,IAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE;AAChD;;ACzCA;;;;AAIG;AACH,MAAM,gCAAgC,GAA8D;IAClG,SAAS,EAAE,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE;IACvC,SAAS,EAAE,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE;CACxC;AAED;AACO,MAAM,4BAA4B,GAAG,MAAM,CAAC,IAAI,CAAC,gCAAgC;AAElF,SAAU,0BAA0B,CAAC,KAAc,EAAA;IACvD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,gCAAgC;AAC/E;AAEA,SAAS,WAAW,CAAC,KAAc,EAAA;AACjC,IAAA,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AAChE;AAEA;;;;;;AAMG;AACG,SAAU,wBAAwB,CACtC,KAA8B,EAC9B,SAAsD,EAAA;AAEtD,IAAA,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,IAAI;AAClD,IAAA,OAAO,gCAAgC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC;AAC3D;AAEA;AACM,SAAU,iBAAiB,CAAC,KAAW,EAAA;IAC3C,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACrF;AAEA;AACA;AACA;AACA,MAAM,aAAa,GAAG,2BAA2B;AACjD,MAAM,aAAa,GAAG,gFAAgF;AACtG;AACA,MAAM,YAAY,GAAG,qEAAqE;AAE1F;;;;;;;AAOG;AACG,SAAU,0BAA0B,CAAC,KAAc,EAAA;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;AAAE,QAAA,OAAO,IAAI;AAE1C,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE;AACzB,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;IAEtB,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;IACzC,IAAI,QAAQ,EAAE;QACZ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,QAAQ;AACrC,QAAA,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACjF,QAAA,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI;IAC5C;AAEA,IAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AAAE,QAAA,OAAO,IAAI;AAEtE,IAAA,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;AAC7B,IAAA,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI;AAC5C;;AC1DA;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,SAAU,qBAAqB,CAAS,OAA6C,EAAA;AACzF,IAAA,MAAM,OAAO,GAAG,IAAI,aAAa,EAAE;IACnC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,EAAE;IACpD,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC;;;IAItD,MAAM,CAAC,MAAK;AACV,QAAA,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAa;QACxC,SAAS,CAAC,MAAK;YACb,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAe,EAAE,KAAe,CAAC,EAAE;gBAC1D,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC/C;AACF,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,CAAC;;IAGF,MAAM,CAAC,SAAS,IAAG;QACjB,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,IAAG;YAC1D,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,KAAe,CAAC;AAAE,gBAAA,OAAO,CAAC,UAAU,CAAC,KAAe,CAAC;AACzF,QAAA,CAAC,CAAC;QACF,SAAS,CAAC,MAAM,YAAY,CAAC,WAAW,EAAE,CAAC;AAC7C,IAAA,CAAC,CAAC;;;;IAKF,MAAM,CAAC,MAAK;AACV,QAAA,MAAM,QAAQ,GAAG,WAAW,EAAE;AAC9B,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE;QAC/B,SAAS,CAAC,MAAK;AACb,YAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM;AAC5B,YAAA,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM;AACpC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,IAAI,CAAC;AACxF,YAAA,IAAI,OAAO;gBAAE,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAE5D,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE;gBAC1C,IAAI,QAAQ,CAAC,QAAQ;oBAAE,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;oBACvD,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC3C;AAEA,YAAA,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO;gBAAE,OAAO,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,KAAK,EAAW,CAAC;AAC5F,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,CAAC,eAAe,CAAC,EAAE,SAAS,EAAE,KAAK,EAAW,CAAC;AAC9F,YAAA,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK;gBAAE,OAAO,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC3E,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;gBAAE,OAAO,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,KAAK,EAAW,CAAC;AAC3F,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,OAAO,OAAO,CAAC,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,EAAE;AACrF;;AC5EA;;;;;;;;;;AAUG;SACa,aAAa,GAAA;AAC3B,IAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiC;IACxD,IAAI,SAAS,GAAG,KAAK;IAErB,MAAM,KAAK,GAAG,MAAW;AACvB,QAAA,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,EAAE;AACjB,IAAA,CAAC;AAED,IAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAK;QAChC,SAAS,GAAG,IAAI;AAChB,QAAA,KAAK,EAAE;AACT,IAAA,CAAC,CAAC;IAEF,OAAO;AACL,QAAA,QAAQ,CAAC,OAAmB,EAAE,OAAO,GAAG,CAAC,EAAA;AACvC,YAAA,IAAI,SAAS;gBAAE;;;;AAIf,YAAA,MAAM,MAAM,GAAG,UAAU,CAAC,MAAK;AAC7B,gBAAA,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AACtB,gBAAA,OAAO,EAAE;YACX,CAAC,EAAE,OAAO,CAAC;AACX,YAAA,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QACrB,CAAC;QACD,KAAK;AACL,QAAA,IAAI,OAAO,GAAA;YACT,OAAO,OAAO,CAAC,IAAI;QACrB,CAAC;KACF;AACH;;ACgDA;AACM,SAAU,kBAAkB,CAAC,KAAc,EAAA;IAC/C,IAAI,KAAK,YAAY,MAAM;QAAE,OAAO,KAAK,CAAC,IAAI;IAC9C,IAAI,KAAK,YAAY,SAAS;AAAE,QAAA,OAAO,KAAK;AAC5C,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC;AAAE,QAAA,OAAO,SAAS;AAEvF,IAAA,MAAM,WAAW,GAAI,KAAoC,CAAC,IAAI;IAC9D,OAAO,WAAW,YAAY,SAAS,GAAG,WAAW,GAAG,SAAS;AACnE;AAEA,SAAS,sBAAsB,CAC7B,KAA4D,EAAA;AAE5D,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;AACrB,IAAA,OAAO,OAAO,KAAK,KAAK,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC3D;AAEA,SAAS,eAAe,CACtB,OAA8D,EAAA;IAE9D,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;AACxE;AAEA,SAAS,gBAAgB,CAAmB,OAAuD,EAAA;IACjG,IAAI,OAAO,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;AAC1E,IAAA,OAAO,OAAO,CAAC,KAAK,EAAE;AACxB;AAEA,SAAS,eAAe,CAAmB,OAAuD,EAAE,YAAsB,EAAA;AACxH,IAAA,IAAI,OAAO,CAAC,cAAc,EAAE;QAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC;AACvD,QAAA,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC;AAAE,YAAA,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;QACpG;IACF;AAEA,IAAA,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC;AAAE,QAAA,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC;AAC1G;AAUM,SAAU,uBAAuB,CACrC,OAA8D,EAAA;IAE9D,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,MAAM,CAAC,EAAE;IACxD,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC;AACxD,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,MAA6C;AAClE,QAAA,MAAM,QAAQ,GAAG,YAAY,EAAE;QAC/B,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI;QACvC,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,KAAK;QAC1C,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,SAAS;QAChE,MAAM,mBAAmB,GAAG,QAAQ,CAAC,OAAO,IAAI,eAAe,KAAK,SAAS;QAE7E,OAAO;AACL,YAAA,GAAG,QAAQ;AACX,YAAA,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK;YAC9B,QAAQ;YACR,QAAQ;YACR,MAAM;YACN,QAAQ,EAAE,MAAM,KAAK,IAAI;YACzB,QAAQ,EAAE,MAAM,KAAK,QAAQ;YAC7B,mBAAmB;YACnB,eAAe,EAAE,mBAAmB,GAAG,eAAe,GAAG,SAAS;SACnE;AACH,IAAA,CAAC,iDAAC;IAEF,MAAM,CAAC,SAAS,IAAG;QACjB,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;AACpD,QAAA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE;;;AAG3B,QAAA,MAAM,OAAO,GAAG,OAAO,CAAC,iBAAiB,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE;AAElE,QAAA,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI;YAAE;QAEzB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;AAgBnC,QAAA,MAAM,gBAAgB,GAAG,OAAO,IAAI,IAAI;;;;AAIxC,QAAA,MAAM,SAAS,GAAG,CAAC,gBAAgB,IAAI,OAAO,KAAK,OAAO,GAAG,OAAO,GAAG,SAAS;QAChF,IAAI,gBAAgB,EAAE;AACpB,YAAA,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;QACrC;AAAO,aAAA,IAAI,OAAO,KAAK,OAAO,EAAE;YAC9B,IAAI,SAAS,EAAE,EAAE;AACf,gBAAA,OAAO,CAAC,KAAK,CACX,CAAA,wCAAA,EAA2C,IAAI,CAAA,2CAAA,CAA6C;oBAC1F,CAAA,4FAAA,CAA8F;AAC9F,oBAAA,CAAA,+DAAA,EAAkE,IAAI,CAAA,qBAAA,CAAuB;AAC7F,oBAAA,CAAA,uBAAA,CAAyB,CAC5B;YACH;AACA,YAAA,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;QACrC;QAEA,SAAS,CAAC,MAAK;;AAEb,YAAA,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,OAAO;gBAAE;YACrC,IAAI,SAAS,EAAE;;AAEb,gBAAA,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;YACvC;iBAAO,IAAI,gBAAgB,EAAE;AAC3B,gBAAA,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC;YAC/B;;AAEF,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,CAAC;AAEF,IAAA,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE;AACjC,YAAA,MAAM,YAAY,GAAG,gBAAgB,CAAC,OAAO,CAAC;YAE9C,SAAS,CAAC,MAAK;gBACb,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE;oBAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gBACtD;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,CAAC,SAAS,IAAG;AACjB,YAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE;YACjC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,YAAY,IAAG;AACjE,gBAAA,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC;AACxC,YAAA,CAAC,CAAC;YACF,SAAS,CAAC,MAAM,YAAY,CAAC,WAAW,EAAE,CAAC;AAC7C,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE;QACrE,MAAM,CAAC,SAAS,IAAG;AACjB,YAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE;YACjC,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC;AAC1E,YAAA,IAAI,OAAO,CAAC,QAAQ,IAAI;AAAE,gBAAA,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YACvE,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAC/G,YAAA,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,sBAAsB,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CACnG,SAAS,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,SAAS,CAAC,CACnD;YAED,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;AAAE,oBAAA,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC;AACtE,gBAAA,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC;AAAE,oBAAA,OAAO,CAAC,kBAAkB,CAAC,oBAAoB,CAAC;gBACrF,OAAO,CAAC,sBAAsB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACtD,YAAA,CAAC,CAAC;YAEF,SAAS,CAAC,MAAK;gBACb,SAAS,CAAC,MAAK;AACb,oBAAA,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;AAAE,wBAAA,OAAO,CAAC,gBAAgB,CAAC,eAAe,CAAC;AACzE,oBAAA,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC;AAAE,wBAAA,OAAO,CAAC,qBAAqB,CAAC,oBAAoB,CAAC;oBACxF,OAAO,CAAC,sBAAsB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACtD,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,IAAI,OAAO,CAAC,QAAQ,EAAE;QACpB,MAAM,CAAC,SAAS,IAAG;AACjB,YAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE;YACjC,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,QAAS,EAAE;AACtC,YAAA,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ;AACzC,YAAA,IAAI,eAAoC;YAExC,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE;oBACjC,eAAe,GAAG,QAAQ;AAC1B,oBAAA,IAAI,QAAQ;wBAAE,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;wBAC9C,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gBAC3C;AACF,YAAA,CAAC,CAAC;YAEF,SAAS,CAAC,MAAK;gBACb,IAAI,eAAe,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,eAAe;oBAAE;gBAE3E,SAAS,CAAC,MAAK;AACb,oBAAA,IAAI,gBAAgB;wBAAE,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;wBACtD,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC3C,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEA,OAAO;QACL,KAAK;QACL,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE;QACtD,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,eAAe,EAAE;QAC1D,WAAW,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE;QAClD,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,cAAc,EAAE;KACzD;AACH;;AC5TA;;;;;;;;;;;;;;AAcG;AAEG,MAAO,sBAAuB,SAAQ,cAAc,CAAA;IAC/C,KAAK,CAAC,KAAc,EAAE,WAA8B,EAAA;QAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC;AAErE,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE;AAC5B,QAAA,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,IAAI;;QAGzB,KAAK,MAAM,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,CAAC,WAAW,CAAC,EAAE;YACpF,MAAM,MAAM,GAAGA,KAAS,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AACrF,YAAA,IAAI,CAACC,OAAW,CAAC,MAAM,CAAC;gBAAE;;YAE1B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,OAAO;AAAE,gBAAA,OAAO,MAAM;QACnE;AAEA,QAAA,OAAO,IAAI;IACb;wGAhBW,sBAAsB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;4GAAtB,sBAAsB,EAAA,CAAA;;4FAAtB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBADlC;;AAoBD;AACM,SAAU,6BAA6B,CAAC,OAAuB,EAAA;IACnE,OAAO;QACL,qBAAqB,CAAC,OAAO,CAAC;;AAE9B,QAAA,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,sBAAsB,EAAE;KAC3D;AACH;;AC/CA;;AAEG;;;;"}
|
|
@@ -14,7 +14,7 @@ import { Subscription } from 'rxjs';
|
|
|
14
14
|
import { SdSuffixDefDirective, SdLabelDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';
|
|
15
15
|
import { SdFormControl, sdViewedTransform, sdViewedInline, sdFormControlState, ɵsdFormControlConnector as _sdFormControlConnector, SdInlineErrorValidator } from '@sdcorejs/angular/forms/models';
|
|
16
16
|
import { sdIsEmpty, sdSerializeDataValue } from '@sdcorejs/angular/utilities/data-state';
|
|
17
|
-
import {
|
|
17
|
+
import { SdTranslatePipe } from '@sdcorejs/angular/i18n';
|
|
18
18
|
import { SdEmptyPipe } from '@sdcorejs/angular/pipes';
|
|
19
19
|
import { SdLabel } from '@sdcorejs/angular/forms/label';
|
|
20
20
|
import { SdHrefDirective } from '@sdcorejs/angular/directives';
|
|
@@ -145,7 +145,7 @@ class SdRadio {
|
|
|
145
145
|
this.formControl.updateValueAndValidity({ emitEvent: true });
|
|
146
146
|
};
|
|
147
147
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdRadio, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
148
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdRadio, isStandalone: true, selector: "sd-radio", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: true, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: true, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, inlineError: { classPropertyName: "inlineError", publicName: "inlineError", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, viewed: { classPropertyName: "viewed", publicName: "viewed", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, hyperlink: { classPropertyName: "hyperlink", publicName: "hyperlink", isSignal: true, isRequired: false, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { model: "modelChange", sdChange: "sdChange", sdSelection: "sdSelection" }, host: { properties: { "class.sd-c-primary": "color() === 'primary'", "class.sd-c-secondary": "color() === 'secondary'", "class.sd-c-info": "color() === 'info'", "class.sd-c-success": "color() === 'success'", "class.sd-c-warning": "color() === 'warning'", "class.sd-c-error": "color() === 'error'" } }, queries: [{ propertyName: "sdSuffixDef", first: true, predicate: SdSuffixDefDirective, descendants: true, isSignal: true }, { propertyName: "sdLabelDef", first: true, predicate: SdLabelDefDirective, descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@let _sdLabelDef = sdLabelDef();\n@let _sdSuffixDef = sdSuffixDef();\n@let _label = label();\n@let _display = display();\n@let _valueField = valueField();\n@let _hyperlink = hyperlink();\n\n@if (isViewed()) {\n @if (_sdLabelDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container>\n } @else if (_label) {\n <div class=\"T14R text-secondary\">{{ _label }}</div>\n }\n @if (_hyperlink) {\n <!-- N\u1EBFu c\u00F3 hyperlink th\u00EC d\u00F9ng th\u1EBB a -->\n <a [sdHref]=\"_hyperlink!\">{{ viewedText() || placeholder() }}</a>\n } @else {\n <!-- Ngo\u00E0i ra d\u00F9ng th\u1EBB m\u1EB7c \u0111\u1ECBnh -->\n <div class=\"T14M\">{{ viewedText() || placeholder() | sdEmpty }}</div>\n }\n} @else {\n <section [ngClass]=\"{ 'c-section': _display === 'row' }\">\n @if (_sdLabelDef?.templateRef) {\n <div [id]=\"labelId\"><ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container></div>\n } @else if (_label) {\n <sd-label [attr.id]=\"labelId\" [label]=\"_label!\" [required]=\"required()\"></sd-label>\n }\n <mat-radio-group\n [class.c-radio-group-column]=\"_display === 'column'\"\n [class.c-radio-group-row]=\"_display === 'row'\"\n [formControl]=\"formControl\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-required]=\"dataRequired()\">\n @for (item of normalizedItems(); track item[valueField()]) {\n <mat-radio-button [class.m-0]=\"_display === 'column'\" [class.mr-16]=\"_display === 'row'\" [value]=\"item[_valueField]\">\n {{ item[displayField()] }}\n </mat-radio-button>\n }\n </mat-radio-group>\n\n @if (_sdSuffixDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdSuffixDef!.templateRef\"> </ng-container>\n }\n\n @if (visibleError() === 'required') {\n <mat-error [id]=\"errorId\">\n {{ 'core.form.radio.required' |
|
|
148
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdRadio, isStandalone: true, selector: "sd-radio", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: true, transformFunction: null }, displayField: { classPropertyName: "displayField", publicName: "displayField", isSignal: true, isRequired: true, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, inlineError: { classPropertyName: "inlineError", publicName: "inlineError", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, viewed: { classPropertyName: "viewed", publicName: "viewed", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, hyperlink: { classPropertyName: "hyperlink", publicName: "hyperlink", isSignal: true, isRequired: false, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { model: "modelChange", sdChange: "sdChange", sdSelection: "sdSelection" }, host: { properties: { "class.sd-c-primary": "color() === 'primary'", "class.sd-c-secondary": "color() === 'secondary'", "class.sd-c-info": "color() === 'info'", "class.sd-c-success": "color() === 'success'", "class.sd-c-warning": "color() === 'warning'", "class.sd-c-error": "color() === 'error'" } }, queries: [{ propertyName: "sdSuffixDef", first: true, predicate: SdSuffixDefDirective, descendants: true, isSignal: true }, { propertyName: "sdLabelDef", first: true, predicate: SdLabelDefDirective, descendants: true, isSignal: true }, { propertyName: "sdViewDef", first: true, predicate: SdViewDefDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@let _sdLabelDef = sdLabelDef();\n@let _sdSuffixDef = sdSuffixDef();\n@let _label = label();\n@let _display = display();\n@let _valueField = valueField();\n@let _hyperlink = hyperlink();\n\n@if (isViewed()) {\n @if (_sdLabelDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container>\n } @else if (_label) {\n <div class=\"T14R text-secondary\">{{ _label }}</div>\n }\n @if (_hyperlink) {\n <!-- N\u1EBFu c\u00F3 hyperlink th\u00EC d\u00F9ng th\u1EBB a -->\n <a [sdHref]=\"_hyperlink!\">{{ viewedText() || placeholder() }}</a>\n } @else {\n <!-- Ngo\u00E0i ra d\u00F9ng th\u1EBB m\u1EB7c \u0111\u1ECBnh -->\n <div class=\"T14M\">{{ viewedText() || placeholder() | sdEmpty }}</div>\n }\n} @else {\n <section [ngClass]=\"{ 'c-section': _display === 'row' }\">\n @if (_sdLabelDef?.templateRef) {\n <div [id]=\"labelId\"><ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container></div>\n } @else if (_label) {\n <sd-label [attr.id]=\"labelId\" [label]=\"_label!\" [required]=\"required()\"></sd-label>\n }\n <mat-radio-group\n [class.c-radio-group-column]=\"_display === 'column'\"\n [class.c-radio-group-row]=\"_display === 'row'\"\n [formControl]=\"formControl\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-required]=\"dataRequired()\">\n @for (item of normalizedItems(); track item[valueField()]) {\n <mat-radio-button [class.m-0]=\"_display === 'column'\" [class.mr-16]=\"_display === 'row'\" [value]=\"item[_valueField]\">\n {{ item[displayField()] }}\n </mat-radio-button>\n }\n </mat-radio-group>\n\n @if (_sdSuffixDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdSuffixDef!.templateRef\"> </ng-container>\n }\n\n @if (visibleError() === 'required') {\n <mat-error [id]=\"errorId\">\n {{ 'core.form.radio.required' | sdTranslate }}\n </mat-error>\n } @else if (visibleError() === 'inlineError') {\n <mat-error [id]=\"errorId\">\n {{ inlineError() }}\n </mat-error>\n }\n </section>\n}\n", styles: [":host{height:100%;display:flex;flex-direction:column}:host ::ng-deep label.mdc-label{margin-bottom:0}:host{--sd-c: var(--sd-primary)}:host(.sd-c-secondary){--sd-c: var(--sd-secondary)}:host(.sd-c-info){--sd-c: var(--sd-info)}:host(.sd-c-success){--sd-c: var(--sd-success)}:host(.sd-c-warning){--sd-c: var(--sd-warning)}:host(.sd-c-error){--sd-c: var(--sd-error)}:host ::ng-deep .mat-mdc-radio-button,:host ::ng-deep .mat-mdc-radio-group,:host ::ng-deep .mdc-radio{--mdc-radio-selected-icon-color: var(--sd-c) !important;--mdc-radio-selected-focus-icon-color: var(--sd-c) !important;--mdc-radio-selected-hover-icon-color: var(--sd-c) !important;--mdc-radio-selected-pressed-icon-color: var(--sd-c) !important;--mdc-radio-selected-focus-state-layer-color: var(--sd-c) !important;--mdc-radio-selected-hover-state-layer-color: var(--sd-c) !important;--mat-radio-selected-icon-color: var(--sd-c) !important;--mat-radio-selected-focus-icon-color: var(--sd-c) !important;--mat-radio-selected-hover-icon-color: var(--sd-c) !important;--mat-radio-selected-pressed-icon-color: var(--sd-c) !important;--mat-radio-checked-ripple-color: var(--sd-c) !important;--mat-radio-checked-state-layer-color: var(--sd-c) !important}.c-section{align-content:center;align-items:center}.c-radio-group-column{flex:1;display:flex;flex-direction:column;align-items:flex-start}.c-radio-group-row{flex:1;display:flex;flex-direction:row;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i4.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i4.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "component", type: SdLabel, selector: "sd-label", inputs: ["label", "description", "required", "helperText"] }, { kind: "directive", type: SdHrefDirective, selector: "a[sdHref]", inputs: ["sdHref"] }, { kind: "pipe", type: SdEmptyPipe, name: "sdEmpty" }, { kind: "pipe", type: SdTranslatePipe, name: "sdTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
149
149
|
}
|
|
150
150
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdRadio, decorators: [{
|
|
151
151
|
type: Component,
|
|
@@ -167,8 +167,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
167
167
|
SdLabel,
|
|
168
168
|
SdEmptyPipe,
|
|
169
169
|
SdHrefDirective,
|
|
170
|
-
|
|
171
|
-
], template: "@let _sdLabelDef = sdLabelDef();\n@let _sdSuffixDef = sdSuffixDef();\n@let _label = label();\n@let _display = display();\n@let _valueField = valueField();\n@let _hyperlink = hyperlink();\n\n@if (isViewed()) {\n @if (_sdLabelDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container>\n } @else if (_label) {\n <div class=\"T14R text-secondary\">{{ _label }}</div>\n }\n @if (_hyperlink) {\n <!-- N\u1EBFu c\u00F3 hyperlink th\u00EC d\u00F9ng th\u1EBB a -->\n <a [sdHref]=\"_hyperlink!\">{{ viewedText() || placeholder() }}</a>\n } @else {\n <!-- Ngo\u00E0i ra d\u00F9ng th\u1EBB m\u1EB7c \u0111\u1ECBnh -->\n <div class=\"T14M\">{{ viewedText() || placeholder() | sdEmpty }}</div>\n }\n} @else {\n <section [ngClass]=\"{ 'c-section': _display === 'row' }\">\n @if (_sdLabelDef?.templateRef) {\n <div [id]=\"labelId\"><ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container></div>\n } @else if (_label) {\n <sd-label [attr.id]=\"labelId\" [label]=\"_label!\" [required]=\"required()\"></sd-label>\n }\n <mat-radio-group\n [class.c-radio-group-column]=\"_display === 'column'\"\n [class.c-radio-group-row]=\"_display === 'row'\"\n [formControl]=\"formControl\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-required]=\"dataRequired()\">\n @for (item of normalizedItems(); track item[valueField()]) {\n <mat-radio-button [class.m-0]=\"_display === 'column'\" [class.mr-16]=\"_display === 'row'\" [value]=\"item[_valueField]\">\n {{ item[displayField()] }}\n </mat-radio-button>\n }\n </mat-radio-group>\n\n @if (_sdSuffixDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdSuffixDef!.templateRef\"> </ng-container>\n }\n\n @if (visibleError() === 'required') {\n <mat-error [id]=\"errorId\">\n {{ 'core.form.radio.required' |
|
|
170
|
+
SdTranslatePipe,
|
|
171
|
+
], template: "@let _sdLabelDef = sdLabelDef();\n@let _sdSuffixDef = sdSuffixDef();\n@let _label = label();\n@let _display = display();\n@let _valueField = valueField();\n@let _hyperlink = hyperlink();\n\n@if (isViewed()) {\n @if (_sdLabelDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container>\n } @else if (_label) {\n <div class=\"T14R text-secondary\">{{ _label }}</div>\n }\n @if (_hyperlink) {\n <!-- N\u1EBFu c\u00F3 hyperlink th\u00EC d\u00F9ng th\u1EBB a -->\n <a [sdHref]=\"_hyperlink!\">{{ viewedText() || placeholder() }}</a>\n } @else {\n <!-- Ngo\u00E0i ra d\u00F9ng th\u1EBB m\u1EB7c \u0111\u1ECBnh -->\n <div class=\"T14M\">{{ viewedText() || placeholder() | sdEmpty }}</div>\n }\n} @else {\n <section [ngClass]=\"{ 'c-section': _display === 'row' }\">\n @if (_sdLabelDef?.templateRef) {\n <div [id]=\"labelId\"><ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container></div>\n } @else if (_label) {\n <sd-label [attr.id]=\"labelId\" [label]=\"_label!\" [required]=\"required()\"></sd-label>\n }\n <mat-radio-group\n [class.c-radio-group-column]=\"_display === 'column'\"\n [class.c-radio-group-row]=\"_display === 'row'\"\n [formControl]=\"formControl\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-required]=\"dataRequired()\">\n @for (item of normalizedItems(); track item[valueField()]) {\n <mat-radio-button [class.m-0]=\"_display === 'column'\" [class.mr-16]=\"_display === 'row'\" [value]=\"item[_valueField]\">\n {{ item[displayField()] }}\n </mat-radio-button>\n }\n </mat-radio-group>\n\n @if (_sdSuffixDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdSuffixDef!.templateRef\"> </ng-container>\n }\n\n @if (visibleError() === 'required') {\n <mat-error [id]=\"errorId\">\n {{ 'core.form.radio.required' | sdTranslate }}\n </mat-error>\n } @else if (visibleError() === 'inlineError') {\n <mat-error [id]=\"errorId\">\n {{ inlineError() }}\n </mat-error>\n }\n </section>\n}\n", styles: [":host{height:100%;display:flex;flex-direction:column}:host ::ng-deep label.mdc-label{margin-bottom:0}:host{--sd-c: var(--sd-primary)}:host(.sd-c-secondary){--sd-c: var(--sd-secondary)}:host(.sd-c-info){--sd-c: var(--sd-info)}:host(.sd-c-success){--sd-c: var(--sd-success)}:host(.sd-c-warning){--sd-c: var(--sd-warning)}:host(.sd-c-error){--sd-c: var(--sd-error)}:host ::ng-deep .mat-mdc-radio-button,:host ::ng-deep .mat-mdc-radio-group,:host ::ng-deep .mdc-radio{--mdc-radio-selected-icon-color: var(--sd-c) !important;--mdc-radio-selected-focus-icon-color: var(--sd-c) !important;--mdc-radio-selected-hover-icon-color: var(--sd-c) !important;--mdc-radio-selected-pressed-icon-color: var(--sd-c) !important;--mdc-radio-selected-focus-state-layer-color: var(--sd-c) !important;--mdc-radio-selected-hover-state-layer-color: var(--sd-c) !important;--mat-radio-selected-icon-color: var(--sd-c) !important;--mat-radio-selected-focus-icon-color: var(--sd-c) !important;--mat-radio-selected-hover-icon-color: var(--sd-c) !important;--mat-radio-selected-pressed-icon-color: var(--sd-c) !important;--mat-radio-checked-ripple-color: var(--sd-c) !important;--mat-radio-checked-state-layer-color: var(--sd-c) !important}.c-section{align-content:center;align-items:center}.c-radio-group-column{flex:1;display:flex;flex-direction:column;align-items:flex-start}.c-radio-group-row{flex:1;display:flex;flex-direction:row;align-items:center}\n"] }]
|
|
172
172
|
}], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], display: [{ type: i0.Input, args: [{ isSignal: true, alias: "display", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: true }] }], displayField: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayField", required: true }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], inlineError: [{ type: i0.Input, args: [{ isSignal: true, alias: "inlineError", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], viewed: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewed", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], hyperlink: [{ type: i0.Input, args: [{ isSignal: true, alias: "hyperlink", required: false }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }, { type: i0.Output, args: ["modelChange"] }], sdSuffixDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdSuffixDefDirective), { isSignal: true }] }], sdLabelDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdLabelDefDirective), { isSignal: true }] }], sdViewDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdViewDefDirective), { isSignal: true }] }], sdChange: [{ type: i0.Output, args: ["sdChange"] }], sdSelection: [{ type: i0.Output, args: ["sdSelection"] }] } });
|
|
173
173
|
|
|
174
174
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdcorejs-angular-forms-radio.mjs","sources":["../../../projects/sdcorejs-angular/forms/radio/src/radio.component.ts","../../../projects/sdcorejs-angular/forms/radio/src/radio.component.html","../../../projects/sdcorejs-angular/forms/radio/sdcorejs-angular-forms-radio.ts"],"sourcesContent":["import { Utilities } from '@sdcorejs/utils/fns';\n\nimport { CommonModule } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n contentChild,\n inject,\n input,\n model,\n OnDestroy,\n OnInit,\n output,\n} from '@angular/core';\nimport { ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatRadioModule } from '@angular/material/radio';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { Subscription } from 'rxjs';\n\nimport { SdLabelDefDirective, SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';\n\nimport {\n SdFormControl,\n SdInlineErrorValidator,\n sdFormControlState,\n SdViewed,\n SdViewedInput,\n sdViewedInline,\n sdViewedTransform,\n ɵsdFormControlConnector,\n ɵSdFormControlParent,\n} from '@sdcorejs/angular/forms/models';\nimport { sdIsEmpty, sdSerializeDataValue } from '@sdcorejs/angular/utilities/data-state';\nimport { Color } from '@sdcorejs/utils/models';\nimport { TranslatePipe } from '@sdcorejs/angular/i18n';\nimport { SdEmptyPipe } from '@sdcorejs/angular/pipes';\nimport { SdLabel } from '@sdcorejs/angular/forms/label';\nimport { SdHrefDirective } from '@sdcorejs/angular/directives';\n\n@Component({\n selector: 'sd-radio',\n templateUrl: './radio.component.html',\n styleUrl: './radio.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n host: {\n // why: host class .sd-c-<x> + default sd-c-primary cho fallback. Thay data-sd-color\n // để tránh edge case host-attr-binding không reactive trong vài cảnh build pipeline.\n '[class.sd-c-primary]': \"color() === 'primary'\",\n '[class.sd-c-secondary]': \"color() === 'secondary'\",\n '[class.sd-c-info]': \"color() === 'info'\",\n '[class.sd-c-success]': \"color() === 'success'\",\n '[class.sd-c-warning]': \"color() === 'warning'\",\n '[class.sd-c-error]': \"color() === 'error'\",\n },\n imports: [\n CommonModule,\n ReactiveFormsModule,\n MatTooltipModule,\n MatFormFieldModule,\n MatRadioModule,\n SdLabel,\n SdEmptyPipe,\n SdHrefDirective,\n TranslatePipe,\n ],\n})\nexport class SdRadio implements OnInit, OnDestroy {\n readonly #ref = inject(ChangeDetectorRef);\n\n readonly id = `I${Utilities.generateUuid()}`;\n readonly labelId = `${this.id}-label`;\n readonly errorId = `${this.id}-error`;\n readonly #defaultName = Utilities.generateUuid();\n formControl = new SdFormControl();\n #subscription = new Subscription();\n\n // Inputs — accept null|undefined at boundary, transform to canonical\n readonly autoIdInput = input<string | undefined, string | null | undefined>(undefined, {\n alias: 'autoId',\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly name = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly form = input<ɵSdFormControlParent>(undefined);\n readonly label = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly placeholder = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly display = input<'row' | 'column', 'row' | 'column' | null | undefined>('row', {\n transform: (v): 'row' | 'column' => v || 'row',\n });\n readonly items = input<any[], any[] | null | undefined>([], {\n transform: (v): any[] => (Array.isArray(v) ? v : []),\n });\n readonly valueField = input.required<string>();\n readonly displayField = input.required<string>();\n readonly required = input(false, { transform: booleanAttribute });\n readonly inlineError = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Display mode: `false` edit · `true` static view · `'inline'` interactive (disabled `'inline'` → static). */\n readonly viewed = input<SdViewed, SdViewedInput>(false, { transform: sdViewedTransform });\n\n // why: tri-state viewed — `'inline'` keeps the radio group interactive; disabled `'inline'` → static.\n readonly #viewedState = sdViewedInline(this.viewed, undefined, this.disabled);\n /** `true` when the static read-only view should render. */\n readonly isViewed = this.#viewedState.isViewed;\n // why: legacy callers pass `null` → fallback to 'primary'. Color enum mở rộng hơn ThemePalette,\n // áp dụng qua host attr [data-sd-color] + SCSS override MDC token vars (mat [color] không nhận 'success'/'info'/...).\n readonly color = input<Color, Color | null | undefined>('primary', {\n transform: (v): Color => v || 'primary',\n });\n readonly hyperlink = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n\n // Two-way model\n readonly model = model<number | string | boolean | undefined | null>(undefined);\n\n // Content children\n readonly sdSuffixDef = contentChild(SdSuffixDefDirective);\n readonly sdLabelDef = contentChild(SdLabelDefDirective);\n readonly sdViewDef = contentChild(SdViewDefDirective);\n\n // Outputs (modelChange auto-generated by model() signal)\n readonly sdChange = output<unknown>();\n readonly sdSelection = output<{ value: any | any[]; item?: any }>();\n\n // Computed (template bindings)\n readonly autoId = computed(() => (this.autoIdInput() ? `forms-radio-${this.autoIdInput()}` : undefined));\n // Kept for back-compat with templates that read `normalizedItems()` — alias of items()\n readonly normalizedItems = computed(() => this.items());\n readonly #state = sdFormControlState(computed(() => this.formControl));\n readonly dataDisabled = computed(() => (this.#state().disabled ? 'true' : 'false'));\n readonly dataEmpty = computed(() => (sdIsEmpty(this.#state().value) ? 'true' : 'false'));\n readonly dataValue = computed(() => sdSerializeDataValue(this.#state().value));\n readonly dataRequired = computed(() => (this.required() ? 'true' : 'false'));\n readonly visibleError = computed<'required' | 'inlineError' | undefined>(() => {\n if (!this.#state().touched) return undefined;\n if (this.formControl.hasError('required')) return 'required';\n if (this.formControl.hasError('inlineError')) return 'inlineError';\n return undefined;\n });\n readonly ariaLabelledBy = computed(() => (this.sdLabelDef()?.templateRef || this.label() ? this.labelId : undefined));\n readonly ariaLabel = computed(() => (this.ariaLabelledBy() ? undefined : this.placeholder() || undefined));\n readonly ariaDescribedBy = computed(() => (this.visibleError() ? this.errorId : undefined));\n readonly ariaInvalid = computed(() => (this.#state().invalid ? 'true' : 'false'));\n\n readonly viewedText = computed(() => {\n const items = this.items();\n const vField = this.valueField();\n const dField = this.displayField();\n // why: tìm item match value rồi trả về string ở `displayField`, không trả nguyên object (sẽ in [object Object]).\n const match = items.find(e => this.formControl?.value?.toString() === e?.[vField]?.toString());\n return match?.[dField] ?? '';\n });\n\n readonly #formConnector = ɵsdFormControlConnector<\n number | string | boolean | undefined | null,\n number | string | boolean | undefined | null\n >({\n form: this.form,\n name: computed(() => this.name() || this.#defaultName),\n control: computed(() => this.formControl),\n model: this.model,\n writeModel: value => {\n const vField = this.valueField();\n this.model.set(value);\n this.sdChange.emit(value);\n this.sdSelection.emit({\n value,\n item: this.items().find(item => value?.toString() === item?.[vField]?.toString()),\n });\n },\n validators: computed(() => {\n const validators: ValidatorFn[] = [];\n if (this.required()) validators.push(Validators.required);\n if (this.inlineError()) validators.push(SdInlineErrorValidator);\n return validators;\n }),\n disabled: this.disabled,\n });\n\n ngOnInit() {\n this.#subscription.add(\n this.formControl.sdChanges.subscribe(() => {\n this.#ref.markForCheck();\n })\n );\n }\n\n ngOnDestroy() {\n this.#subscription.unsubscribe();\n }\n\n reValidate = () => {\n this.formControl.updateValueAndValidity({ emitEvent: true });\n };\n}\n","@let _sdLabelDef = sdLabelDef();\n@let _sdSuffixDef = sdSuffixDef();\n@let _label = label();\n@let _display = display();\n@let _valueField = valueField();\n@let _hyperlink = hyperlink();\n\n@if (isViewed()) {\n @if (_sdLabelDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container>\n } @else if (_label) {\n <div class=\"T14R text-secondary\">{{ _label }}</div>\n }\n @if (_hyperlink) {\n <!-- Nếu có hyperlink thì dùng thẻ a -->\n <a [sdHref]=\"_hyperlink!\">{{ viewedText() || placeholder() }}</a>\n } @else {\n <!-- Ngoài ra dùng thẻ mặc định -->\n <div class=\"T14M\">{{ viewedText() || placeholder() | sdEmpty }}</div>\n }\n} @else {\n <section [ngClass]=\"{ 'c-section': _display === 'row' }\">\n @if (_sdLabelDef?.templateRef) {\n <div [id]=\"labelId\"><ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container></div>\n } @else if (_label) {\n <sd-label [attr.id]=\"labelId\" [label]=\"_label!\" [required]=\"required()\"></sd-label>\n }\n <mat-radio-group\n [class.c-radio-group-column]=\"_display === 'column'\"\n [class.c-radio-group-row]=\"_display === 'row'\"\n [formControl]=\"formControl\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-required]=\"dataRequired()\">\n @for (item of normalizedItems(); track item[valueField()]) {\n <mat-radio-button [class.m-0]=\"_display === 'column'\" [class.mr-16]=\"_display === 'row'\" [value]=\"item[_valueField]\">\n {{ item[displayField()] }}\n </mat-radio-button>\n }\n </mat-radio-group>\n\n @if (_sdSuffixDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdSuffixDef!.templateRef\"> </ng-container>\n }\n\n @if (visibleError() === 'required') {\n <mat-error [id]=\"errorId\">\n {{ 'core.form.radio.required' | translate }}\n </mat-error>\n } @else if (visibleError() === 'inlineError') {\n <mat-error [id]=\"errorId\">\n {{ inlineError() }}\n </mat-error>\n }\n </section>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵsdFormControlConnector"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sdcorejs-angular-forms-radio.mjs","sources":["../../../projects/sdcorejs-angular/forms/radio/src/radio.component.ts","../../../projects/sdcorejs-angular/forms/radio/src/radio.component.html","../../../projects/sdcorejs-angular/forms/radio/sdcorejs-angular-forms-radio.ts"],"sourcesContent":["import { Utilities } from '@sdcorejs/utils/fns';\n\nimport { CommonModule } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n contentChild,\n inject,\n input,\n model,\n OnDestroy,\n OnInit,\n output,\n} from '@angular/core';\nimport { ReactiveFormsModule, ValidatorFn, Validators } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatRadioModule } from '@angular/material/radio';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { Subscription } from 'rxjs';\n\nimport { SdLabelDefDirective, SdSuffixDefDirective, SdViewDefDirective } from '@sdcorejs/angular/forms/directives';\n\nimport {\n SdFormControl,\n SdInlineErrorValidator,\n sdFormControlState,\n SdViewed,\n SdViewedInput,\n sdViewedInline,\n sdViewedTransform,\n ɵsdFormControlConnector,\n ɵSdFormControlParent,\n} from '@sdcorejs/angular/forms/models';\nimport { sdIsEmpty, sdSerializeDataValue } from '@sdcorejs/angular/utilities/data-state';\nimport { Color } from '@sdcorejs/utils/models';\nimport { SdTranslatePipe } from '@sdcorejs/angular/i18n';\nimport { SdEmptyPipe } from '@sdcorejs/angular/pipes';\nimport { SdLabel } from '@sdcorejs/angular/forms/label';\nimport { SdHrefDirective } from '@sdcorejs/angular/directives';\n\n@Component({\n selector: 'sd-radio',\n templateUrl: './radio.component.html',\n styleUrl: './radio.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n host: {\n // why: host class .sd-c-<x> + default sd-c-primary cho fallback. Thay data-sd-color\n // để tránh edge case host-attr-binding không reactive trong vài cảnh build pipeline.\n '[class.sd-c-primary]': \"color() === 'primary'\",\n '[class.sd-c-secondary]': \"color() === 'secondary'\",\n '[class.sd-c-info]': \"color() === 'info'\",\n '[class.sd-c-success]': \"color() === 'success'\",\n '[class.sd-c-warning]': \"color() === 'warning'\",\n '[class.sd-c-error]': \"color() === 'error'\",\n },\n imports: [\n CommonModule,\n ReactiveFormsModule,\n MatTooltipModule,\n MatFormFieldModule,\n MatRadioModule,\n SdLabel,\n SdEmptyPipe,\n SdHrefDirective,\n SdTranslatePipe,\n ],\n})\nexport class SdRadio implements OnInit, OnDestroy {\n readonly #ref = inject(ChangeDetectorRef);\n\n readonly id = `I${Utilities.generateUuid()}`;\n readonly labelId = `${this.id}-label`;\n readonly errorId = `${this.id}-error`;\n readonly #defaultName = Utilities.generateUuid();\n formControl = new SdFormControl();\n #subscription = new Subscription();\n\n // Inputs — accept null|undefined at boundary, transform to canonical\n readonly autoIdInput = input<string | undefined, string | null | undefined>(undefined, {\n alias: 'autoId',\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly name = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly form = input<ɵSdFormControlParent>(undefined);\n readonly label = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly placeholder = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly display = input<'row' | 'column', 'row' | 'column' | null | undefined>('row', {\n transform: (v): 'row' | 'column' => v || 'row',\n });\n readonly items = input<any[], any[] | null | undefined>([], {\n transform: (v): any[] => (Array.isArray(v) ? v : []),\n });\n readonly valueField = input.required<string>();\n readonly displayField = input.required<string>();\n readonly required = input(false, { transform: booleanAttribute });\n readonly inlineError = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Display mode: `false` edit · `true` static view · `'inline'` interactive (disabled `'inline'` → static). */\n readonly viewed = input<SdViewed, SdViewedInput>(false, { transform: sdViewedTransform });\n\n // why: tri-state viewed — `'inline'` keeps the radio group interactive; disabled `'inline'` → static.\n readonly #viewedState = sdViewedInline(this.viewed, undefined, this.disabled);\n /** `true` when the static read-only view should render. */\n readonly isViewed = this.#viewedState.isViewed;\n // why: legacy callers pass `null` → fallback to 'primary'. Color enum mở rộng hơn ThemePalette,\n // áp dụng qua host attr [data-sd-color] + SCSS override MDC token vars (mat [color] không nhận 'success'/'info'/...).\n readonly color = input<Color, Color | null | undefined>('primary', {\n transform: (v): Color => v || 'primary',\n });\n readonly hyperlink = input<string | undefined, string | null | undefined>(undefined, {\n transform: (v): string | undefined => v ?? undefined,\n });\n\n // Two-way model\n readonly model = model<number | string | boolean | undefined | null>(undefined);\n\n // Content children\n readonly sdSuffixDef = contentChild(SdSuffixDefDirective);\n readonly sdLabelDef = contentChild(SdLabelDefDirective);\n readonly sdViewDef = contentChild(SdViewDefDirective);\n\n // Outputs (modelChange auto-generated by model() signal)\n readonly sdChange = output<unknown>();\n readonly sdSelection = output<{ value: any | any[]; item?: any }>();\n\n // Computed (template bindings)\n readonly autoId = computed(() => (this.autoIdInput() ? `forms-radio-${this.autoIdInput()}` : undefined));\n // Kept for back-compat with templates that read `normalizedItems()` — alias of items()\n readonly normalizedItems = computed(() => this.items());\n readonly #state = sdFormControlState(computed(() => this.formControl));\n readonly dataDisabled = computed(() => (this.#state().disabled ? 'true' : 'false'));\n readonly dataEmpty = computed(() => (sdIsEmpty(this.#state().value) ? 'true' : 'false'));\n readonly dataValue = computed(() => sdSerializeDataValue(this.#state().value));\n readonly dataRequired = computed(() => (this.required() ? 'true' : 'false'));\n readonly visibleError = computed<'required' | 'inlineError' | undefined>(() => {\n if (!this.#state().touched) return undefined;\n if (this.formControl.hasError('required')) return 'required';\n if (this.formControl.hasError('inlineError')) return 'inlineError';\n return undefined;\n });\n readonly ariaLabelledBy = computed(() => (this.sdLabelDef()?.templateRef || this.label() ? this.labelId : undefined));\n readonly ariaLabel = computed(() => (this.ariaLabelledBy() ? undefined : this.placeholder() || undefined));\n readonly ariaDescribedBy = computed(() => (this.visibleError() ? this.errorId : undefined));\n readonly ariaInvalid = computed(() => (this.#state().invalid ? 'true' : 'false'));\n\n readonly viewedText = computed(() => {\n const items = this.items();\n const vField = this.valueField();\n const dField = this.displayField();\n // why: tìm item match value rồi trả về string ở `displayField`, không trả nguyên object (sẽ in [object Object]).\n const match = items.find(e => this.formControl?.value?.toString() === e?.[vField]?.toString());\n return match?.[dField] ?? '';\n });\n\n readonly #formConnector = ɵsdFormControlConnector<\n number | string | boolean | undefined | null,\n number | string | boolean | undefined | null\n >({\n form: this.form,\n name: computed(() => this.name() || this.#defaultName),\n control: computed(() => this.formControl),\n model: this.model,\n writeModel: value => {\n const vField = this.valueField();\n this.model.set(value);\n this.sdChange.emit(value);\n this.sdSelection.emit({\n value,\n item: this.items().find(item => value?.toString() === item?.[vField]?.toString()),\n });\n },\n validators: computed(() => {\n const validators: ValidatorFn[] = [];\n if (this.required()) validators.push(Validators.required);\n if (this.inlineError()) validators.push(SdInlineErrorValidator);\n return validators;\n }),\n disabled: this.disabled,\n });\n\n ngOnInit() {\n this.#subscription.add(\n this.formControl.sdChanges.subscribe(() => {\n this.#ref.markForCheck();\n })\n );\n }\n\n ngOnDestroy() {\n this.#subscription.unsubscribe();\n }\n\n reValidate = () => {\n this.formControl.updateValueAndValidity({ emitEvent: true });\n };\n}\n","@let _sdLabelDef = sdLabelDef();\n@let _sdSuffixDef = sdSuffixDef();\n@let _label = label();\n@let _display = display();\n@let _valueField = valueField();\n@let _hyperlink = hyperlink();\n\n@if (isViewed()) {\n @if (_sdLabelDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container>\n } @else if (_label) {\n <div class=\"T14R text-secondary\">{{ _label }}</div>\n }\n @if (_hyperlink) {\n <!-- Nếu có hyperlink thì dùng thẻ a -->\n <a [sdHref]=\"_hyperlink!\">{{ viewedText() || placeholder() }}</a>\n } @else {\n <!-- Ngoài ra dùng thẻ mặc định -->\n <div class=\"T14M\">{{ viewedText() || placeholder() | sdEmpty }}</div>\n }\n} @else {\n <section [ngClass]=\"{ 'c-section': _display === 'row' }\">\n @if (_sdLabelDef?.templateRef) {\n <div [id]=\"labelId\"><ng-container *ngTemplateOutlet=\"_sdLabelDef!.templateRef\"> </ng-container></div>\n } @else if (_label) {\n <sd-label [attr.id]=\"labelId\" [label]=\"_label!\" [required]=\"required()\"></sd-label>\n }\n <mat-radio-group\n [class.c-radio-group-column]=\"_display === 'column'\"\n [class.c-radio-group-row]=\"_display === 'row'\"\n [formControl]=\"formControl\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-disabled]=\"dataDisabled()\"\n [attr.data-empty]=\"dataEmpty()\"\n [attr.data-value]=\"dataValue()\"\n [attr.data-required]=\"dataRequired()\"\n [attr.aria-labelledby]=\"ariaLabelledBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-required]=\"dataRequired()\">\n @for (item of normalizedItems(); track item[valueField()]) {\n <mat-radio-button [class.m-0]=\"_display === 'column'\" [class.mr-16]=\"_display === 'row'\" [value]=\"item[_valueField]\">\n {{ item[displayField()] }}\n </mat-radio-button>\n }\n </mat-radio-group>\n\n @if (_sdSuffixDef?.templateRef) {\n <ng-container *ngTemplateOutlet=\"_sdSuffixDef!.templateRef\"> </ng-container>\n }\n\n @if (visibleError() === 'required') {\n <mat-error [id]=\"errorId\">\n {{ 'core.form.radio.required' | sdTranslate }}\n </mat-error>\n } @else if (visibleError() === 'inlineError') {\n <mat-error [id]=\"errorId\">\n {{ inlineError() }}\n </mat-error>\n }\n </section>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵsdFormControlConnector"],"mappings":"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"}
|