@tekus/design-system 5.19.0 → 5.21.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.
Files changed (26) hide show
  1. package/components/checkbox/src/checkbox.component.d.ts +24 -0
  2. package/components/date-picker/src/date-picker.component.d.ts +112 -87
  3. package/components/drawer/src/drawer.component.d.ts +36 -9
  4. package/components/drawer/src/drawer.types.d.ts +5 -2
  5. package/components/drawer/src/services/drawer.service.d.ts +2 -2
  6. package/components/modal/src/modal.component.d.ts +86 -67
  7. package/components/modal/src/modal.types.d.ts +22 -2
  8. package/components/modal/src/services/modal.service.d.ts +15 -0
  9. package/components/radio-button/src/radio-button.component.d.ts +33 -3
  10. package/components/toolbar/src/toolbar.component.d.ts +55 -1
  11. package/core/types/public-api.d.ts +1 -0
  12. package/core/types/src/interception/index.d.ts +1 -0
  13. package/core/types/src/interception/interception.types.d.ts +21 -0
  14. package/fesm2022/tekus-design-system-components-checkbox.mjs +24 -6
  15. package/fesm2022/tekus-design-system-components-checkbox.mjs.map +1 -1
  16. package/fesm2022/tekus-design-system-components-date-picker.mjs +164 -165
  17. package/fesm2022/tekus-design-system-components-date-picker.mjs.map +1 -1
  18. package/fesm2022/tekus-design-system-components-drawer.mjs +130 -22
  19. package/fesm2022/tekus-design-system-components-drawer.mjs.map +1 -1
  20. package/fesm2022/tekus-design-system-components-modal.mjs +190 -89
  21. package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
  22. package/fesm2022/tekus-design-system-components-radio-button.mjs +53 -18
  23. package/fesm2022/tekus-design-system-components-radio-button.mjs.map +1 -1
  24. package/fesm2022/tekus-design-system-components-toolbar.mjs +72 -4
  25. package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
  26. package/package.json +9 -9
