@tekus/design-system 5.18.0 → 5.20.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 (51) hide show
  1. package/assets/tokens/tk-foundations.json +3 -3
  2. package/components/checkbox/src/checkbox.component.d.ts +33 -2
  3. package/components/drawer/index.d.ts +5 -0
  4. package/components/drawer/public-api.d.ts +3 -0
  5. package/components/drawer/src/drawer.component.d.ts +105 -0
  6. package/components/drawer/src/drawer.types.d.ts +22 -0
  7. package/components/drawer/src/services/drawer.service.d.ts +15 -0
  8. package/components/icon/core/icons/arrows-rotate.d.ts +2 -0
  9. package/components/icon/core/icons/edit.d.ts +2 -0
  10. package/components/icon/core/icons/globe-pointer.d.ts +2 -0
  11. package/components/icon/core/icons/grip-vertical.d.ts +2 -0
  12. package/components/modal/src/modal.component.d.ts +86 -67
  13. package/components/modal/src/modal.types.d.ts +22 -2
  14. package/components/modal/src/services/modal.service.d.ts +15 -0
  15. package/components/multiselect/src/multiselect.component.d.ts +115 -19
  16. package/components/panel/index.d.ts +5 -0
  17. package/components/panel/public-api.d.ts +1 -0
  18. package/components/panel/src/panel.component.d.ts +82 -0
  19. package/components/radio-button/src/radio-button.component.d.ts +33 -3
  20. package/components/table/src/table.component.d.ts +45 -1
  21. package/components/table/src/table.interface.d.ts +1 -1
  22. package/components/toolbar/src/toolbar.component.d.ts +55 -1
  23. package/core/types/public-api.d.ts +1 -0
  24. package/core/types/src/interception/index.d.ts +1 -0
  25. package/core/types/src/interception/interception.types.d.ts +21 -0
  26. package/fesm2022/tekus-design-system-components-checkbox.mjs +52 -16
  27. package/fesm2022/tekus-design-system-components-checkbox.mjs.map +1 -1
  28. package/fesm2022/tekus-design-system-components-drawer.mjs +280 -0
  29. package/fesm2022/tekus-design-system-components-drawer.mjs.map +1 -0
  30. package/fesm2022/tekus-design-system-components-icon.mjs +56 -0
  31. package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
  32. package/fesm2022/tekus-design-system-components-modal.mjs +190 -89
  33. package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
  34. package/fesm2022/tekus-design-system-components-multiselect.mjs +164 -45
  35. package/fesm2022/tekus-design-system-components-multiselect.mjs.map +1 -1
  36. package/fesm2022/tekus-design-system-components-panel.mjs +102 -0
  37. package/fesm2022/tekus-design-system-components-panel.mjs.map +1 -0
  38. package/fesm2022/tekus-design-system-components-radio-button.mjs +53 -18
  39. package/fesm2022/tekus-design-system-components-radio-button.mjs.map +1 -1
  40. package/fesm2022/tekus-design-system-components-select.mjs +3 -8
  41. package/fesm2022/tekus-design-system-components-select.mjs.map +1 -1
  42. package/fesm2022/tekus-design-system-components-table.mjs +72 -5
  43. package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
  44. package/fesm2022/tekus-design-system-components-toolbar.mjs +72 -4
  45. package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
  46. package/fesm2022/tekus-design-system-core-types.mjs +31 -1
  47. package/fesm2022/tekus-design-system-core-types.mjs.map +1 -1
  48. package/fesm2022/tekus-design-system-core.mjs +31 -1
  49. package/fesm2022/tekus-design-system-core.mjs.map +1 -1
  50. package/package.json +13 -5
  51. package/styles/variables.css +3 -3
@@ -527,7 +527,7 @@
527
527
  }
528
528
  },
529
529
  "paddingX": {
530
- "nome": {
530
+ "none": {
531
531
  "value": "{tk-spacing.base.0}",
532
532
  "type": "number"
533
533
  },
@@ -553,7 +553,7 @@
553
553
  }
554
554
  },
555
555
  "paddingY": {
556
- "nome": {
556
+ "none": {
557
557
  "value": "{tk-spacing.base.0}",
558
558
  "type": "number"
559
559
  },
@@ -579,7 +579,7 @@
579
579
  }
580
580
  },