@@ -2,8 +2,13 @@ import { OnInit, OnDestroy } from '@angular/core';
2
2
  import { ControlValueAccessor, FormControl, NgControl } from '@angular/forms';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class CheckboxComponent implements ControlValueAccessor, OnInit, OnDestroy {
5
+ /** Internal references and injections */
5
6
  readonly ngControl: NgControl | null;
7
+ /**
8
+ * Initialize the component and register it as a ControlValueAccessor.
9
+ */
6
10
  constructor();
11
+ /** Properties and Signals */
7
12
  /**
8
13
  * @property {ModelSignal<any>} model
9
14
  * @description
@@ -68,17 +73,36 @@ export declare class CheckboxComponent implements ControlValueAccessor, OnInit,
68
73
  * Whether the checkbox is disabled.
69
74
  */
70
75
  disabled: import("@angular/core").ModelSignal<boolean>;
76
+ /** Component Methods */
71
77
  get effectiveControl(): FormControl;
72
78
  onChange: (value: unknown) => void;
73
79
  onTouched: () => void;
74
80
  private readonly subscription;
75
81
  ngOnInit(): void;
76
82
  ngOnDestroy(): void;
83
+ /**
84
+ * Implementation of ControlValueAccessor: Writes a new value from the form.
85
+ */
77
86
  writeValue(value: unknown): void;
87
+ /**
88
+ * Implementation of ControlValueAccessor: Registers a callback for change events.
89
+ */
78
90
  registerOnChange(fn: (value: unknown) => void): void;
91
+ /**
92
+ * Implementation of ControlValueAccessor: Registers a callback for touched events.
93
+ */
79
94
  registerOnTouched(fn: () => void): void;
95
+ /**
96
+ * Implementation of ControlValueAccessor: Sets the disabled state.
97
+ */
80
98
  setDisabledState?(isDisabled: boolean): void;
99
+ /**
100
+ * Handle model change events from the template.
101
+ */
81
102
  onModelChange(value: unknown): void;
103
+ /**
104
+ * Handle blur events to trigger onTouched.
105
+ */
82
106
  onBlur(): void;
83
107
  static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxComponent, never>;
84
108
  static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxComponent, "tk-checkbox", never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "binary": { "alias": "binary"; "required": false; "isSignal": true; }; "control": { "alias": "control"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "model": "modelChange"; "indeterminate": "indeterminateChange"; "disabled": "disabledChange"; }, never, never, true, never>;
@@ -1,163 +1,188 @@
1
- import { EventEmitter, OnInit, OnDestroy } from '@angular/core';
2
- import { FormControl, ControlValueAccessor } from '@angular/forms';
1
+ import { OnInit, OnDestroy } from '@angular/core';
2
+ import { FormControl, ControlValueAccessor, NgControl } from '@angular/forms';
3
3
  import * as i0 from "@angular/core";
4
4
  export type DateValue = Date | [Date, Date] | null;
5
5
  export declare class DatePickerComponent implements OnInit, OnDestroy, ControlValueAccessor {
6
+ /** Internal references and injections */
7
+ readonly ngControl: NgControl | null;
8
+ constructor();
6
9
  /**
7
- * @property {'single' | 'range'} selectionMode
10
+ * @property {InputSignal<'date' | 'time'>} variant
11
+ * @description
12
+ * Defines the visual and functional mode:
13
+ * - `'date'`: standard date/range picker
14
+ * - `'time'`: time-only picker
15
+ * @default 'date'
16
+ */
17
+ variant: import("@angular/core").InputSignal<"date" | "time">;
18
+ /**
19
+ * @property {InputSignal<'single' | 'range'>} selectionMode
8
20
  * @description
9
21
  * Defines how the datepicker behaves:
10
22
  * - `'single'`: select one date
11
23
  * - `'range'`: select a pair of dates [start, end]
12
24
  * @default 'range'
13
25
  */
14
- selectionMode: 'single' | 'range';
26
+ selectionMode: import("@angular/core").InputSignal<"single" | "range">;
15
27
  /**
16
- * @property {boolean} readonlyInput
28
+ * @property {InputSignal<boolean>} readonlyInput
17
29
  * @description
18
30
  * Disables manual typing in the input and forces the user to select via the calendar.
19
31
  * @default true
20
32
  */
21
- readonlyInput: boolean;
22
- /**
23
- * @property {boolean} disabled
24
- * @description
25
- * Disables component.
26
- * @default false
27
- */
28
- disabled: boolean;
33
+ readonlyInput: import("@angular/core").InputSignal<boolean>;
29
34
  /**
30
- * @property {boolean} showClear
35
+ * @property {InputSignal<boolean>} showClear
31
36
  * @description
32
37
  * Displays a clear button that resets the datepicker value.
33
38
  * @default true
34
39
  */
35
- showClear: boolean;
40
+ showClear: import("@angular/core").InputSignal<boolean>;
36
41
  /**
37
- * @property {boolean} showIcon
42
+ * @property {InputSignal<boolean>} showIcon
38
43
  * @description
39
- * Shows the calendar icon inside the input.
44
+ * Shows the calendar or clock icon inside the input.
40
45
  * @default true
41
46
  */
42
- showIcon: boolean;
47
+ showIcon: import("@angular/core").InputSignal<boolean>;
43
48
  /**
44
- * @property {string} dateFormat
49
+ * @property {InputSignal<string>} dateFormat
45
50
  * @description
46
51
  * Format used by PrimeNG for displaying dates.
47
52
  * @default 'mm/dd/yy'
48
53
  */
49
- dateFormat: string;
54
+ dateFormat: import("@angular/core").InputSignal<string>;
50
55
  /**
51
- * @property {Date | null} maxDate
56
+ * @property {InputSignal<string>} timeFormat
52
57
  * @description
53
- * Maximum selectable date. When set, the calendar will prevent selecting dates after this value.
54
- * Provide a JavaScript Date object. Use `null` to allow any future date.
55
- * @default null
58
+ * Format used by PrimeNG for displaying times.
59
+ * @default 'HH:mm'
56
60
  */
57
- maxDate: Date | null;
61
+ timeFormat: import("@angular/core").InputSignal<string>;
58
62
  /**
59
- * @property {Date | null} minDate
63
+ * @property {InputSignal<number>} stepHour
60
64
  * @description
61
- * Minimum selectable date. When set, the calendar will prevent selecting dates before this value.
62
- * Provide a JavaScript Date object. Use `null` to allow any past date.
63
- * @default null
65
+ * Hours to skip when clicking up/down.
66
+ * @default 1
64
67
  */
65
- minDate: Date | null;
68
+ stepHour: import("@angular/core").InputSignal<number>;
66
69
  /**
67
- * @property {string} labelText
70
+ * @property {InputSignal<number>} stepMinute
68
71
  * @description
69
- * Label shown by the float-label wrapper.
70
- * @default 'Select a date'
72
+ * Minutes to skip when clicking up/down.
73
+ * @default 1
71
74
  */
72
- labelText: string;
75
+ stepMinute: import("@angular/core").InputSignal<number>;
73
76
  /**
74
- * @private
75
- * @property {FormControl<DateValue>} internalControl
77
+ * @property {InputSignal<number>} stepSecond
76
78
  * @description
77
- * The internal FormControl used in the template. It handles value synchronization
78
- * for both CVA and the optional external control input.
79
+ * Seconds to skip when clicking up/down.
80
+ * @default 1
79
81
  */
80
- internalControl: FormControl<DateValue>;
82
+ stepSecond: import("@angular/core").InputSignal<number>;
81
83
  /**
82
- * @private
83
- * @property {Subscription} sub
84
- * @description Subscription to the valueChanges observable.
84
+ * @property {InputSignal<boolean>} showSeconds
85
+ * @description
86
+ * Whether to show seconds in the time picker.
87
+ * @default false
85
88
  */
86
- private sub;
87
- private onChange;
88
- private onTouched;
89
+ showSeconds: import("@angular/core").InputSignal<boolean>;
89
90
  /**
90
- * @property {FormControl<DateValue> | null} control
91
+ * @property {InputSignal<Date | null>} maxDate
91
92
  * @description
92
- * Allows passing an external FormControl (traditional Reactive Forms usage).
93
- * If provided, it overrides the internal control.
93
+ * Maximum selectable date.
94
+ * @default null
94
95
  */
95
- set control(ctrl: FormControl<DateValue> | null);
96
- get control(): FormControl<DateValue>;
96
+ maxDate: import("@angular/core").InputSignal<Date | null>;
97
97
  /**
98
- * @event handleSelect
98
+ * @property {InputSignal<Date | null>} minDate
99
99
  * @description
100
- * Emitted when:
101
- * - single mode → a valid Date is selected
102
- * - range mode → both start and end dates are selected
103
- *
104
- * Payload:
105
- * - Date (single mode)
106
- * - [Date, Date] (completed range)
100
+ * Minimum selectable date.
101
+ * @default null
107
102
  */
108
- handleSelect: EventEmitter<DateValue>;
103
+ minDate: import("@angular/core").InputSignal<Date | null>;
109
104
  /**
110
- * @event handleClear
105
+ * @property {InputSignal<string>} labelText
111
106
  * @description
112
- * Emitted when the control's value becomes `null`.
107
+ * Label shown by the float-label wrapper.
113
108
  */
114
- handleClear: EventEmitter<void>;
109
+ labelText: import("@angular/core").InputSignal<string>;
115
110
  /**
116
- * @property faCalendarDay
111
+ * @property {InputSignal<FormControl>} control
117
112
  * @description
118
- * Icon displayed inside the datepicker input.
113
+ * External FormControl used to read/set the datepicker value.
114
+ * If not provided, an internal FormControl is created.
119
115
  */
120
- faCalendarDay: import("@fortawesome/fontawesome-common-types").IconDefinition;
116
+ control: import("@angular/core").InputSignal<FormControl<any> | undefined>;
121
117
  /**
122
- * @method writeValue
123
- * @description Writes a new value from the form model (ngModel or formControl) into the component.
118
+ * @property {ModelSignal<DateValue>} modelValue
119
+ * @description
120
+ * The value of the datepicker model. Supports two-way binding.
124
121
  */
125
- writeValue(value: DateValue): void;
122
+ modelValue: import("@angular/core").ModelSignal<DateValue>;
123
+ /**
124
+ * @property {OutputRef<DateValue>} handleSelect
125
+ * @description
126
+ * Emitted when a value is selected.
127
+ */
128
+ handleSelect: import("@angular/core").OutputEmitterRef<DateValue>;
126
129
  /**
127
- * @method registerOnChange
128
- * @description Registers a callback function to be called when the control's value changes.
130
+ * @property {OutputRef<void>} handleClear
131
+ * @description
132
+ * Emitted when the value is cleared.
129
133
  */
130
- registerOnChange(fn: (value: DateValue) => void): void;
134
+ handleClear: import("@angular/core").OutputEmitterRef<void>;
135
+ /** Computed properties */
131
136
  /**
132
- * @method registerOnTouched
133
- * @description Registers a callback function to be called when the control receives a blur event (is touched).
137
+ * @property {Signal<'single' | 'range'>} effectiveSelectionMode
138
+ * @description
139
+ * Returns 'single' automatically if variant is 'time', otherwise returns the user-provided selectionMode.
134
140
  */
135
- registerOnTouched(fn: () => void): void;
141
+ effectiveSelectionMode: import("@angular/core").Signal<"single" | "range">;
136
142
  /**
137
- * @method setDisabledState
138
- * @description Called when the control should be disabled or enabled.
143
+ * @property {Signal<string>} effectiveDateFormat
144
+ * @description
145
+ * Returns the user-provided dateFormat or timeFormat based on the variant.
139
146
  */
140
- setDisabledState(isDisabled: boolean): void;
147
+ effectiveDateFormat: import("@angular/core").Signal<string>;
141
148
  /**
142
- * @method ngOnInit
149
+ * @property {Signal<FormControl>} effectiveControl
143
150
  * @description
144
- * Subscribes to the internal control's valueChanges:
145
- * 1. Notifies the external form (CVA) via `this.onChange()`.
146
- * 2. Emits the semantic events `handleSelect` or `handleClear`.
151
+ * Returns the external FormControl from NgControl or a local fallback.
147
152
  */
153
+ internalControl: FormControl<DateValue>;
154
+ get effectiveControl(): FormControl;
155
+ /** Icons */
156
+ faCalendarDay: import("@fortawesome/fontawesome-common-types").IconDefinition;
157
+ faClock: import("@fortawesome/fontawesome-common-types").IconDefinition;
158
+ /** CVA Logic */
159
+ onChange: (value: DateValue) => void;
160
+ onTouched: () => void;
161
+ private readonly sub;
148
162
  ngOnInit(): void;
163
+ ngOnDestroy(): void;
164
+ writeValue(value: DateValue): void;
165
+ registerOnChange(fn: (value: DateValue) => void): void;
166
+ registerOnTouched(fn: () => void): void;
167
+ setDisabledState(isDisabled: boolean): void;
149
168
  /**
150
- * @method ngOnDestroy
151
- * @description Cleans up the internal subscription when the component is destroyed.
169
+ * @method onModelChange
170
+ * @description
171
+ * Called when the PrimeNG DatePicker template updates the value.
152
172
  */
153
- ngOnDestroy(): void;
173
+ onModelChange(value: DateValue): void;
174
+ /**
175
+ * @method onBlur
176
+ * @description
177
+ * Triggered when the component loses focus.
178
+ */
179
+ onBlur(): void;
154
180
  /**
155
181
  * @method clear
156
182
  * @description
157
- * Programmatically clears the control's value,
158
- * which automatically triggers `handleClear`.
183
+ * Programmatically clears the value.
159
184
  */
160
185
  clear(): void;
161
186
  static ɵfac: i0.ɵɵFactoryDeclaration<DatePickerComponent, never>;
162
- static ɵcmp: i0.ɵɵComponentDeclaration<DatePickerComponent, "tk-date-picker", never, { "selectionMode": { "alias": "selectionMode"; "required": false; }; "readonlyInput": { "alias": "readonlyInput"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "showClear": { "alias": "showClear"; "required": false; }; "showIcon": { "alias": "showIcon"; "required": false; }; "dateFormat": { "alias": "dateFormat"; "required": false; }; "maxDate": { "alias": "maxDate"; "required": false; }; "minDate": { "alias": "minDate"; "required": false; }; "labelText": { "alias": "labelText"; "required": false; }; "control": { "alias": "control"; "required": false; }; }, { "handleSelect": "handleSelect"; "handleClear": "handleClear"; }, never, never, true, never>;
187
+ static ɵcmp: i0.ɵɵComponentDeclaration<DatePickerComponent, "tk-date-picker", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "readonlyInput": { "alias": "readonlyInput"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "showIcon": { "alias": "showIcon"; "required": false; "isSignal": true; }; "dateFormat": { "alias": "dateFormat"; "required": false; "isSignal": true; }; "timeFormat": { "alias": "timeFormat"; "required": false; "isSignal": true; }; "stepHour": { "alias": "stepHour"; "required": false; "isSignal": true; }; "stepMinute": { "alias": "stepMinute"; "required": false; "isSignal": true; }; "stepSecond": { "alias": "stepSecond"; "required": false; "isSignal": true; }; "showSeconds": { "alias": "showSeconds"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "labelText": { "alias": "labelText"; "required": false; "isSignal": true; }; "control": { "alias": "control"; "required": false; "isSignal": true; }; "modelValue": { "alias": "modelValue"; "required": false; "isSignal": true; }; }, { "modelValue": "modelValueChange"; "handleSelect": "handleSelect"; "handleClear": "handleClear"; }, never, never, true, never>;
163
188
  }
@@ -1,5 +1,6 @@
1
- import { EventEmitter, Type, ElementRef } from '@angular/core';
1
+ import { EventEmitter, Type, ElementRef, OnDestroy } from '@angular/core';
2
2
  import { DrawerHeaderAction, DrawerSizeType } from './drawer.types';
3
+ import { TkCloseInterceptor } from '@tekus/design-system/core/types';
3
4
  import * as i0 from "@angular/core";
4
5
  /**
5
6
  * @component DrawerComponent
@@ -33,14 +34,16 @@ import * as i0 from "@angular/core";
33
34
  * console.log('Drawer closed with value:', result);
34
35
  * });
35
36
  * ```
37
+ * Modernized for Angular 19 with 100% synchronous Signal-based closing interception.
36
38
  */
37
- export declare class DrawerComponent {
39
+ export declare class DrawerComponent<T = unknown> implements OnDestroy {
38
40
  private readonly elementRef;
39
- constructor(elementRef: ElementRef);
41
+ private readonly contentHost;
42
+ private componentRef?;
40
43
  /** The required title displayed at the top left of the drawer header */
41
44
  title: import("@angular/core").InputSignal<string>;
42
- /** The main content of the drawer */
43
- content: import("@angular/core").InputSignal<string | Type<unknown> | null>;
45
+ /** The main content of the drawer. Can be a string or a Component Type. */
46
+ content: import("@angular/core").InputSignal<string | Type<T> | null>;
44
47
  /** Optional header action button (displayed before close button) */
45
48
  headerAction: import("@angular/core").InputSignal<DrawerHeaderAction | null>;
46
49
  /** Drawer size: 'small' (500px), 'large' (1024px) */
@@ -49,6 +52,10 @@ export declare class DrawerComponent {
49
52
  closable: import("@angular/core").InputSignal<boolean>;
50
53
  /** Whether clicking the mask closes the drawer */
51
54
  dismissible: import("@angular/core").InputSignal<boolean>;
55
+ /** Optional data to be passed as inputs to the dynamic component. */
56
+ data: import("@angular/core").InputSignal<Partial<T>>;
57
+ /** Optional interceptor called before the drawer closes. */
58
+ interceptor: import("@angular/core").InputSignal<TkCloseInterceptor | undefined>;
52
59
  isContentString: import("@angular/core").Signal<boolean>;
53
60
  hasHeaderAction: import("@angular/core").Signal<boolean>;
54
61
  /** Computed: drawer width (responsive) and max-width based on `size`. Always right position. */
@@ -58,21 +65,41 @@ export declare class DrawerComponent {
58
65
  }>;
59
66
  /** Visibility flag. Use model for two-way binding when using drawer in template. */
60
67
  isOpened: import("@angular/core").ModelSignal<boolean>;
68
+ /** Whether the drawer content has a scrollbar */
69
+ hasScroll: boolean;
61
70
  /** Emits when the drawer closes, passing the return value from header action or null */
62
71
  readonly onClose: EventEmitter<unknown>;
63
72
  private alreadyEmitted;
64
73
  private returnValueOnClose;
74
+ constructor(elementRef: ElementRef);
75
+ ngOnDestroy(): void;
76
+ private attachDynamicContent;
77
+ private syncDynamicInputs;
78
+ private detachDynamicContent;
79
+ /**
80
+ * Checks if the drawer content has a scrollbar and updates `hasScroll` state.
81
+ */
82
+ checkScroll(): void;
65
83
  /** Opens the drawer */
66
84
  open(): void;
85
+ /**
86
+ * @summary Main entry point for closure requests.
87
+ * @returns true if closure was executed.
88
+ */
89
+ tryClose(returnValue?: unknown): boolean;
90
+ private canExecuteClosure;
91
+ private executeClosure;
92
+ /** Handles external visibility changes (from p-drawer close button or mask) */
93
+ onVisibleChange(visible: boolean): void;
67
94
  /** Closes the drawer and emits onClose */
68
95
  handleClose(): void;
69
- /** Closes the drawer without emitting an event */
96
+ /** Forcefully closes the drawer without checks */
70
97
  close(): void;
71
98
  /**
72
99
  * Handles header action button click.
73
- * Executes the action callback, emits onClose with the provided returnValue, then closes the drawer.
74
100
  */
75
101
  handleHeaderAction(action: (() => void) | undefined, returnValue: unknown): void;
76
- static ɵfac: i0.ɵɵFactoryDeclaration<DrawerComponent, never>;
77
- static ɵcmp: i0.ɵɵComponentDeclaration<DrawerComponent, "tk-drawer", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "content": { "alias": "content"; "required": false; "isSignal": true; }; "headerAction": { "alias": "headerAction"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "isOpened": { "alias": "isOpened"; "required": false; "isSignal": true; }; }, { "isOpened": "isOpenedChange"; }, never, never, true, never>;
102
+ private resetClosureState;
103
+ static ɵfac: i0.ɵɵFactoryDeclaration<DrawerComponent<any>, never>;
104
+ static ɵcmp: i0.ɵɵComponentDeclaration<DrawerComponent<any>, "tk-drawer", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "content": { "alias": "content"; "required": false; "isSignal": true; }; "headerAction": { "alias": "headerAction"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "interceptor": { "alias": "interceptor"; "required": false; "isSignal": true; }; "isOpened": { "alias": "isOpened"; "required": false; "isSignal": true; }; }, { "isOpened": "isOpenedChange"; }, never, never, true, never>;
78
105
  }
@@ -1,6 +1,7 @@
1
1
  import { Type } from '@angular/core';
2
2
  import { Variant } from '@tekus/design-system/components/button';
3
3
  import { SeverityType } from '@tekus/design-system/components/modal';
4
+ import { TkCloseInterceptor } from '@tekus/design-system/core/types';
4
5
  export type DrawerSizeType = 'small' | 'large';
5
6
  export interface DrawerHeaderAction {
6
7
  label: string;
@@ -9,11 +10,13 @@ export interface DrawerHeaderAction {
9
10
  returnValue?: unknown;
10
11
  variant?: Variant;
11
12
  }
12
- export interface DrawerConfig {
13
+ export interface DrawerConfig<T = unknown> {
13
14
  title: string;
14
- content?: string | Type<unknown>;
15
+ content?: string | Type<T>;
15
16
  headerAction?: DrawerHeaderAction;
16
17
  size?: DrawerSizeType;
17
18
  closable?: boolean;
18
19
  dismissible?: boolean;
20
+ data?: Partial<T>;
21
+ interceptor?: TkCloseInterceptor;
19
22
  }
@@ -7,8 +7,8 @@ export declare class DrawerService {
7
7
  private readonly appRef;
8
8
  private drawerRef;
9
9
  constructor(appRef: ApplicationRef);
10
- get _drawerRefForTesting(): ComponentRef<DrawerComponent> | null;
11
- set _drawerRefForTesting(ref: ComponentRef<DrawerComponent> | null);
10
+ get _drawerRefForTesting(): ComponentRef<DrawerComponent<unknown>> | null;
11
+ set _drawerRefForTesting(ref: ComponentRef<DrawerComponent<unknown>> | null);
12
12
  open(config: DrawerConfig): Observable<unknown>;
13
13
  static ɵfac: i0.ɵɵFactoryDeclaration<DrawerService, never>;
14
14
  static ɵprov: i0.ɵɵInjectableDeclaration<DrawerService>;
@@ -1,99 +1,118 @@
1
- import { EventEmitter, Type, ElementRef } from '@angular/core';
1
+ import { EventEmitter, Type, ElementRef, OnDestroy } from '@angular/core';
2
2
  import { ModalFooterButton, ModalSizeType } from './modal.types';
3
+ import { TkCloseInterceptor } from '@tekus/design-system/core/types';
3
4
  import * as i0 from "@angular/core";
4
5
  /**
5
6
  * @component ModalComponent
6
7
  * @description
7
- * A programmatically controlled modal dialog used for displaying dynamic content, titles, and footer actions.
8
- * The modal is not instantiated via template bindings, but rather opened through a service with a configuration object.
9
- *
10
- * This component supports:
11
- * - Configurable title and content.
12
- * - Optional footer buttons with callbacks and return values.
13
- * - Multiple sizes: `'small' | 'large' | 'full'`.
14
- * - Closable modal and outside-click behavior.
15
- * - Passing arbitrary data to the modal instance.
16
- *
17
- * @usage
18
- * ### Open a modal from TypeScript using the modal service
19
- * ```ts
20
- * this.modalService.open({
21
- * title: 'Demo Modal',
22
- * content: 'This modal is opened from TypeScript using the service.',
23
- * footerButtons: [
24
- * {
25
- * label: 'Accept',
26
- * severity: 'secondary',
27
- * action: () => console.log('Accept clicked'),
28
- * returnValue: true,
29
- * },
30
- * {
31
- * label: 'Cancel',
32
- * severity: 'danger',
33
- * action: () => console.log('Cancel clicked'),
34
- * returnValue: false,
35
- * },
36
- * ],
37
- * size: 'small',
38
- * closable: true,
39
- * closeOnOutsideClick: false,
40
- * }).subscribe((result) => {
41
- * console.log('Modal closed with value:', result);
42
- * });
43
- * ```
8
+ * A programmatically controlled modal dialog used for displaying dynamic content.
9
+ * Modernized for Angular 19 with 100% synchronous Signal-based closing interception.
44
10
  */
45
- export declare class ModalComponent {
11
+ export declare class ModalComponent<T = unknown> implements OnDestroy {
46
12
  private readonly elementRef;
47
- constructor(elementRef: ElementRef);
13
+ private readonly contentHost;
14
+ private componentRef?;
48
15
  /** The title displayed at the top of the modal */
49
16
  title: import("@angular/core").InputSignal<string>;
50
- /** The main content of the modal */
51
- content: import("@angular/core").InputSignal<string | Type<unknown> | null>;
17
+ /** The main content of the modal. Can be a string or a Component Type. */
18
+ content: import("@angular/core").InputSignal<string | Type<T> | null>;
52
19
  /** Array of footer buttons with label, callback, and return value */
53
20
  footerButtons: import("@angular/core").InputSignal<ModalFooterButton[]>;
54
- /** Modal size: 'small', 'large', or 'full' */
21
+ /** Modal size: 'small', 'large', 'medium' or 'full' */
55
22
  size: import("@angular/core").InputSignal<ModalSizeType>;
56
- /** Whether the modal can be closed by the user */
23
+ /** Whether the modal can be closed by the user via close button */
57
24
  closable: import("@angular/core").InputSignal<boolean>;
58
- /** Whether clicking outside closes the modal */
25
+ /** Whether clicking outside the modal mask closes the modal */
59
26
  closeOnOutsideClick: import("@angular/core").InputSignal<boolean>;
60
- isContentString: import("@angular/core").Signal<boolean>;
61
- /** Computed: whether the modal has footer buttons */
62
- hasFooter: import("@angular/core").Signal<boolean>;
63
27
  /**
64
- * Whether the modal should be responsive on mobile screens.
65
- * If true, the modal width will adapt based on breakpoints.
66
- * @default true
28
+ * Optional data to be passed as inputs to the dynamic component.
29
+ */
30
+ data: import("@angular/core").InputSignal<Partial<T>>;
31
+ /**
32
+ * Optional interceptor called before the modal closes.
33
+ * MUST be synchronous. Returns true to allow closing.
67
34
  */
35
+ interceptor: import("@angular/core").InputSignal<TkCloseInterceptor | undefined>;
36
+ /** Computed: whether the content is a simple string */
37
+ isContentString: import("@angular/core").Signal<boolean>;
38
+ /** Computed: whether the modal has footer buttons to display */
39
+ hasFooter: import("@angular/core").Signal<boolean>;
40
+ /** Whether the modal should be responsive on mobile screens */
68
41
  responsive: import("@angular/core").InputSignal<boolean>;
69
- /** Computed: calculates modal max-width based on `size` */
70
- modalMaxWidth: import("@angular/core").Signal<"67.5rem" | "35rem" | "98vw" | "25rem">;
42
+ /** Visibility flag as Model Signal (allows two-way binding) */
43
+ isOpened: import("@angular/core").ModelSignal<boolean>;
71
44
  /** Whether the modal content has a scrollbar */
72
45
  hasScroll: boolean;
73
- /** Visibility flag */
74
- isOpened: boolean;
75
46
  /** Emits when the modal closes, passing the return value from footer buttons or null */
76
47
  readonly onClose: EventEmitter<unknown>;
77
48
  private alreadyEmitted;
78
49
  private returnValueOnClose;
79
- /** Opens the modal */
80
- open(): void;
50
+ constructor(elementRef: ElementRef);
51
+ /** Computed: calculates modal max-width based on `size` */
52
+ modalMaxWidth: import("@angular/core").Signal<"67.5rem" | "35rem" | "98vw" | "25rem">;
53
+ ngOnDestroy(): void;
54
+ /**
55
+ * @summary Orchestrates dynamic rendering and destruction based on visibility.
56
+ * @private
57
+ */
58
+ private attachDynamicContent;
59
+ /**
60
+ * @summary Synchronizes incoming data record with the dynamic instance @Inputs.
61
+ * @private
62
+ */
63
+ private syncDynamicInputs;
64
+ /**
65
+ * @summary Safely destroys the dynamic component and clears references.
66
+ * @private
67
+ */
68
+ private detachDynamicContent;
81
69
  /**
82
70
  * Checks if the modal content has a scrollbar and updates `hasScroll` state.
83
- * This is called when the modal is shown.
84
71
  */
85
72
  checkScroll(): void;
86
- /** Closes the modal and emits onClose with null */
73
+ /**
74
+ * Opens the modal dialog.
75
+ */
76
+ open(): void;
77
+ /**
78
+ * @summary Main entry point for closure requests.
79
+ * Evaluation is 100% synchronous based on current Signal state.
80
+ * @param returnValue (Optional) Value to emit on close.
81
+ */
82
+ tryClose(returnValue?: unknown): void;
83
+ /**
84
+ * @summary Synchronous evaluator of hierarchical guards.
85
+ * @returns true if closure is allowed.
86
+ * @private
87
+ */
88
+ private canExecuteClosure;
89
+ /**
90
+ * @summary Unified logic to execute the final closure state change.
91
+ * @private
92
+ */
93
+ private executeClosure;
94
+ /**
95
+ * @summary Handles external visibility changes (from p-dialog 'X' or Escape).
96
+ * Ensures the reactive guard is respected before allowing closure.
97
+ */
98
+ onVisibleChange(visible: boolean): void;
99
+ /**
100
+ * Handles the close event from the underlying dialog component.
101
+ */
87
102
  handleClose(): void;
88
- /** Closes the modal without emitting an event */
89
- close(): void;
90
103
  /**
91
- * Handles footer button actions.
92
- * Executes the action callback, emits `onClose` with the provided returnValue, then closes the modal.
93
- * @param action Callback to execute when the button is clicked
94
- * @param returnValue Value emitted on modal close
104
+ * @summary Handles actions triggered by footer buttons.
95
105
  */
96
106
  handleAction(action: (() => void) | undefined, returnValue: unknown): void;
97
- static ɵfac: i0.ɵɵFactoryDeclaration<ModalComponent, never>;
98
- static ɵcmp: i0.ɵɵComponentDeclaration<ModalComponent, "tk-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "content": { "alias": "content"; "required": false; "isSignal": true; }; "footerButtons": { "alias": "footerButtons"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "closeOnOutsideClick": { "alias": "closeOnOutsideClick"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
107
+ /**
108
+ * @summary Safely closes the modal forcefully without checks.
109
+ */
110
+ close(): void;
111
+ /**
112
+ * @private
113
+ * Encapsulates state cleanup to avoid repetitive assignments
114
+ */
115
+ private resetClosureState;
116
+ static ɵfac: i0.ɵɵFactoryDeclaration<ModalComponent<any>, never>;
117
+ static ɵcmp: i0.ɵɵComponentDeclaration<ModalComponent<any>, "tk-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "content": { "alias": "content"; "required": false; "isSignal": true; }; "footerButtons": { "alias": "footerButtons"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "closeOnOutsideClick": { "alias": "closeOnOutsideClick"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "interceptor": { "alias": "interceptor"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "isOpened": { "alias": "isOpened"; "required": false; "isSignal": true; }; }, { "isOpened": "isOpenedChange"; }, never, never, true, never>;
99
118
  }