581
581
  "gap": {
582
- "nome": {
582
+ "none": {
583
583
  "value": "{tk-spacing.base.0}",
584
584
  "type": "number"
585
585
  },
@@ -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
@@ -55,24 +60,50 @@ export declare class CheckboxComponent implements ControlValueAccessor, OnInit,
55
60
  * Message to display when the control is invalid and touched.
56
61
  */
57
62
  errorMessage: import("@angular/core").InputSignal<string>;
63
+ /**
64
+ * @property {ModelSignal<boolean>} indeterminate
65
+ * @description
66
+ * Indeterminate state of the checkbox (reactive).
67
+ * Useful for parent checkboxes in lists with partial selection.
68
+ */
69
+ indeterminate: import("@angular/core").ModelSignal<boolean>;
58
70
  /**
59
71
  * @property {boolean} disabled
60
72
  * @description
61
73
  * Whether the checkbox is disabled.
62
74
  */
63
- disabled: import("@angular/core").WritableSignal<boolean>;
75
+ disabled: import("@angular/core").ModelSignal<boolean>;
76
+ /** Component Methods */
64
77
  get effectiveControl(): FormControl;
65
78
  onChange: (value: unknown) => void;
66
79
  onTouched: () => void;
67
80
  private readonly subscription;
68
81
  ngOnInit(): void;
69
82
  ngOnDestroy(): void;
83
+ /**
84
+ * Implementation of ControlValueAccessor: Writes a new value from the form.
85
+ */
70
86
  writeValue(value: unknown): void;
87
+ /**
88
+ * Implementation of ControlValueAccessor: Registers a callback for change events.
89
+ */
71
90
  registerOnChange(fn: (value: unknown) => void): void;
91
+ /**
92
+ * Implementation of ControlValueAccessor: Registers a callback for touched events.
93
+ */
72
94
  registerOnTouched(fn: () => void): void;
95
+ /**
96
+ * Implementation of ControlValueAccessor: Sets the disabled state.
97
+ */
73
98
  setDisabledState?(isDisabled: boolean): void;
99
+ /**
100
+ * Handle model change events from the template.
101
+ */
74
102
  onModelChange(value: unknown): void;
103
+ /**
104
+ * Handle blur events to trigger onTouched.
105
+ */
75
106
  onBlur(): void;
76
107
  static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxComponent, never>;
77
- 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; }; }, { "model": "modelChange"; }, never, never, true, never>;
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>;
78
109
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@tekus/design-system/components/drawer" />
5
+ export * from './public-api';
@@ -0,0 +1,3 @@
1
+ export * from './src/drawer.component';
2
+ export * from './src/services/drawer.service';
3
+ export * from './src/drawer.types';
@@ -0,0 +1,105 @@
1
+ import { EventEmitter, Type, ElementRef, OnDestroy } from '@angular/core';
2
+ import { DrawerHeaderAction, DrawerSizeType } from './drawer.types';
3
+ import { TkCloseInterceptor } from '@tekus/design-system/core/types';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * @component DrawerComponent
7
+ * @description
8
+ * A programmatically controlled drawer overlay used for displaying dynamic content,
9
+ * titles, and header actions. The drawer is opened through a service with a configuration object,
10
+ * similar to tk-modal.
11
+ *
12
+ * This component supports:
13
+ * - Required title with ellipsis for long text.
14
+ * - Optional header action button + close button.
15
+ * - Content as string or component.
16
+ * - Position: always right.
17
+ * - Sizes: small (500px), large (1024px).
18
+ * - Closable and dismissible mask behavior.
19
+ *
20
+ * @usage
21
+ * ### Open a drawer from TypeScript using the drawer service
22
+ * ```ts
23
+ * this.drawerService.open({
24
+ * title: 'Drawer name',
25
+ * content: 'Content text drawer example',
26
+ * headerAction: {
27
+ * label: 'Action',
28
+ * severity: 'primary',
29
+ * action: () => console.log('Action clicked'),
30
+ * returnValue: true,
31
+ * },
32
+ * size: 'small',
33
+ * }).subscribe((result) => {
34
+ * console.log('Drawer closed with value:', result);
35
+ * });
36
+ * ```
37
+ * Modernized for Angular 19 with 100% synchronous Signal-based closing interception.
38
+ */
39
+ export declare class DrawerComponent<T = unknown> implements OnDestroy {
40
+ private readonly elementRef;
41
+ private readonly contentHost;
42
+ private componentRef?;
43
+ /** The required title displayed at the top left of the drawer header */
44
+ title: import("@angular/core").InputSignal<string>;
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>;
47
+ /** Optional header action button (displayed before close button) */
48
+ headerAction: import("@angular/core").InputSignal<DrawerHeaderAction | null>;
49
+ /** Drawer size: 'small' (500px), 'large' (1024px) */
50
+ size: import("@angular/core").InputSignal<DrawerSizeType>;
51
+ /** Whether the drawer can be closed by the user via close button */
52
+ closable: import("@angular/core").InputSignal<boolean>;
53
+ /** Whether clicking the mask closes the drawer */
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>;
59
+ isContentString: import("@angular/core").Signal<boolean>;
60
+ hasHeaderAction: import("@angular/core").Signal<boolean>;
61
+ /** Computed: drawer width (responsive) and max-width based on `size`. Always right position. */
62
+ drawerStyle: import("@angular/core").Signal<{
63
+ width: string;
64
+ maxWidth: string;
65
+ }>;
66
+ /** Visibility flag. Use model for two-way binding when using drawer in template. */
67
+ isOpened: import("@angular/core").ModelSignal<boolean>;
68
+ /** Whether the drawer content has a scrollbar */
69
+ hasScroll: boolean;
70
+ /** Emits when the drawer closes, passing the return value from header action or null */
71
+ readonly onClose: EventEmitter<unknown>;
72
+ private alreadyEmitted;
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;
83
+ /** Opens the drawer */
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;
94
+ /** Closes the drawer and emits onClose */
95
+ handleClose(): void;
96
+ /** Forcefully closes the drawer without checks */
97
+ close(): void;
98
+ /**
99
+ * Handles header action button click.
100
+ */
101
+ handleHeaderAction(action: (() => void) | undefined, returnValue: unknown): void;
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>;
105
+ }
@@ -0,0 +1,22 @@
1
+ import { Type } from '@angular/core';
2
+ import { Variant } from '@tekus/design-system/components/button';
3
+ import { SeverityType } from '@tekus/design-system/components/modal';
4
+ import { TkCloseInterceptor } from '@tekus/design-system/core/types';
5
+ export type DrawerSizeType = 'small' | 'large';
6
+ export interface DrawerHeaderAction {
7
+ label: string;
8
+ severity: SeverityType;
9
+ action?: () => void;
10
+ returnValue?: unknown;
11
+ variant?: Variant;
12
+ }
13
+ export interface DrawerConfig<T = unknown> {
14
+ title: string;
15
+ content?: string | Type<T>;
16
+ headerAction?: DrawerHeaderAction;
17
+ size?: DrawerSizeType;
18
+ closable?: boolean;
19
+ dismissible?: boolean;
20
+ data?: Partial<T>;
21
+ interceptor?: TkCloseInterceptor;
22
+ }
@@ -0,0 +1,15 @@
1
+ import { ApplicationRef, ComponentRef } from '@angular/core';
2
+ import { DrawerComponent } from '../drawer.component';
3
+ import { Observable } from 'rxjs';
4
+ import { DrawerConfig } from '../drawer.types';
5
+ import * as i0 from "@angular/core";
6
+ export declare class DrawerService {
7
+ private readonly appRef;
8
+ private drawerRef;
9
+ constructor(appRef: ApplicationRef);
10
+ get _drawerRefForTesting(): ComponentRef<DrawerComponent<unknown>> | null;
11
+ set _drawerRefForTesting(ref: ComponentRef<DrawerComponent<unknown>> | null);
12
+ open(config: DrawerConfig): Observable<unknown>;
13
+ static ɵfac: i0.ɵɵFactoryDeclaration<DrawerService, never>;
14
+ static ɵprov: i0.ɵɵInjectableDeclaration<DrawerService>;
15
+ }
@@ -0,0 +1,2 @@
1
+ import { IconRegister } from "../icon-catalog";
2
+ export declare const arrowsRotateIcon: IconRegister;
@@ -0,0 +1,2 @@
1
+ import { IconRegister } from '../icon-catalog';
2
+ export declare const editIcon: IconRegister;
@@ -0,0 +1,2 @@
1
+ import { IconRegister } from '../icon-catalog';
2
+ export declare const globePointerIcon: IconRegister;
@@ -0,0 +1,2 @@
1
+ import { IconRegister } from '../icon-catalog';
2
+ export declare const gridVerticalIcon: IconRegister;
@@ -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
  }
@@ -1,19 +1,39 @@
1
1
  import { Type } from '@angular/core';
2
2
  import { Variant } from '@tekus/design-system/components/button';
3
+ import { TkCloseInterceptor } from '@tekus/design-system/core/types';
3
4
  export type ModalSizeType = 'small' | 'large' | 'medium' | 'full';
4
5
  export type SeverityType = 'primary' | 'secondary' | 'danger';
5
6
  export interface ModalFooterButton {
6
7
  label: string;
7
8
  severity: SeverityType;
9
+ /** Optional callback function executed when the button is clicked */
8
10
  action?: () => void;
11
+ /** Optional value emitted when the modal closes after clicking this button */
9
12
  returnValue?: unknown;
13
+ /** Optional button variant */
10
14
  variant?: Variant;
11
15
  }
12
- export interface ModalConfig {
16
+ export interface ModalConfig<T = unknown> {
17
+ /** The title displayed at the top of the modal */
13
18
  title: string;
14
- content?: string | Type<unknown>;
19
+ /** The main content of the modal. Can be a string or a Component Type. */
20
+ content?: string | Type<T>;
21
+ /** Array of footer buttons with label, callback, and return value */
15
22
  footerButtons?: ModalFooterButton[];
23
+ /** Modal size: 'small', 'large', 'medium' or 'full' */
16
24
  size?: ModalSizeType;
25
+ /** Whether the modal can be closed by the user via close button */
17
26
  closable?: boolean;
27
+ /** Whether clicking outside the modal mask closes the modal */
18
28
  closeOnOutsideClick?: boolean;
29
+ /**
30
+ * Optional data to be passed as inputs to the dynamic component.
31
+ * Keys must match the component's @Input names.
32
+ */
33
+ data?: Partial<T>;
34
+ /**
35
+ * Optional interceptor called before the modal closes.
36
+ * Return false, Promise<false> or Observable<false> to prevent closing.
37
+ */
38
+ interceptor?: TkCloseInterceptor;
19
39
  }
@@ -3,13 +3,28 @@ import { ModalComponent } from '../modal.component';
3
3
  import { Observable } from 'rxjs';
4
4
  import { ModalConfig } from '../modal.types';
5
5
  import * as i0 from "@angular/core";
6
+ /**
7
+ * @service ModalService
8
+ * @description
9
+ * Service responsible for programmatically opening and managing modal dialogs.
10
+ * It handles component creation, attachment to the document body, and cleanup.
11
+ */
6
12
  export declare class ModalService {
7
13
  private readonly injector;
8
14
  private readonly appRef;
15
+ /** Reference to the currently open modal component */
9
16
  private modalRef;
10
17
  constructor(injector: Injector, appRef: ApplicationRef);
18
+ /** Internal getter for testing purposes */
11
19
  get _modalRefForTesting(): ComponentRef<ModalComponent> | null;
20
+ /** Internal setter for testing purposes */
12
21
  set _modalRefForTesting(ref: ComponentRef<ModalComponent> | null);
22
+ /**
23
+ * Opens a modal dialog with the provided configuration.
24
+ * Only one modal can be open at a time.
25
+ * @param config Configuration object for the modal (title, content, buttons, etc.)
26
+ * @returns An observable that emits the modal's return value when it closes.
27
+ */
13
28
  open(config: ModalConfig): Observable<unknown>;
14
29
  static ɵfac: i0.ɵɵFactoryDeclaration<ModalService, never>;
15
30
  static ɵprov: i0.ɵɵInjectableDeclaration<ModalService>;