@tekus/design-system 5.25.0 → 5.26.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/assets/readme-images/tk-card-default.svg +32 -0
- package/assets/readme-images/tk-card-horizontal.svg +22 -0
- package/assets/readme-images/tk-card-layouts.svg +58 -0
- package/assets/readme-images/tk-card-list-selected.svg +102 -0
- package/assets/readme-images/tk-card-list.svg +70 -0
- package/assets/readme-images/tk-card-simple-versions.svg +46 -0
- package/assets/readme-images/tk-card.svg +32 -0
- package/assets/readme-images/tk-progress-bar-sizes.svg +28 -0
- package/assets/readme-images/tk-progress-bar.svg +13 -0
- package/assets/readme-images/tk-status-bar-severity.svg +15 -0
- package/assets/readme-images/tk-status-bar.svg +9 -0
- package/assets/readme-images/tk-toast-action.svg +17 -0
- package/assets/readme-images/tk-toast.svg +38 -0
- package/fesm2022/tekus-design-system-components-button.mjs +14 -3
- package/fesm2022/tekus-design-system-components-button.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-card-list.mjs +61 -0
- package/fesm2022/tekus-design-system-components-card-list.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-card.mjs +126 -0
- package/fesm2022/tekus-design-system-components-card.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-drawer.mjs +1 -1
- package/fesm2022/tekus-design-system-components-drawer.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-fallback-view.mjs +1 -1
- package/fesm2022/tekus-design-system-components-fallback-view.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-modal.mjs +1 -1
- package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-progress-bar.mjs +55 -0
- package/fesm2022/tekus-design-system-components-progress-bar.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-status-bar.mjs +52 -0
- package/fesm2022/tekus-design-system-components-status-bar.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-table.mjs +1 -1
- package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-toast.mjs +47 -0
- package/fesm2022/tekus-design-system-components-toast.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-toolbar.mjs +1 -1
- package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-topbar.mjs +1 -1
- package/fesm2022/tekus-design-system-components-topbar.mjs.map +1 -1
- package/fesm2022/tekus-design-system-core-types.mjs +55 -0
- package/fesm2022/tekus-design-system-core-types.mjs.map +1 -1
- package/fesm2022/tekus-design-system-core.mjs +55 -0
- package/fesm2022/tekus-design-system-core.mjs.map +1 -1
- package/package.json +21 -1
- package/types/tekus-design-system-components-button.d.ts +12 -1
- package/types/tekus-design-system-components-card-list.d.ts +63 -0
- package/types/tekus-design-system-components-card.d.ts +95 -0
- package/types/tekus-design-system-components-progress-bar.d.ts +43 -0
- package/types/tekus-design-system-components-status-bar.d.ts +42 -0
- package/types/tekus-design-system-components-toast.d.ts +27 -0
- package/types/tekus-design-system-core-types.d.ts +9 -1
- package/types/tekus-design-system-core.d.ts +9 -1
|
@@ -119,6 +119,17 @@ class ButtonComponent {
|
|
|
119
119
|
* @default `undefined`
|
|
120
120
|
*/
|
|
121
121
|
this.tooltipText = input(...(ngDevMode ? [undefined, { debugName: "tooltipText" }] : /* istanbul ignore next */ []));
|
|
122
|
+
/**
|
|
123
|
+
* @property {'small' | 'large' | undefined} size
|
|
124
|
+
* @description
|
|
125
|
+
* Defines the size of the button.
|
|
126
|
+
* - `'small'`: Small button.
|
|
127
|
+
* - `'large'`: Large button.
|
|
128
|
+
* - `undefined`: Default size.
|
|
129
|
+
*
|
|
130
|
+
* @default `undefined`
|
|
131
|
+
*/
|
|
132
|
+
this.size = input(...(ngDevMode ? [undefined, { debugName: "size" }] : /* istanbul ignore next */ []));
|
|
122
133
|
}
|
|
123
134
|
/**
|
|
124
135
|
* @method onButtonClick
|
|
@@ -131,12 +142,12 @@ class ButtonComponent {
|
|
|
131
142
|
this.clicked.emit('mouse');
|
|
132
143
|
}
|
|
133
144
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
134
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: ButtonComponent, isStandalone: true, selector: "tk-button", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tooltipText: { classPropertyName: "tooltipText", publicName: "tooltipText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<p-button\n class=\"tk-button\"\n [label]=\"label()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [severity]=\"link() ? undefined : severity()\"\n [variant]=\"variant()\"\n [link]=\"link()\"\n [pTooltip]=\"tooltipText()\"\n tooltipPosition=\"top\"\n (click)=\"onButtonClick()\"\n (keydown.enter)=\"onButtonClick()\"\n (keydown.space)=\"onButtonClick()\">\n\n @if (icon()) {\n <tk-icon [icon]=\"icon()!\"></tk-icon>\n }\n</p-button>\n", styles: [":host ::ng-deep .p-button{min-width:var(--tk-size-base-250, 2.5rem)}:host ::ng-deep .p-button.p-button-primary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{color:var(--tk-color-base-surface-0, #ffffff)!important}:host ::ng-deep .p-button.p-button-link .p-button-label{color:var(--tk-color-base-primary-500, #16006f)!important}:host ::ng-deep .p-button.p-button-link:hover .p-button-label{color:var(--tk-color-base-primary-400, #45338c)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label{color:var(--tk-color-base-surface-900, #191A1B)!important}:host ::ng-deep .p-button.p-button-secondary.p-button-outlined .p-button-label{color:var(--tk-color-base-surface-500, #8a8a8b)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{font-weight:var(--tk-font-weight-400, 400)}:host ::ng-deep .p-button-label{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
145
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: ButtonComponent, isStandalone: true, selector: "tk-button", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tooltipText: { classPropertyName: "tooltipText", publicName: "tooltipText", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<p-button\n class=\"tk-button\"\n [label]=\"label()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [severity]=\"link() ? undefined : severity()\"\n [variant]=\"variant()\"\n [link]=\"link()\"\n [size]=\"size()\"\n [pTooltip]=\"tooltipText()\"\n tooltipPosition=\"top\"\n (click)=\"onButtonClick()\"\n (keydown.enter)=\"onButtonClick()\"\n (keydown.space)=\"onButtonClick()\">\n\n @if (icon()) {\n <tk-icon [icon]=\"icon()!\"></tk-icon>\n }\n</p-button>\n", styles: [":host{display:inline-flex;vertical-align:middle}:host ::ng-deep .p-button{min-width:var(--tk-size-base-250, 2.5rem)}:host ::ng-deep .p-button.p-button-sm{min-width:var(--tk-spacing-paddingX-xl, 1.5rem);height:var(--tk-spacing-paddingY-xl, 1.5rem);padding:0;display:flex;align-items:center;justify-content:center;line-height:1}:host ::ng-deep .p-button.p-button-sm.p-button-icon-only{width:var(--tk-spacing-paddingX-xl, 1.5rem)}:host ::ng-deep .p-button.p-button-sm ::ng-deep tk-icon{display:flex;align-items:center;justify-content:center}:host ::ng-deep .p-button.p-button-sm ::ng-deep tk-icon svg{width:1rem;height:1rem}:host ::ng-deep .p-button.p-button-primary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{color:var(--tk-color-base-surface-0, #ffffff)!important}:host ::ng-deep .p-button.p-button-link .p-button-label{color:var(--tk-color-base-primary-500, #16006f)!important}:host ::ng-deep .p-button.p-button-link:hover .p-button-label{color:var(--tk-color-base-primary-400, #45338c)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label{color:var(--tk-color-base-surface-900, #191A1B)!important}:host ::ng-deep .p-button.p-button-secondary.p-button-outlined .p-button-label{color:var(--tk-color-base-surface-500, #8a8a8b)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{font-weight:var(--tk-font-weight-400, 400)}:host ::ng-deep .p-button-label{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
135
146
|
}
|
|
136
147
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
137
148
|
type: Component,
|
|
138
|
-
args: [{ selector: 'tk-button', imports: [ButtonModule, IconComponent, Tooltip], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-button\n class=\"tk-button\"\n [label]=\"label()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [severity]=\"link() ? undefined : severity()\"\n [variant]=\"variant()\"\n [link]=\"link()\"\n [pTooltip]=\"tooltipText()\"\n tooltipPosition=\"top\"\n (click)=\"onButtonClick()\"\n (keydown.enter)=\"onButtonClick()\"\n (keydown.space)=\"onButtonClick()\">\n\n @if (icon()) {\n <tk-icon [icon]=\"icon()!\"></tk-icon>\n }\n</p-button>\n", styles: [":host ::ng-deep .p-button{min-width:var(--tk-size-base-250, 2.5rem)}:host ::ng-deep .p-button.p-button-primary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{color:var(--tk-color-base-surface-0, #ffffff)!important}:host ::ng-deep .p-button.p-button-link .p-button-label{color:var(--tk-color-base-primary-500, #16006f)!important}:host ::ng-deep .p-button.p-button-link:hover .p-button-label{color:var(--tk-color-base-primary-400, #45338c)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label{color:var(--tk-color-base-surface-900, #191A1B)!important}:host ::ng-deep .p-button.p-button-secondary.p-button-outlined .p-button-label{color:var(--tk-color-base-surface-500, #8a8a8b)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{font-weight:var(--tk-font-weight-400, 400)}:host ::ng-deep .p-button-label{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
|
|
139
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }], tooltipText: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipText", required: false }] }] } });
|
|
149
|
+
args: [{ selector: 'tk-button', imports: [ButtonModule, IconComponent, Tooltip], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-button\n class=\"tk-button\"\n [label]=\"label()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [severity]=\"link() ? undefined : severity()\"\n [variant]=\"variant()\"\n [link]=\"link()\"\n [size]=\"size()\"\n [pTooltip]=\"tooltipText()\"\n tooltipPosition=\"top\"\n (click)=\"onButtonClick()\"\n (keydown.enter)=\"onButtonClick()\"\n (keydown.space)=\"onButtonClick()\">\n\n @if (icon()) {\n <tk-icon [icon]=\"icon()!\"></tk-icon>\n }\n</p-button>\n", styles: [":host{display:inline-flex;vertical-align:middle}:host ::ng-deep .p-button{min-width:var(--tk-size-base-250, 2.5rem)}:host ::ng-deep .p-button.p-button-sm{min-width:var(--tk-spacing-paddingX-xl, 1.5rem);height:var(--tk-spacing-paddingY-xl, 1.5rem);padding:0;display:flex;align-items:center;justify-content:center;line-height:1}:host ::ng-deep .p-button.p-button-sm.p-button-icon-only{width:var(--tk-spacing-paddingX-xl, 1.5rem)}:host ::ng-deep .p-button.p-button-sm ::ng-deep tk-icon{display:flex;align-items:center;justify-content:center}:host ::ng-deep .p-button.p-button-sm ::ng-deep tk-icon svg{width:1rem;height:1rem}:host ::ng-deep .p-button.p-button-primary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{color:var(--tk-color-base-surface-0, #ffffff)!important}:host ::ng-deep .p-button.p-button-link .p-button-label{color:var(--tk-color-base-primary-500, #16006f)!important}:host ::ng-deep .p-button.p-button-link:hover .p-button-label{color:var(--tk-color-base-primary-400, #45338c)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label{color:var(--tk-color-base-surface-900, #191A1B)!important}:host ::ng-deep .p-button.p-button-secondary.p-button-outlined .p-button-label{color:var(--tk-color-base-surface-500, #8a8a8b)!important}:host ::ng-deep .p-button.p-button-secondary .p-button-label,:host ::ng-deep .p-button.p-button-danger .p-button-label{font-weight:var(--tk-font-weight-400, 400)}:host ::ng-deep .p-button-label{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
|
|
150
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }], tooltipText: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipText", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
140
151
|
|
|
141
152
|
/**
|
|
142
153
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tekus-design-system-components-button.mjs","sources":["../../../projects/design-system/components/button/src/button.component.ts","../../../projects/design-system/components/button/src/button.component.html","../../../projects/design-system/components/button/tekus-design-system-components-button.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { ButtonModule } from 'primeng/button';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { Tooltip } from 'primeng/tooltip';\n\n\nexport type ButtonSeverity = 'primary' | 'secondary' | 'danger';\nexport type Variant = 'text' | 'outlined';\n/**\n * @component ButtonComponent\n * @description\n * Atomic button component that provides a reusable and customizable button element\n * across the application.\n * It uses PrimeNG's `ButtonModule` under the hood and allows setting different visual\n * variants (severity), button types, and disabled states.\n *\n * This component ensures consistent design and behavior in all button interactions.\n * It is accessible via both mouse clicks and keyboard actions (Enter/Space).\n *\n * @usage\n * ```html\n * <tk-button\n * label=\"Save\"\n * [severity]=\"'primary'\"\n * [type]=\"'submit'\"\n * (clicked)=\"handleSave()\">\n * </tk-button>\n *\n * <tk-button\n * label=\"Cancel\"\n * [severity]=\"'secondary'\"\n * [disabled]=\"true\">\n * </tk-button>\n * ```\n */\n@Component({\n selector: 'tk-button',\n imports: [ButtonModule, IconComponent, Tooltip],\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ButtonComponent {\n /**\n * @property {string} label\n * @description\n * Text displayed inside the button.\n *\n * @default `undefined`\n */\n label = input<string>();\n\n /**\n * @property {boolean} disabled\n * @description\n * Disables the button, preventing user interaction and applying a visual style\n * that indicates the inactive state.\n *\n * @default `false`\n */\n disabled = input<boolean>(false);\n\n /**\n * @property {'button' | 'submit'} type\n * @description\n * Defines the button's HTML type attribute.\n * - `'button'`: Standard clickable button (default).\n * - `'submit'`: Used to submit forms.\n *\n * @default `'button'`\n */\n type = input<'button' | 'submit'>('button');\n\n /**\n * @property {ButtonSeverity} severity\n * @description\n * Defines the visual importance or style of the button.\n * - `'primary'`: Default, neutral action.\n * - `'secondary'`: Secondary option.\n * - `'danger'`: Destructive or warning actions.\n *\n * @default `'primary'`\n */\n severity = input<ButtonSeverity>('primary');\n\n /**\n * @property {'text' | 'outlined'} variant\n * @description\n * Defines the variant of the button.\n * - `'text'`: Text-only button.\n * - `'outlined'`: Outlined button.\n *\n * @default `undefined`\n */\n variant = input<Variant>();\n\n /**\n * @property {boolean} link\n * @description\n * When true, the button will be styled as a link (text only with underline).\n *\n * @default false\n */\n link = input<boolean>(false);\n\n /**\n * @property {string} icon\n * @description\n * - If `label` is provided, the icon is displayed to the left.\n * - If `label` is empty, the button is rendered as an icon-only button.\n *\n * @default `undefined`\n */\n icon = input<string>();\n\n /**\n * @event clicked\n * @description\n * Emits when the button is activated via click or keyboard (Enter/Space),\n * unless the button is disabled.\n *\n * @example\n * ```html\n * <tk-button label=\"Click me\" (clicked)=\"handleClick()\"></tk-button>\n * ```\n */\n clicked = output<'mouse' | 'keyboard'>();\n\n /**\n * @property {string} tooltipText\n * @description\n * Tooltip text to be displayed when the user hovers over the button.\n *\n * @default `undefined`\n */\n tooltipText = input<string>();\n\n /**\n * @method onButtonClick\n * @description\n * Handles the native click event. Emits the `clicked` event if the button\n * is not disabled.\n */\n onButtonClick(): void {\n if (!this.disabled()) this.clicked.emit('mouse');\n }\n}\n","<p-button\n class=\"tk-button\"\n [label]=\"label()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [severity]=\"link() ? undefined : severity()\"\n [variant]=\"variant()\"\n [link]=\"link()\"\n [pTooltip]=\"tooltipText()\"\n tooltipPosition=\"top\"\n (click)=\"onButtonClick()\"\n (keydown.enter)=\"onButtonClick()\"\n (keydown.space)=\"onButtonClick()\">\n\n @if (icon()) {\n <tk-icon [icon]=\"icon()!\"></tk-icon>\n }\n</p-button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BG;MAQU,eAAe,CAAA;AAP5B,IAAA,WAAA,GAAA;AAQE;;;;;;AAMG;QACH,IAAA,CAAA,KAAK,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAEvB;;;;;;;AAOG;AACH,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,+EAAC;AAEhC;;;;;;;;AAQG;AACH,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAsB,QAAQ,2EAAC;AAE3C;;;;;;;;;AASG;AACH,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAiB,SAAS,+EAAC;AAE3C;;;;;;;;AAQG;QACH,IAAA,CAAA,OAAO,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;AAE1B;;;;;;AAMG;AACH,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAU,KAAK,2EAAC;AAE5B;;;;;;;AAOG;QACH,IAAA,CAAA,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAEtB;;;;;;;;;;AAUG;QACH,IAAA,CAAA,OAAO,GAAG,MAAM,EAAwB;AAExC;;;;;;AAMG;QACH,IAAA,CAAA,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-button.mjs","sources":["../../../projects/design-system/components/button/src/button.component.ts","../../../projects/design-system/components/button/src/button.component.html","../../../projects/design-system/components/button/tekus-design-system-components-button.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { ButtonModule } from 'primeng/button';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { Tooltip } from 'primeng/tooltip';\n\n\nexport type ButtonSeverity = 'primary' | 'secondary' | 'danger';\nexport type Variant = 'text' | 'outlined';\n/**\n * @component ButtonComponent\n * @description\n * Atomic button component that provides a reusable and customizable button element\n * across the application.\n * It uses PrimeNG's `ButtonModule` under the hood and allows setting different visual\n * variants (severity), button types, and disabled states.\n *\n * This component ensures consistent design and behavior in all button interactions.\n * It is accessible via both mouse clicks and keyboard actions (Enter/Space).\n *\n * @usage\n * ```html\n * <tk-button\n * label=\"Save\"\n * [severity]=\"'primary'\"\n * [type]=\"'submit'\"\n * (clicked)=\"handleSave()\">\n * </tk-button>\n *\n * <tk-button\n * label=\"Cancel\"\n * [severity]=\"'secondary'\"\n * [disabled]=\"true\">\n * </tk-button>\n * ```\n */\n@Component({\n selector: 'tk-button',\n imports: [ButtonModule, IconComponent, Tooltip],\n templateUrl: './button.component.html',\n styleUrl: './button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ButtonComponent {\n /**\n * @property {string} label\n * @description\n * Text displayed inside the button.\n *\n * @default `undefined`\n */\n label = input<string>();\n\n /**\n * @property {boolean} disabled\n * @description\n * Disables the button, preventing user interaction and applying a visual style\n * that indicates the inactive state.\n *\n * @default `false`\n */\n disabled = input<boolean>(false);\n\n /**\n * @property {'button' | 'submit'} type\n * @description\n * Defines the button's HTML type attribute.\n * - `'button'`: Standard clickable button (default).\n * - `'submit'`: Used to submit forms.\n *\n * @default `'button'`\n */\n type = input<'button' | 'submit'>('button');\n\n /**\n * @property {ButtonSeverity} severity\n * @description\n * Defines the visual importance or style of the button.\n * - `'primary'`: Default, neutral action.\n * - `'secondary'`: Secondary option.\n * - `'danger'`: Destructive or warning actions.\n *\n * @default `'primary'`\n */\n severity = input<ButtonSeverity>('primary');\n\n /**\n * @property {'text' | 'outlined'} variant\n * @description\n * Defines the variant of the button.\n * - `'text'`: Text-only button.\n * - `'outlined'`: Outlined button.\n *\n * @default `undefined`\n */\n variant = input<Variant>();\n\n /**\n * @property {boolean} link\n * @description\n * When true, the button will be styled as a link (text only with underline).\n *\n * @default false\n */\n link = input<boolean>(false);\n\n /**\n * @property {string} icon\n * @description\n * - If `label` is provided, the icon is displayed to the left.\n * - If `label` is empty, the button is rendered as an icon-only button.\n *\n * @default `undefined`\n */\n icon = input<string>();\n\n /**\n * @event clicked\n * @description\n * Emits when the button is activated via click or keyboard (Enter/Space),\n * unless the button is disabled.\n *\n * @example\n * ```html\n * <tk-button label=\"Click me\" (clicked)=\"handleClick()\"></tk-button>\n * ```\n */\n clicked = output<'mouse' | 'keyboard'>();\n\n /**\n * @property {string} tooltipText\n * @description\n * Tooltip text to be displayed when the user hovers over the button.\n *\n * @default `undefined`\n */\n tooltipText = input<string>();\n\n /**\n * @property {'small' | 'large' | undefined} size\n * @description\n * Defines the size of the button.\n * - `'small'`: Small button.\n * - `'large'`: Large button.\n * - `undefined`: Default size.\n *\n * @default `undefined`\n */\n size = input<'small' | 'large' | undefined>();\n\n /**\n * @method onButtonClick\n * @description\n * Handles the native click event. Emits the `clicked` event if the button\n * is not disabled.\n */\n onButtonClick(): void {\n if (!this.disabled()) this.clicked.emit('mouse');\n }\n}\n","<p-button\n class=\"tk-button\"\n [label]=\"label()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [severity]=\"link() ? undefined : severity()\"\n [variant]=\"variant()\"\n [link]=\"link()\"\n [size]=\"size()\"\n [pTooltip]=\"tooltipText()\"\n tooltipPosition=\"top\"\n (click)=\"onButtonClick()\"\n (keydown.enter)=\"onButtonClick()\"\n (keydown.space)=\"onButtonClick()\">\n\n @if (icon()) {\n <tk-icon [icon]=\"icon()!\"></tk-icon>\n }\n</p-button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BG;MAQU,eAAe,CAAA;AAP5B,IAAA,WAAA,GAAA;AAQE;;;;;;AAMG;QACH,IAAA,CAAA,KAAK,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,OAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAEvB;;;;;;;AAOG;AACH,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,+EAAC;AAEhC;;;;;;;;AAQG;AACH,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAsB,QAAQ,2EAAC;AAE3C;;;;;;;;;AASG;AACH,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAiB,SAAS,+EAAC;AAE3C;;;;;;;;AAQG;QACH,IAAA,CAAA,OAAO,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;AAE1B;;;;;;AAMG;AACH,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAU,KAAK,2EAAC;AAE5B;;;;;;;AAOG;QACH,IAAA,CAAA,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAEtB;;;;;;;;;;AAUG;QACH,IAAA,CAAA,OAAO,GAAG,MAAM,EAAwB;AAExC;;;;;;AAMG;QACH,IAAA,CAAA,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAE7B;;;;;;;;;AASG;QACH,IAAA,CAAA,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAiC;AAW9C,IAAA;AATC;;;;;AAKG;IACH,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAAE,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;IAClD;8GAnHW,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAf,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,wsCC1C5B,8dAmBA,EAAA,MAAA,EAAA,CAAA,wiDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDkBY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,SAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,eAAA,EAAA,WAAA,EAAA,WAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EAAA,SAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,SAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,aAAa,gHAAE,OAAO,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,cAAA,EAAA,eAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,QAAA,EAAA,WAAA,EAAA,WAAA,EAAA,MAAA,EAAA,aAAA,EAAA,cAAA,EAAA,UAAA,EAAA,YAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,WAAA,EAAA,YAAA,EAAA,kBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAKnC,eAAe,EAAA,UAAA,EAAA,CAAA;kBAP3B,SAAS;+BACE,WAAW,EAAA,OAAA,EACZ,CAAC,YAAY,EAAE,aAAa,EAAE,OAAO,CAAC,EAAA,eAAA,EAG9B,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,8dAAA,EAAA,MAAA,EAAA,CAAA,wiDAAA,CAAA,EAAA;;;AExCjD;;AAEG;;;;"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, model, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { CardComponent } from '@tekus/design-system/components/card';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @component CardListComponent
|
|
8
|
+
* @description
|
|
9
|
+
* High-level component used to display a grid of cards with responsive behavioral breakpoints.
|
|
10
|
+
* Supports individual item selection and consistent spacing.
|
|
11
|
+
*/
|
|
12
|
+
class CardListComponent {
|
|
13
|
+
constructor() {
|
|
14
|
+
/** The list of items to display in the grid. Required. */
|
|
15
|
+
this.items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
16
|
+
/** Whether the list supports global item selection (checkboxes). */
|
|
17
|
+
this.selectable = input(false, ...(ngDevMode ? [{ debugName: "selectable" }] : /* istanbul ignore next */ []));
|
|
18
|
+
/** Two-way signal for the current selection of item IDs. */
|
|
19
|
+
this.selectedIds = model([], ...(ngDevMode ? [{ debugName: "selectedIds" }] : /* istanbul ignore next */ []));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Helper method to determine if an individual item is currently selected.
|
|
23
|
+
*/
|
|
24
|
+
isItemSelected(id) {
|
|
25
|
+
return this.selectedIds().includes(id);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Helper method to determine if a card should be marked as selected in the template.
|
|
29
|
+
* Only returns true if the item is explicitly selectable and its ID is in the selected list.
|
|
30
|
+
*/
|
|
31
|
+
isCardSelected(item) {
|
|
32
|
+
const isSelectable = item.selectable ?? this.selectable();
|
|
33
|
+
return isSelectable ? this.isItemSelected(item.id) : false;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Handler for individual card selection change events.
|
|
37
|
+
* Updates the global selectedIds model accordingly.
|
|
38
|
+
*/
|
|
39
|
+
onItemSelected(id, selected) {
|
|
40
|
+
const current = this.selectedIds();
|
|
41
|
+
if (selected && !current.includes(id)) {
|
|
42
|
+
this.selectedIds.set([...current, id]);
|
|
43
|
+
}
|
|
44
|
+
else if (!selected && current.includes(id)) {
|
|
45
|
+
this.selectedIds.set(current.filter(item => item !== id));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: CardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: CardListComponent, isStandalone: true, selector: "tk-card-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIds: "selectedIdsChange" }, ngImport: i0, template: "<div class=\"tk-card-list-grid\">\n @for (item of items(); track item.id) {\n <div class=\"tk-card-list-item\">\n <tk-card\n [title]=\"item.title\"\n [titleIcon]=\"item.titleIcon!\"\n [description]=\"item.description!\"\n [image]=\"item.image!\"\n [badgeText]=\"item.badgeText!\"\n [secondaryBadgeText]=\"item.secondaryBadgeText!\"\n [actions]=\"item.actions || []\"\n [infoElements]=\"item.infoElements || []\"\n [selectable]=\"item.selectable ?? selectable()\"\n [selected]=\"isCardSelected(item)\"\n (selectedChange)=\"onItemSelected(item.id, $event)\">\n </tk-card>\n </div>\n }\n</div>\n", styles: [".tk-card-list-grid{display:grid;gap:var(--tk-spacing-base-150);width:100%;grid-template-columns:repeat(1,1fr)}@media screen and (min-width:768px){.tk-card-list-grid{grid-template-columns:repeat(2,1fr)}}@media screen and (min-width:1024px){.tk-card-list-grid{grid-template-columns:repeat(4,1fr)}}@media screen and (min-width:1440px){.tk-card-list-grid{grid-template-columns:repeat(5,1fr)}}.tk-card-list-grid .tk-card-list-item{display:flex;flex-direction:column;height:100%}.tk-card-list-grid .tk-card-list-item tk-card{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CardComponent, selector: "tk-card", inputs: ["title", "titleIcon", "description", "image", "showImage", "layout", "selectable", "selected", "badgeText", "secondaryBadgeText", "actions", "infoElements"], outputs: ["selectedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
50
|
+
}
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: CardListComponent, decorators: [{
|
|
52
|
+
type: Component,
|
|
53
|
+
args: [{ selector: 'tk-card-list', standalone: true, imports: [CommonModule, CardComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tk-card-list-grid\">\n @for (item of items(); track item.id) {\n <div class=\"tk-card-list-item\">\n <tk-card\n [title]=\"item.title\"\n [titleIcon]=\"item.titleIcon!\"\n [description]=\"item.description!\"\n [image]=\"item.image!\"\n [badgeText]=\"item.badgeText!\"\n [secondaryBadgeText]=\"item.secondaryBadgeText!\"\n [actions]=\"item.actions || []\"\n [infoElements]=\"item.infoElements || []\"\n [selectable]=\"item.selectable ?? selectable()\"\n [selected]=\"isCardSelected(item)\"\n (selectedChange)=\"onItemSelected(item.id, $event)\">\n </tk-card>\n </div>\n }\n</div>\n", styles: [".tk-card-list-grid{display:grid;gap:var(--tk-spacing-base-150);width:100%;grid-template-columns:repeat(1,1fr)}@media screen and (min-width:768px){.tk-card-list-grid{grid-template-columns:repeat(2,1fr)}}@media screen and (min-width:1024px){.tk-card-list-grid{grid-template-columns:repeat(4,1fr)}}@media screen and (min-width:1440px){.tk-card-list-grid{grid-template-columns:repeat(5,1fr)}}.tk-card-list-grid .tk-card-list-item{display:flex;flex-direction:column;height:100%}.tk-card-list-grid .tk-card-list-item tk-card{display:block;height:100%}\n"] }]
|
|
54
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }, { type: i0.Output, args: ["selectedIdsChange"] }] } });
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generated bundle index. Do not edit.
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
export { CardListComponent };
|
|
61
|
+
//# sourceMappingURL=tekus-design-system-components-card-list.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-card-list.mjs","sources":["../../../projects/design-system/components/card-list/src/card-list.component.ts","../../../projects/design-system/components/card-list/src/card-list.component.html","../../../projects/design-system/components/card-list/tekus-design-system-components-card-list.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { CardComponent } from '@tekus/design-system/components/card';\nimport { TkCardListItem } from './card-list.types';\n\n/**\n * @component CardListComponent\n * @description\n * High-level component used to display a grid of cards with responsive behavioral breakpoints.\n * Supports individual item selection and consistent spacing.\n */\n@Component({\n selector: 'tk-card-list',\n standalone: true,\n imports: [CommonModule, CardComponent],\n templateUrl: './card-list.component.html',\n styleUrl: './card-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CardListComponent {\n /** The list of items to display in the grid. Required. */\n items = input.required<TkCardListItem[]>();\n\n /** Whether the list supports global item selection (checkboxes). */\n selectable = input<boolean>(false);\n\n /** Two-way signal for the current selection of item IDs. */\n selectedIds = model<string[]>([]);\n\n /**\n * Helper method to determine if an individual item is currently selected.\n */\n isItemSelected(id: string): boolean {\n return this.selectedIds().includes(id);\n }\n\n /**\n * Helper method to determine if a card should be marked as selected in the template.\n * Only returns true if the item is explicitly selectable and its ID is in the selected list.\n */\n isCardSelected(item: TkCardListItem): boolean {\n const isSelectable = item.selectable ?? this.selectable();\n return isSelectable ? this.isItemSelected(item.id) : false;\n }\n\n /**\n * Handler for individual card selection change events.\n * Updates the global selectedIds model accordingly.\n */\n onItemSelected(id: string, selected: boolean): void {\n const current = this.selectedIds();\n if (selected && !current.includes(id)) {\n this.selectedIds.set([...current, id]);\n } else if (!selected && current.includes(id)) {\n this.selectedIds.set(current.filter(item => item !== id));\n }\n }\n}\n","<div class=\"tk-card-list-grid\">\n @for (item of items(); track item.id) {\n <div class=\"tk-card-list-item\">\n <tk-card\n [title]=\"item.title\"\n [titleIcon]=\"item.titleIcon!\"\n [description]=\"item.description!\"\n [image]=\"item.image!\"\n [badgeText]=\"item.badgeText!\"\n [secondaryBadgeText]=\"item.secondaryBadgeText!\"\n [actions]=\"item.actions || []\"\n [infoElements]=\"item.infoElements || []\"\n [selectable]=\"item.selectable ?? selectable()\"\n [selected]=\"isCardSelected(item)\"\n (selectedChange)=\"onItemSelected(item.id, $event)\">\n </tk-card>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, model, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import * as i1 from 'primeng/menu';
|
|
5
|
+
import { MenuModule } from 'primeng/menu';
|
|
6
|
+
import { ButtonComponent } from '@tekus/design-system/components/button';
|
|
7
|
+
import { CheckboxComponent } from '@tekus/design-system/components/checkbox';
|
|
8
|
+
import { IconComponent } from '@tekus/design-system/components/icon';
|
|
9
|
+
import { ProgressBarComponent } from '@tekus/design-system/components/progress-bar';
|
|
10
|
+
import { StatusBarComponent } from '@tekus/design-system/components/status-bar';
|
|
11
|
+
import { TagComponent } from '@tekus/design-system/components/tag';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @component CardComponent
|
|
15
|
+
* @description
|
|
16
|
+
* Flexible card component used to display grouped content with multiple layout options.
|
|
17
|
+
* Supports vertical and horizontal orientations, optional images, headers with selection,
|
|
18
|
+
* and dynamic action buttons (with overflow menu support).
|
|
19
|
+
*
|
|
20
|
+
* It utilizes Angular 21 Signals for efficient state management and reactivity.
|
|
21
|
+
*
|
|
22
|
+
* @usage
|
|
23
|
+
* ```html
|
|
24
|
+
* <tk-card
|
|
25
|
+
* title="My Document"
|
|
26
|
+
* description="Upload in progress..."
|
|
27
|
+
* layout="horizontal"
|
|
28
|
+
* [actions]="myActions"
|
|
29
|
+
* [infoElements]="[{ type: 'progress-bar', value: 75 }]">
|
|
30
|
+
* </tk-card>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
class CardComponent {
|
|
34
|
+
constructor() {
|
|
35
|
+
/** The primary title of the card. Required. */
|
|
36
|
+
this.title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
37
|
+
/** Optional icon to display next to the title. */
|
|
38
|
+
this.titleIcon = input(...(ngDevMode ? [undefined, { debugName: "titleIcon" }] : /* istanbul ignore next */ []));
|
|
39
|
+
/** Optional secondary description. */
|
|
40
|
+
this.description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** Optional image URL or source. */
|
|
42
|
+
this.image = input(...(ngDevMode ? [undefined, { debugName: "image" }] : /* istanbul ignore next */ []));
|
|
43
|
+
/** Whether to show the image section. If true and no URL is provided, a placeholder is shown. */
|
|
44
|
+
this.showImage = input(true, ...(ngDevMode ? [{ debugName: "showImage" }] : /* istanbul ignore next */ []));
|
|
45
|
+
/** Layout orientation: 'vertical' (default) or 'horizontal'. */
|
|
46
|
+
this.layout = input('vertical', ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
47
|
+
/** Whether the card shows a checkbox for selection. */
|
|
48
|
+
this.selectable = input(false, ...(ngDevMode ? [{ debugName: "selectable" }] : /* istanbul ignore next */ []));
|
|
49
|
+
/** Two-way signal for the selection state. */
|
|
50
|
+
this.selected = model(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
51
|
+
/** Optional ID or primary badge text displayed in the header. */
|
|
52
|
+
this.badgeText = input(...(ngDevMode ? [undefined, { debugName: "badgeText" }] : /* istanbul ignore next */ []));
|
|
53
|
+
/** Optional secondary metadata text (e.g. file size) displayed next to the badge. */
|
|
54
|
+
this.secondaryBadgeText = input(...(ngDevMode ? [undefined, { debugName: "secondaryBadgeText" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/** List of actions associated with the card. */
|
|
56
|
+
this.actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
|
|
57
|
+
/** Dynamic list of informational elements (tags, progress bars, etc.). */
|
|
58
|
+
this.infoElements = input([], ...(ngDevMode ? [{ debugName: "infoElements" }] : /* istanbul ignore next */ []));
|
|
59
|
+
/**
|
|
60
|
+
* Computed logic for handling actions.
|
|
61
|
+
* If there are > 3 actions, they are all moved to an overflow menu.
|
|
62
|
+
* Otherwise, they are displayed as individual buttons.
|
|
63
|
+
*/
|
|
64
|
+
this.hasOverflowActions = computed(() => this.actions().length > 3, ...(ngDevMode ? [{ debugName: "hasOverflowActions" }] : /* istanbul ignore next */ []));
|
|
65
|
+
/** Actions to be displayed directly as buttons. */
|
|
66
|
+
this.visibleActions = computed(() => this.hasOverflowActions() ? [] : this.actions(), ...(ngDevMode ? [{ debugName: "visibleActions" }] : /* istanbul ignore next */ []));
|
|
67
|
+
/**
|
|
68
|
+
* Actions to be displayed in the overflow menu.
|
|
69
|
+
* Maps TkCardAction to PrimeNG MenuItem format.
|
|
70
|
+
*/
|
|
71
|
+
this.menuItems = computed(() => {
|
|
72
|
+
if (!this.hasOverflowActions())
|
|
73
|
+
return [];
|
|
74
|
+
return this.actions().map(action => ({
|
|
75
|
+
label: action.label,
|
|
76
|
+
icon: action.icon ? `fa fa-${action.icon}` : undefined,
|
|
77
|
+
disabled: action.disabled,
|
|
78
|
+
command: () => action.handler()
|
|
79
|
+
}));
|
|
80
|
+
}, ...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Maps card severity to button severity.
|
|
84
|
+
*/
|
|
85
|
+
getButtonSeverity(severity) {
|
|
86
|
+
if (severity === 'danger')
|
|
87
|
+
return 'danger';
|
|
88
|
+
if (severity === 'secondary')
|
|
89
|
+
return 'secondary';
|
|
90
|
+
return 'primary';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Maps card severity to status bar severity.
|
|
94
|
+
*/
|
|
95
|
+
getStatusBarSeverity(severity) {
|
|
96
|
+
if (severity === 'danger')
|
|
97
|
+
return 'error';
|
|
98
|
+
if (severity === 'success')
|
|
99
|
+
return 'success';
|
|
100
|
+
if (severity === 'secondary')
|
|
101
|
+
return 'secondary';
|
|
102
|
+
return 'primary';
|
|
103
|
+
}
|
|
104
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
105
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: CardComponent, isStandalone: true, selector: "tk-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, titleIcon: { classPropertyName: "titleIcon", publicName: "titleIcon", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, showImage: { classPropertyName: "showImage", publicName: "showImage", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, badgeText: { classPropertyName: "badgeText", publicName: "badgeText", isSignal: true, isRequired: false, transformFunction: null }, secondaryBadgeText: { classPropertyName: "secondaryBadgeText", publicName: "secondaryBadgeText", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, infoElements: { classPropertyName: "infoElements", publicName: "infoElements", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange" }, ngImport: i0, template: "<div \n class=\"tk-card\" \n [class.tk-card-horizontal]=\"layout() === 'horizontal'\"\n [class.tk-card-selectable]=\"selectable()\"\n [class.tk-card-selected]=\"selectable() && selected()\"\n [class.tk-card-no-image]=\"!showImage()\"\n [attr.aria-pressed]=\"selectable() ? selected() : null\">\n \n <!-- Header: Selection, Metadata, and Actions -->\n @if (selectable() || badgeText() || secondaryBadgeText() || actions().length > 0) {\n <div class=\"tk-card-header\">\n <div class=\"tk-card-header-left\">\n @if (selectable()) {\n <div \n class=\"tk-card-selection\" \n tabindex=\"-1\">\n <tk-checkbox [binary]=\"true\" [(model)]=\"selected\"></tk-checkbox>\n </div>\n }\n @if (badgeText() || secondaryBadgeText()) {\n <div class=\"tk-card-metadata\">\n @if (badgeText()) {\n <tk-tag [value]=\"badgeText()!\"></tk-tag>\n }\n @if (secondaryBadgeText()) {\n <span class=\"tk-card-metadata-secondary\">{{ secondaryBadgeText() }}</span>\n }\n </div>\n }\n </div>\n\n <div \n class=\"tk-card-actions\" \n tabindex=\"-1\">\n <!-- Visible Actions (up to 3) -->\n @for (action of visibleActions(); track action.id) {\n <tk-button \n [icon]=\"action.icon\" \n [severity]=\"getButtonSeverity(action.severity)\"\n variant=\"text\"\n [disabled]=\"action.disabled || false\"\n [tooltipText]=\"action.label\"\n size=\"small\"\n (clicked)=\"action.handler()\">\n </tk-button>\n }\n\n <!-- Overflow Menu (> 3 actions) -->\n @if (hasOverflowActions()) {\n <div class=\"tk-card-overflow\">\n <p-menu #menu [model]=\"menuItems()\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <tk-button \n icon=\"ellipsis-vertical\" \n severity=\"secondary\" \n variant=\"text\" \n size=\"small\"\n (click)=\"menu.toggle($event)\"\n (keydown.enter)=\"menu.toggle($event)\"\n (keydown.space)=\"menu.toggle($event); $event.preventDefault()\">\n </tk-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Image Section -->\n @if (showImage()) {\n <div class=\"tk-card-image-container\">\n @if (image()) {\n <div \n class=\"tk-card-image\" \n [style.background-image]=\"'url(' + image() + ')'\">\n </div>\n } @else {\n <div class=\"tk-card-image-placeholder\">\n <tk-icon icon=\"image\" size=\"lg\"></tk-icon>\n </div>\n }\n </div>\n }\n\n <!-- Content Section -->\n <div class=\"tk-card-content\">\n <div class=\"tk-card-body\">\n <h3 class=\"tk-card-title\">\n @if (titleIcon()) {\n <tk-icon [icon]=\"titleIcon()!\" size=\"sm\"></tk-icon>\n }\n {{ title() }}\n </h3>\n @if (description()) {\n <p class=\"tk-card-description\">{{ description() }}</p>\n }\n </div>\n\n @if (infoElements().length > 0) {\n <div class=\"tk-card-info-elements\">\n @for (element of infoElements(); track $index) {\n <div class=\"tk-card-info-item\">\n @switch (element.type) {\n @case ('progress-bar') {\n <div class=\"tk-card-info-progress\">\n @if (element.label) {\n <span class=\"tk-card-info-progress-label\">{{ element.label }}</span>\n }\n <tk-progress-bar [value]=\"element.value || 0\" size=\"small\"></tk-progress-bar>\n </div>\n }\n @case ('tag') {\n <tk-tag [value]=\"element.label || ''\" [severity]=\"element.severity || 'secondary'\"></tk-tag>\n }\n @case ('chip') {\n <!-- Using tag for chips as per design system style -->\n <tk-tag [value]=\"element.label || ''\" [severity]=\"element.severity || 'secondary'\"></tk-tag>\n }\n @case ('status-bar') {\n <tk-status-bar \n [label]=\"element.label || ''\" \n [barLabel]=\"element.barLabel || ''\"\n [severity]=\"getStatusBarSeverity(element.severity)\">\n </tk-status-bar>\n }\n @case ('button') {\n <tk-button \n [label]=\"element.label\" \n [icon]=\"element.icon\" \n [severity]=\"getButtonSeverity(element.severity)\"\n size=\"small\"\n (clicked)=\"element.handler ? element.handler() : null\">\n </tk-button>\n }\n @case ('icon') {\n <tk-icon [icon]=\"element.icon || ''\"></tk-icon>\n }\n @case ('string') {\n <span class=\"tk-card-info-text\">{{ element.label }}</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.tk-card{background-color:var(--tk-color-base-surface-0);border:1px solid var(--tk-color-base-surface-200);border-radius:var(--tk-borderRadius-m);display:flex;flex-direction:column;position:relative;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);width:100%;box-shadow:0 1px 3px rgba(var(--tk-color-base-surface-1000),.05)}.tk-card.tk-card-selectable:hover{border-color:var(--tk-color-base-primary-300);box-shadow:0 4px 12px rgba(var(--tk-color-base-surface-1000),.08);transform:translateY(-2px)}.tk-card.tk-card-selected{border-color:var(--tk-color-base-primary-500);background-color:var(--tk-color-base-sky-100)}.tk-card .tk-card-header{display:flex;justify-content:space-between;align-items:center;padding:var(--tk-spacing-paddingX-s);min-height:var(--tk-spacing-base-300);z-index:2}.tk-card .tk-card-header .tk-card-header-left{display:flex;align-items:center;gap:var(--tk-spacing-base-100)}.tk-card .tk-card-header .tk-card-metadata{display:flex;align-items:center;gap:var(--tk-spacing-base-75)}.tk-card .tk-card-header .tk-card-metadata tk-tag ::ng-deep .p-tag{background-color:var(--tk-color-base-surface-100)!important;color:var(--tk-color-text-default)!important;font-weight:500}.tk-card .tk-card-header .tk-card-metadata .tk-card-metadata-secondary{font-size:var(--tk-font-size-legal-m);color:var(--tk-color-text-subtle);font-weight:400}.tk-card .tk-card-header .tk-card-actions{display:flex;align-items:center;gap:var(--tk-spacing-base-25)}.tk-card .tk-card-image-container{background-color:var(--tk-color-base-surface-100);display:flex;justify-content:center;align-items:center;width:100%;position:relative}.tk-card .tk-card-image-container .tk-card-image{width:100%;height:100%;background-size:contain;background-position:center;background-repeat:no-repeat}.tk-card .tk-card-image-container .tk-card-image-placeholder{color:var(--tk-color-base-surface-400);display:flex;justify-content:center;align-items:center;width:100%;height:100%}.tk-card .tk-card-image-container .tk-card-image-placeholder tk-icon{font-size:3rem;opacity:.5}.tk-card .tk-card-content{padding:var(--tk-spacing-paddingX-m);display:flex;flex-direction:column;gap:var(--tk-spacing-gap-s);flex:1}.tk-card .tk-card-content .tk-card-body{display:flex;flex-direction:column;gap:var(--tk-spacing-base-25)}.tk-card .tk-card-content .tk-card-title{margin:0;font-size:var(--tk-font-size-paragraph-m);font-weight:var(--tk-font-weight-600);color:var(--tk-color-text-default);display:flex;align-items:center;gap:var(--tk-spacing-base-50);line-height:normal}.tk-card .tk-card-content .tk-card-description{margin:0;font-size:var(--tk-font-size-paragraph-s);color:var(--tk-color-text-subtle);line-height:1.5}.tk-card .tk-card-content .tk-card-info-elements{display:flex;flex-direction:column;gap:var(--tk-spacing-base-100);margin-top:auto}.tk-card .tk-card-content .tk-card-info-progress{display:flex;flex-direction:row;align-items:center;gap:var(--tk-spacing-base-75)}.tk-card .tk-card-content .tk-card-info-progress .tk-card-info-progress-label{font-size:var(--tk-font-size-legal-m);font-weight:600;color:var(--tk-color-text-default);min-width:fit-content}.tk-card .tk-card-content .tk-card-info-progress tk-progress-bar{flex:1}.tk-card .tk-card-content .tk-card-info-text{font-size:var(--tk-font-size-legal-m);color:var(--tk-color-text-default);line-height:normal}.tk-card.tk-card-horizontal{flex-direction:row;min-height:11.25rem;display:grid;grid-template-columns:11.25rem 1fr;grid-template-rows:auto 1fr}.tk-card.tk-card-horizontal.tk-card-no-image{grid-template-columns:1fr;min-height:auto}.tk-card.tk-card-horizontal .tk-card-image-container{grid-row:1/span 2;grid-column:1;width:11.25rem;min-width:11.25rem;height:100%;border-right:1px solid var(--tk-color-base-surface-100)}.tk-card.tk-card-horizontal .tk-card-header{grid-column:2;grid-row:1}.tk-card.tk-card-horizontal .tk-card-content{grid-column:2;grid-row:2;margin-top:0}.tk-card:not(.tk-card-horizontal) .tk-card-image-container{height:13.75rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i1.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo", "motionOptions"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "tooltipText", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: ProgressBarComponent, selector: "tk-progress-bar", inputs: ["value", "showValue", "size"] }, { kind: "component", type: StatusBarComponent, selector: "tk-status-bar", inputs: ["label", "severity", "size", "barLabel"] }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
106
|
+
}
|
|
107
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: CardComponent, decorators: [{
|
|
108
|
+
type: Component,
|
|
109
|
+
args: [{ selector: 'tk-card', standalone: true, imports: [
|
|
110
|
+
CommonModule,
|
|
111
|
+
MenuModule,
|
|
112
|
+
ButtonComponent,
|
|
113
|
+
CheckboxComponent,
|
|
114
|
+
IconComponent,
|
|
115
|
+
ProgressBarComponent,
|
|
116
|
+
StatusBarComponent,
|
|
117
|
+
TagComponent
|
|
118
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div \n class=\"tk-card\" \n [class.tk-card-horizontal]=\"layout() === 'horizontal'\"\n [class.tk-card-selectable]=\"selectable()\"\n [class.tk-card-selected]=\"selectable() && selected()\"\n [class.tk-card-no-image]=\"!showImage()\"\n [attr.aria-pressed]=\"selectable() ? selected() : null\">\n \n <!-- Header: Selection, Metadata, and Actions -->\n @if (selectable() || badgeText() || secondaryBadgeText() || actions().length > 0) {\n <div class=\"tk-card-header\">\n <div class=\"tk-card-header-left\">\n @if (selectable()) {\n <div \n class=\"tk-card-selection\" \n tabindex=\"-1\">\n <tk-checkbox [binary]=\"true\" [(model)]=\"selected\"></tk-checkbox>\n </div>\n }\n @if (badgeText() || secondaryBadgeText()) {\n <div class=\"tk-card-metadata\">\n @if (badgeText()) {\n <tk-tag [value]=\"badgeText()!\"></tk-tag>\n }\n @if (secondaryBadgeText()) {\n <span class=\"tk-card-metadata-secondary\">{{ secondaryBadgeText() }}</span>\n }\n </div>\n }\n </div>\n\n <div \n class=\"tk-card-actions\" \n tabindex=\"-1\">\n <!-- Visible Actions (up to 3) -->\n @for (action of visibleActions(); track action.id) {\n <tk-button \n [icon]=\"action.icon\" \n [severity]=\"getButtonSeverity(action.severity)\"\n variant=\"text\"\n [disabled]=\"action.disabled || false\"\n [tooltipText]=\"action.label\"\n size=\"small\"\n (clicked)=\"action.handler()\">\n </tk-button>\n }\n\n <!-- Overflow Menu (> 3 actions) -->\n @if (hasOverflowActions()) {\n <div class=\"tk-card-overflow\">\n <p-menu #menu [model]=\"menuItems()\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <tk-button \n icon=\"ellipsis-vertical\" \n severity=\"secondary\" \n variant=\"text\" \n size=\"small\"\n (click)=\"menu.toggle($event)\"\n (keydown.enter)=\"menu.toggle($event)\"\n (keydown.space)=\"menu.toggle($event); $event.preventDefault()\">\n </tk-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Image Section -->\n @if (showImage()) {\n <div class=\"tk-card-image-container\">\n @if (image()) {\n <div \n class=\"tk-card-image\" \n [style.background-image]=\"'url(' + image() + ')'\">\n </div>\n } @else {\n <div class=\"tk-card-image-placeholder\">\n <tk-icon icon=\"image\" size=\"lg\"></tk-icon>\n </div>\n }\n </div>\n }\n\n <!-- Content Section -->\n <div class=\"tk-card-content\">\n <div class=\"tk-card-body\">\n <h3 class=\"tk-card-title\">\n @if (titleIcon()) {\n <tk-icon [icon]=\"titleIcon()!\" size=\"sm\"></tk-icon>\n }\n {{ title() }}\n </h3>\n @if (description()) {\n <p class=\"tk-card-description\">{{ description() }}</p>\n }\n </div>\n\n @if (infoElements().length > 0) {\n <div class=\"tk-card-info-elements\">\n @for (element of infoElements(); track $index) {\n <div class=\"tk-card-info-item\">\n @switch (element.type) {\n @case ('progress-bar') {\n <div class=\"tk-card-info-progress\">\n @if (element.label) {\n <span class=\"tk-card-info-progress-label\">{{ element.label }}</span>\n }\n <tk-progress-bar [value]=\"element.value || 0\" size=\"small\"></tk-progress-bar>\n </div>\n }\n @case ('tag') {\n <tk-tag [value]=\"element.label || ''\" [severity]=\"element.severity || 'secondary'\"></tk-tag>\n }\n @case ('chip') {\n <!-- Using tag for chips as per design system style -->\n <tk-tag [value]=\"element.label || ''\" [severity]=\"element.severity || 'secondary'\"></tk-tag>\n }\n @case ('status-bar') {\n <tk-status-bar \n [label]=\"element.label || ''\" \n [barLabel]=\"element.barLabel || ''\"\n [severity]=\"getStatusBarSeverity(element.severity)\">\n </tk-status-bar>\n }\n @case ('button') {\n <tk-button \n [label]=\"element.label\" \n [icon]=\"element.icon\" \n [severity]=\"getButtonSeverity(element.severity)\"\n size=\"small\"\n (clicked)=\"element.handler ? element.handler() : null\">\n </tk-button>\n }\n @case ('icon') {\n <tk-icon [icon]=\"element.icon || ''\"></tk-icon>\n }\n @case ('string') {\n <span class=\"tk-card-info-text\">{{ element.label }}</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%}.tk-card{background-color:var(--tk-color-base-surface-0);border:1px solid var(--tk-color-base-surface-200);border-radius:var(--tk-borderRadius-m);display:flex;flex-direction:column;position:relative;overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1);width:100%;box-shadow:0 1px 3px rgba(var(--tk-color-base-surface-1000),.05)}.tk-card.tk-card-selectable:hover{border-color:var(--tk-color-base-primary-300);box-shadow:0 4px 12px rgba(var(--tk-color-base-surface-1000),.08);transform:translateY(-2px)}.tk-card.tk-card-selected{border-color:var(--tk-color-base-primary-500);background-color:var(--tk-color-base-sky-100)}.tk-card .tk-card-header{display:flex;justify-content:space-between;align-items:center;padding:var(--tk-spacing-paddingX-s);min-height:var(--tk-spacing-base-300);z-index:2}.tk-card .tk-card-header .tk-card-header-left{display:flex;align-items:center;gap:var(--tk-spacing-base-100)}.tk-card .tk-card-header .tk-card-metadata{display:flex;align-items:center;gap:var(--tk-spacing-base-75)}.tk-card .tk-card-header .tk-card-metadata tk-tag ::ng-deep .p-tag{background-color:var(--tk-color-base-surface-100)!important;color:var(--tk-color-text-default)!important;font-weight:500}.tk-card .tk-card-header .tk-card-metadata .tk-card-metadata-secondary{font-size:var(--tk-font-size-legal-m);color:var(--tk-color-text-subtle);font-weight:400}.tk-card .tk-card-header .tk-card-actions{display:flex;align-items:center;gap:var(--tk-spacing-base-25)}.tk-card .tk-card-image-container{background-color:var(--tk-color-base-surface-100);display:flex;justify-content:center;align-items:center;width:100%;position:relative}.tk-card .tk-card-image-container .tk-card-image{width:100%;height:100%;background-size:contain;background-position:center;background-repeat:no-repeat}.tk-card .tk-card-image-container .tk-card-image-placeholder{color:var(--tk-color-base-surface-400);display:flex;justify-content:center;align-items:center;width:100%;height:100%}.tk-card .tk-card-image-container .tk-card-image-placeholder tk-icon{font-size:3rem;opacity:.5}.tk-card .tk-card-content{padding:var(--tk-spacing-paddingX-m);display:flex;flex-direction:column;gap:var(--tk-spacing-gap-s);flex:1}.tk-card .tk-card-content .tk-card-body{display:flex;flex-direction:column;gap:var(--tk-spacing-base-25)}.tk-card .tk-card-content .tk-card-title{margin:0;font-size:var(--tk-font-size-paragraph-m);font-weight:var(--tk-font-weight-600);color:var(--tk-color-text-default);display:flex;align-items:center;gap:var(--tk-spacing-base-50);line-height:normal}.tk-card .tk-card-content .tk-card-description{margin:0;font-size:var(--tk-font-size-paragraph-s);color:var(--tk-color-text-subtle);line-height:1.5}.tk-card .tk-card-content .tk-card-info-elements{display:flex;flex-direction:column;gap:var(--tk-spacing-base-100);margin-top:auto}.tk-card .tk-card-content .tk-card-info-progress{display:flex;flex-direction:row;align-items:center;gap:var(--tk-spacing-base-75)}.tk-card .tk-card-content .tk-card-info-progress .tk-card-info-progress-label{font-size:var(--tk-font-size-legal-m);font-weight:600;color:var(--tk-color-text-default);min-width:fit-content}.tk-card .tk-card-content .tk-card-info-progress tk-progress-bar{flex:1}.tk-card .tk-card-content .tk-card-info-text{font-size:var(--tk-font-size-legal-m);color:var(--tk-color-text-default);line-height:normal}.tk-card.tk-card-horizontal{flex-direction:row;min-height:11.25rem;display:grid;grid-template-columns:11.25rem 1fr;grid-template-rows:auto 1fr}.tk-card.tk-card-horizontal.tk-card-no-image{grid-template-columns:1fr;min-height:auto}.tk-card.tk-card-horizontal .tk-card-image-container{grid-row:1/span 2;grid-column:1;width:11.25rem;min-width:11.25rem;height:100%;border-right:1px solid var(--tk-color-base-surface-100)}.tk-card.tk-card-horizontal .tk-card-header{grid-column:2;grid-row:1}.tk-card.tk-card-horizontal .tk-card-content{grid-column:2;grid-row:2;margin-top:0}.tk-card:not(.tk-card-horizontal) .tk-card-image-container{height:13.75rem}\n"] }]
|
|
119
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], titleIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleIcon", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], image: [{ type: i0.Input, args: [{ isSignal: true, alias: "image", required: false }] }], showImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showImage", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], badgeText: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeText", required: false }] }], secondaryBadgeText: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryBadgeText", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], infoElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoElements", required: false }] }] } });
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Generated bundle index. Do not edit.
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
export { CardComponent };
|
|
126
|
+
//# sourceMappingURL=tekus-design-system-components-card.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-card.mjs","sources":["../../../projects/design-system/components/card/src/card.component.ts","../../../projects/design-system/components/card/src/card.component.html","../../../projects/design-system/components/card/tekus-design-system-components-card.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, model } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MenuModule } from 'primeng/menu';\nimport { MenuItem } from 'primeng/api';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { CheckboxComponent } from '@tekus/design-system/components/checkbox';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { ProgressBarComponent } from '@tekus/design-system/components/progress-bar';\nimport { StatusBarComponent } from '@tekus/design-system/components/status-bar';\nimport { TagComponent } from '@tekus/design-system/components/tag';\nimport { TkCardAction, TkCardInfoElement, TkCardLayout } from './card.types';\n\n/**\n * @component CardComponent\n * @description\n * Flexible card component used to display grouped content with multiple layout options.\n * Supports vertical and horizontal orientations, optional images, headers with selection,\n * and dynamic action buttons (with overflow menu support).\n *\n * It utilizes Angular 21 Signals for efficient state management and reactivity.\n *\n * @usage\n * ```html\n * <tk-card\n * title=\"My Document\"\n * description=\"Upload in progress...\"\n * layout=\"horizontal\"\n * [actions]=\"myActions\"\n * [infoElements]=\"[{ type: 'progress-bar', value: 75 }]\">\n * </tk-card>\n * ```\n */\n@Component({\n selector: 'tk-card',\n standalone: true,\n imports: [\n CommonModule,\n MenuModule,\n ButtonComponent,\n CheckboxComponent,\n IconComponent,\n ProgressBarComponent,\n StatusBarComponent,\n TagComponent\n ],\n templateUrl: './card.component.html',\n styleUrl: './card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CardComponent {\n /** The primary title of the card. Required. */\n title = input.required<string>();\n\n /** Optional icon to display next to the title. */\n titleIcon = input<string>();\n\n /** Optional secondary description. */\n description = input<string>();\n\n /** Optional image URL or source. */\n image = input<string>();\n\n /** Whether to show the image section. If true and no URL is provided, a placeholder is shown. */\n showImage = input<boolean>(true);\n\n /** Layout orientation: 'vertical' (default) or 'horizontal'. */\n layout = input<TkCardLayout>('vertical');\n\n /** Whether the card shows a checkbox for selection. */\n selectable = input<boolean>(false);\n\n /** Two-way signal for the selection state. */\n selected = model<boolean>(false);\n\n /** Optional ID or primary badge text displayed in the header. */\n badgeText = input<string>();\n\n /** Optional secondary metadata text (e.g. file size) displayed next to the badge. */\n secondaryBadgeText = input<string>();\n\n /** List of actions associated with the card. */\n actions = input<TkCardAction[]>([]);\n\n /** Dynamic list of informational elements (tags, progress bars, etc.). */\n infoElements = input<TkCardInfoElement[]>([]);\n\n /**\n * Computed logic for handling actions.\n * If there are > 3 actions, they are all moved to an overflow menu.\n * Otherwise, they are displayed as individual buttons.\n */\n hasOverflowActions = computed(() => this.actions().length > 3);\n\n /** Actions to be displayed directly as buttons. */\n visibleActions = computed(() => this.hasOverflowActions() ? [] : this.actions());\n\n /** \n * Actions to be displayed in the overflow menu.\n * Maps TkCardAction to PrimeNG MenuItem format.\n */\n menuItems = computed<MenuItem[]>(() => {\n if (!this.hasOverflowActions()) return [];\n return this.actions().map(action => ({\n label: action.label,\n icon: action.icon ? `fa fa-${action.icon}` : undefined,\n disabled: action.disabled,\n command: () => action.handler()\n }));\n });\n\n /**\n * Maps card severity to button severity.\n */\n getButtonSeverity(severity?: string): 'primary' | 'secondary' | 'danger' {\n if (severity === 'danger') return 'danger';\n if (severity === 'secondary') return 'secondary';\n return 'primary';\n }\n\n /**\n * Maps card severity to status bar severity.\n */\n getStatusBarSeverity(severity?: string): 'primary' | 'secondary' | 'success' | 'error' {\n if (severity === 'danger') return 'error';\n if (severity === 'success') return 'success';\n if (severity === 'secondary') return 'secondary';\n return 'primary';\n }\n}\n","<div \n class=\"tk-card\" \n [class.tk-card-horizontal]=\"layout() === 'horizontal'\"\n [class.tk-card-selectable]=\"selectable()\"\n [class.tk-card-selected]=\"selectable() && selected()\"\n [class.tk-card-no-image]=\"!showImage()\"\n [attr.aria-pressed]=\"selectable() ? selected() : null\">\n \n <!-- Header: Selection, Metadata, and Actions -->\n @if (selectable() || badgeText() || secondaryBadgeText() || actions().length > 0) {\n <div class=\"tk-card-header\">\n <div class=\"tk-card-header-left\">\n @if (selectable()) {\n <div \n class=\"tk-card-selection\" \n tabindex=\"-1\">\n <tk-checkbox [binary]=\"true\" [(model)]=\"selected\"></tk-checkbox>\n </div>\n }\n @if (badgeText() || secondaryBadgeText()) {\n <div class=\"tk-card-metadata\">\n @if (badgeText()) {\n <tk-tag [value]=\"badgeText()!\"></tk-tag>\n }\n @if (secondaryBadgeText()) {\n <span class=\"tk-card-metadata-secondary\">{{ secondaryBadgeText() }}</span>\n }\n </div>\n }\n </div>\n\n <div \n class=\"tk-card-actions\" \n tabindex=\"-1\">\n <!-- Visible Actions (up to 3) -->\n @for (action of visibleActions(); track action.id) {\n <tk-button \n [icon]=\"action.icon\" \n [severity]=\"getButtonSeverity(action.severity)\"\n variant=\"text\"\n [disabled]=\"action.disabled || false\"\n [tooltipText]=\"action.label\"\n size=\"small\"\n (clicked)=\"action.handler()\">\n </tk-button>\n }\n\n <!-- Overflow Menu (> 3 actions) -->\n @if (hasOverflowActions()) {\n <div class=\"tk-card-overflow\">\n <p-menu #menu [model]=\"menuItems()\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <tk-button \n icon=\"ellipsis-vertical\" \n severity=\"secondary\" \n variant=\"text\" \n size=\"small\"\n (click)=\"menu.toggle($event)\"\n (keydown.enter)=\"menu.toggle($event)\"\n (keydown.space)=\"menu.toggle($event); $event.preventDefault()\">\n </tk-button>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Image Section -->\n @if (showImage()) {\n <div class=\"tk-card-image-container\">\n @if (image()) {\n <div \n class=\"tk-card-image\" \n [style.background-image]=\"'url(' + image() + ')'\">\n </div>\n } @else {\n <div class=\"tk-card-image-placeholder\">\n <tk-icon icon=\"image\" size=\"lg\"></tk-icon>\n </div>\n }\n </div>\n }\n\n <!-- Content Section -->\n <div class=\"tk-card-content\">\n <div class=\"tk-card-body\">\n <h3 class=\"tk-card-title\">\n @if (titleIcon()) {\n <tk-icon [icon]=\"titleIcon()!\" size=\"sm\"></tk-icon>\n }\n {{ title() }}\n </h3>\n @if (description()) {\n <p class=\"tk-card-description\">{{ description() }}</p>\n }\n </div>\n\n @if (infoElements().length > 0) {\n <div class=\"tk-card-info-elements\">\n @for (element of infoElements(); track $index) {\n <div class=\"tk-card-info-item\">\n @switch (element.type) {\n @case ('progress-bar') {\n <div class=\"tk-card-info-progress\">\n @if (element.label) {\n <span class=\"tk-card-info-progress-label\">{{ element.label }}</span>\n }\n <tk-progress-bar [value]=\"element.value || 0\" size=\"small\"></tk-progress-bar>\n </div>\n }\n @case ('tag') {\n <tk-tag [value]=\"element.label || ''\" [severity]=\"element.severity || 'secondary'\"></tk-tag>\n }\n @case ('chip') {\n <!-- Using tag for chips as per design system style -->\n <tk-tag [value]=\"element.label || ''\" [severity]=\"element.severity || 'secondary'\"></tk-tag>\n }\n @case ('status-bar') {\n <tk-status-bar \n [label]=\"element.label || ''\" \n [barLabel]=\"element.barLabel || ''\"\n [severity]=\"getStatusBarSeverity(element.severity)\">\n </tk-status-bar>\n }\n @case ('button') {\n <tk-button \n [label]=\"element.label\" \n [icon]=\"element.icon\" \n [severity]=\"getButtonSeverity(element.severity)\"\n size=\"small\"\n (clicked)=\"element.handler ? element.handler() : null\">\n </tk-button>\n }\n @case ('icon') {\n <tk-icon [icon]=\"element.icon || ''\"></tk-icon>\n }\n @case ('string') {\n <span class=\"tk-card-info-text\">{{ element.label }}</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -224,7 +224,7 @@ class DrawerComponent {
|
|
|
224
224
|
this.returnValueOnClose = null;
|
|
225
225
|
}
|
|
226
226
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: DrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
227
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: DrawerComponent, isStandalone: true, selector: "tk-drawer", inputs: { dialogRef: { classPropertyName: "dialogRef", publicName: "dialogRef", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, headerAction: { classPropertyName: "headerAction", publicName: "headerAction", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, interceptor: { classPropertyName: "interceptor", publicName: "interceptor", isSignal: true, isRequired: false, transformFunction: null }, isOpened: { classPropertyName: "isOpened", publicName: "isOpened", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpened: "isOpenedChange", closed: "closed" }, viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<p-drawer\n [modal]=\"true\"\n [visible]=\"isOpened()\"\n (visibleChange)=\"onVisibleChange($event)\"\n [closable]=\"closable()\"\n [dismissible]=\"dismissible()\"\n [closeOnEscape]=\"true\"\n position=\"right\"\n [style]=\"drawerStyle()\"\n [styleClass]=\"'tk-drawer'\"\n [class.tk-drawer--has-scroll]=\"hasScroll\">\n @if (title() || hasHeaderAction()) {\n <ng-template pTemplate=\"header\">\n <div class=\"tk-drawer__header\">\n <h2 class=\"tk-drawer__title\" [title]=\"title()\">{{ title() }}</h2>\n @if (hasHeaderAction()) {\n <div class=\"tk-drawer__actions\">\n <tk-button\n [label]=\"headerAction()!.label\"\n [severity]=\"headerAction()!.severity\"\n [variant]=\"headerAction()!.variant\"\n (clicked)=\"\n handleHeaderAction(\n headerAction()!.action,\n headerAction()!.returnValue\n )\n \" />\n </div>\n }\n </div>\n </ng-template>\n }\n\n <section class=\"tk-drawer__content\">\n @if (content()) {\n @if (isContentString()) {\n <p [innerHTML]=\"content()\"></p>\n } @else {\n <ng-template #contentHost></ng-template>\n }\n }\n </section>\n</p-drawer>\n", styles: [":host ::ng-deep .tk-drawer{max-height:100vh;display:flex;flex-direction:column}:host ::ng-deep .tk-drawer__content{flex:1;overflow-y:auto;padding:var(--tk-spacing-paddingX-m, 1.5rem)}:host ::ng-deep .p-drawer-content{overflow-y:auto;display:flex;flex-direction:column;flex:1}:host ::ng-deep .p-drawer-close-button{color:var(--tk-color-base-surface-500, #8a8a8b)}:host ::ng-deep .p-drawer-close-button:hover{background:var(--tk-color-base-surface-100, #f0f0f0)!important;color:var(--tk-color-base-surface-500, #8a8a8b)}.tk-drawer--has-scroll .p-drawer-header{border-bottom:1px solid var(--tk-color-base-surface-200, #e2e8f0);box-shadow:0 2px 4px #00000005}.tk-drawer__header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:var(--tk-spacing-base-100, 1rem);flex-shrink:0;width:calc(100% - var(--tk-spacing-base-250, 2.5rem))}.tk-drawer__title{margin:0;font-size:var(--tk-font-size-headers-s, 1.125rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-text-default, #212121);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.tk-drawer__actions{display:flex;flex-direction:row;align-items:center;gap:var(--tk-spacing-base-50, .5rem);flex-shrink:0;padding-right:var(--tk-spacing-paddingX-xs, .25rem)}\n"], dependencies: [{ kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i1.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "tooltipText"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
227
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: DrawerComponent, isStandalone: true, selector: "tk-drawer", inputs: { dialogRef: { classPropertyName: "dialogRef", publicName: "dialogRef", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, headerAction: { classPropertyName: "headerAction", publicName: "headerAction", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, interceptor: { classPropertyName: "interceptor", publicName: "interceptor", isSignal: true, isRequired: false, transformFunction: null }, isOpened: { classPropertyName: "isOpened", publicName: "isOpened", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpened: "isOpenedChange", closed: "closed" }, viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<p-drawer\n [modal]=\"true\"\n [visible]=\"isOpened()\"\n (visibleChange)=\"onVisibleChange($event)\"\n [closable]=\"closable()\"\n [dismissible]=\"dismissible()\"\n [closeOnEscape]=\"true\"\n position=\"right\"\n [style]=\"drawerStyle()\"\n [styleClass]=\"'tk-drawer'\"\n [class.tk-drawer--has-scroll]=\"hasScroll\">\n @if (title() || hasHeaderAction()) {\n <ng-template pTemplate=\"header\">\n <div class=\"tk-drawer__header\">\n <h2 class=\"tk-drawer__title\" [title]=\"title()\">{{ title() }}</h2>\n @if (hasHeaderAction()) {\n <div class=\"tk-drawer__actions\">\n <tk-button\n [label]=\"headerAction()!.label\"\n [severity]=\"headerAction()!.severity\"\n [variant]=\"headerAction()!.variant\"\n (clicked)=\"\n handleHeaderAction(\n headerAction()!.action,\n headerAction()!.returnValue\n )\n \" />\n </div>\n }\n </div>\n </ng-template>\n }\n\n <section class=\"tk-drawer__content\">\n @if (content()) {\n @if (isContentString()) {\n <p [innerHTML]=\"content()\"></p>\n } @else {\n <ng-template #contentHost></ng-template>\n }\n }\n </section>\n</p-drawer>\n", styles: [":host ::ng-deep .tk-drawer{max-height:100vh;display:flex;flex-direction:column}:host ::ng-deep .tk-drawer__content{flex:1;overflow-y:auto;padding:var(--tk-spacing-paddingX-m, 1.5rem)}:host ::ng-deep .p-drawer-content{overflow-y:auto;display:flex;flex-direction:column;flex:1}:host ::ng-deep .p-drawer-close-button{color:var(--tk-color-base-surface-500, #8a8a8b)}:host ::ng-deep .p-drawer-close-button:hover{background:var(--tk-color-base-surface-100, #f0f0f0)!important;color:var(--tk-color-base-surface-500, #8a8a8b)}.tk-drawer--has-scroll .p-drawer-header{border-bottom:1px solid var(--tk-color-base-surface-200, #e2e8f0);box-shadow:0 2px 4px #00000005}.tk-drawer__header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:var(--tk-spacing-base-100, 1rem);flex-shrink:0;width:calc(100% - var(--tk-spacing-base-250, 2.5rem))}.tk-drawer__title{margin:0;font-size:var(--tk-font-size-headers-s, 1.125rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-text-default, #212121);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.tk-drawer__actions{display:flex;flex-direction:row;align-items:center;gap:var(--tk-spacing-base-50, .5rem);flex-shrink:0;padding-right:var(--tk-spacing-paddingX-xs, .25rem)}\n"], dependencies: [{ kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i1.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "tooltipText", "size"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
228
228
|
}
|
|
229
229
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: DrawerComponent, decorators: [{
|
|
230
230
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tekus-design-system-components-drawer.mjs","sources":["../../../projects/design-system/components/drawer/src/drawer.component.ts","../../../projects/design-system/components/drawer/src/drawer.component.html","../../../projects/design-system/components/drawer/src/services/drawer.service.ts","../../../projects/design-system/components/drawer/tekus-design-system-components-drawer.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n model,\n output,\n Type,\n ElementRef,\n ViewContainerRef,\n viewChild,\n ComponentRef,\n effect,\n untracked,\n OnDestroy,\n afterEveryRender,\n inject,\n Injector,\n} from '@angular/core';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { DrawerModule } from 'primeng/drawer';\nimport { DrawerHeaderAction, DrawerSizeType } from './drawer.types';\nimport {\n TkCanClose,\n TkCloseInterceptor,\n TkDialogRef,\n} from '@tekus/design-system/core/types';\n\n/**\n * @component DrawerComponent\n * @description\n * A programmatically controlled drawer overlay used for displaying dynamic content,\n * titles, and header actions. The drawer is opened through a service with a configuration object,\n * similar to tk-modal.\n *\n * This component supports:\n * - Required title with ellipsis for long text.\n * - Optional header action button + close button.\n * - Content as string or component.\n * - Position: always right.\n * - Sizes: small (500px), large (1024px).\n * - Closable and dismissible mask behavior.\n *\n * @usage\n * ### Open a drawer from TypeScript using the drawer service\n * ```ts\n * this.drawerService.open({\n * title: 'Drawer name',\n * content: 'Content text drawer example',\n * headerAction: {\n * label: 'Action',\n * severity: 'primary',\n * action: () => console.log('Action clicked'),\n * returnValue: true,\n * },\n * size: 'small',\n * }).subscribe((result) => {\n * console.log('Drawer closed with value:', result);\n * });\n * ```\n * Modernized for Angular 19 with 100% synchronous Signal-based closing interception.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-drawer',\n imports: [DrawerModule, ButtonComponent],\n templateUrl: './drawer.component.html',\n styleUrl: './drawer.component.scss',\n})\nexport class DrawerComponent<T = unknown> implements OnDestroy {\n private readonly elementRef = inject(ElementRef);\n private readonly injector = inject(Injector);\n\n private readonly contentHost = viewChild('contentHost', {\n read: ViewContainerRef,\n });\n private componentRef?: ComponentRef<T>;\n\n /** The dialog ref associated with this drawer */\n dialogRef = input<TkDialogRef<DrawerComponent<T>, unknown> | null>(null);\n\n /** The required title displayed at the top left of the drawer header */\n title = input.required<string>();\n\n /** The main content of the drawer. Can be a string or a Component Type. */\n content = input<string | Type<T> | null>(null);\n\n /** Optional header action button (displayed before close button) */\n headerAction = input<DrawerHeaderAction | null>(null);\n\n /** Drawer size: 'small' (500px), 'large' (1024px) */\n size = input<DrawerSizeType>('small');\n\n /** Whether the drawer can be closed by the user via close button */\n closable = input<boolean>(true);\n\n /** Whether clicking the mask closes the drawer */\n dismissible = input<boolean>(true);\n\n /** Optional data to be passed as inputs to the dynamic component. */\n data = input<Partial<T>>({});\n\n /** Optional interceptor called before the drawer closes. */\n interceptor = input<TkCloseInterceptor | undefined>(undefined);\n\n isContentString = computed(() => typeof this.content() === 'string');\n hasHeaderAction = computed(() => this.headerAction() != null);\n\n /** Computed: drawer width (responsive) and max-width based on `size`. Always right position. */\n drawerStyle = computed(() => {\n const sz = this.size();\n const maxWidth = sz === 'large' ? '1024px' : '500px';\n return {\n width: 'calc(100vw - 1rem)',\n maxWidth,\n };\n });\n\n /** Visibility flag. Use model for two-way binding when using drawer in template. */\n isOpened = model<boolean>(false);\n\n /** Whether the drawer content has a scrollbar */\n hasScroll = false;\n\n /** Emits when the drawer closes, passing the return value from header action or null */\n readonly closed = output<unknown>();\n private alreadyEmitted = false;\n private returnValueOnClose: unknown = null;\n\n constructor() {\n /**\n * @summary Orchestrates the reactive dynamic lifecycle.\n */\n effect(() => {\n const opened = this.isOpened();\n const host = this.contentHost();\n this.dialogRef();\n\n untracked(() => {\n if (opened && host) {\n this.attachDynamicContent();\n } else if (!opened) {\n this.detachDynamicContent();\n }\n });\n });\n\n effect(() => {\n const currentData = this.data();\n untracked(() => this.syncDynamicInputs(currentData));\n });\n\n afterEveryRender(() => {\n this.checkScroll();\n });\n }\n\n ngOnDestroy(): void {\n this.detachDynamicContent();\n }\n\n private attachDynamicContent(): void {\n const type = this.content();\n const host = this.contentHost();\n\n if (!type || typeof type === 'string' || !host) return;\n this.detachDynamicContent();\n\n const customInjector = Injector.create({\n providers: [{ provide: TkDialogRef, useValue: this.dialogRef() }],\n parent: this.injector,\n });\n\n this.componentRef = host.createComponent(type, {\n injector: customInjector,\n });\n this.syncDynamicInputs(this.data());\n }\n\n private syncDynamicInputs(data: Partial<T>): void {\n if (!this.componentRef) return;\n Object.entries(data).forEach(([key, value]) => {\n this.componentRef?.setInput(key, value);\n });\n }\n\n private detachDynamicContent(): void {\n if (this.componentRef) {\n this.componentRef.destroy();\n this.componentRef = undefined;\n }\n }\n\n /**\n * Checks if the drawer content has a scrollbar and updates `hasScroll` state.\n */\n checkScroll(): void {\n const contentEl =\n this.elementRef.nativeElement.querySelector('.p-drawer-content');\n if (contentEl) {\n this.hasScroll = contentEl.scrollHeight > contentEl.clientHeight;\n }\n }\n\n private wasOpened = false;\n \n /** Opens the drawer */\n open(): void {\n this.isOpened.set(true);\n this.resetClosureState();\n }\n\n /** Marks the drawer as shown to enable closure emission guards */\n handleShow(): void {\n this.wasOpened = true;\n }\n\n /**\n * @summary Main entry point for closure requests.\n * @returns true if closure was executed.\n */\n tryClose(returnValue: unknown = null): boolean {\n if (this.canExecuteClosure()) {\n this.executeClosure(returnValue, arguments.length > 0);\n return true;\n } else {\n const instance = this.componentRef?.instance as TkCanClose | undefined;\n instance?.onBlockedClose?.();\n return false;\n }\n }\n\n private canExecuteClosure(): boolean {\n const instance = this.componentRef?.instance as TkCanClose | undefined;\n const canClose = instance?.canClose ? instance.canClose() : true;\n if (!canClose) return false;\n\n const configInterceptor = this.interceptor();\n if (configInterceptor && !configInterceptor()) return false;\n\n return true;\n }\n\n private executeClosure(returnValue: unknown, hasReturnValue: boolean): void {\n if (hasReturnValue) {\n this.alreadyEmitted = true;\n this.returnValueOnClose = returnValue;\n }\n this.isOpened.set(false);\n this.handleClose();\n }\n\n /** Handles external visibility changes (from p-drawer close button or mask) */\n onVisibleChange(visible: boolean): void {\n if (!visible) {\n const closed = this.tryClose();\n\n if (!closed) {\n this.isOpened.set(true);\n }\n }\n }\n\n /** Closes the drawer and emits onClose */\n handleClose(): void {\n if (this.isOpened()) {\n return;\n }\n const valueToEmit = this.alreadyEmitted ? this.returnValueOnClose : null;\n this.closed.emit(valueToEmit);\n this.resetClosureState();\n }\n\n /** Forcefully closes the drawer without checks */\n close(): void {\n this.tryClose();\n }\n\n /**\n * Handles header action button click.\n */\n handleHeaderAction(\n action: (() => void) | undefined,\n returnValue: unknown\n ): void {\n if (action) action();\n this.tryClose(returnValue);\n }\n\n private resetClosureState(): void {\n this.alreadyEmitted = false;\n this.returnValueOnClose = null;\n }\n}\n","<p-drawer\n [modal]=\"true\"\n [visible]=\"isOpened()\"\n (visibleChange)=\"onVisibleChange($event)\"\n [closable]=\"closable()\"\n [dismissible]=\"dismissible()\"\n [closeOnEscape]=\"true\"\n position=\"right\"\n [style]=\"drawerStyle()\"\n [styleClass]=\"'tk-drawer'\"\n [class.tk-drawer--has-scroll]=\"hasScroll\">\n @if (title() || hasHeaderAction()) {\n <ng-template pTemplate=\"header\">\n <div class=\"tk-drawer__header\">\n <h2 class=\"tk-drawer__title\" [title]=\"title()\">{{ title() }}</h2>\n @if (hasHeaderAction()) {\n <div class=\"tk-drawer__actions\">\n <tk-button\n [label]=\"headerAction()!.label\"\n [severity]=\"headerAction()!.severity\"\n [variant]=\"headerAction()!.variant\"\n (clicked)=\"\n handleHeaderAction(\n headerAction()!.action,\n headerAction()!.returnValue\n )\n \" />\n </div>\n }\n </div>\n </ng-template>\n }\n\n <section class=\"tk-drawer__content\">\n @if (content()) {\n @if (isContentString()) {\n <p [innerHTML]=\"content()\"></p>\n } @else {\n <ng-template #contentHost></ng-template>\n }\n }\n </section>\n</p-drawer>\n","import {\n Injectable,\n ApplicationRef,\n ComponentRef,\n createComponent,\n EmbeddedViewRef,\n inject,\n} from '@angular/core';\nimport { DrawerComponent } from '../drawer.component';\nimport { DrawerConfig } from '../drawer.types';\nimport { TkDialogRef } from '@tekus/design-system/core/types';\n\n@Injectable({ providedIn: 'root' })\nexport class DrawerService {\n private readonly appRef = inject(ApplicationRef);\n\n private dialogRef: TkDialogRef<DrawerComponent<unknown>> | null = null;\n\n get drawerRefForTesting(): ComponentRef<DrawerComponent<unknown>> | null {\n return (\n (this.dialogRef?.componentRef as ComponentRef<\n DrawerComponent<unknown>\n >) || null\n );\n }\n set drawerRefForTesting(ref: ComponentRef<DrawerComponent<unknown>> | null) {\n this.dialogRef = ref ? new TkDialogRef(ref) : null;\n }\n\n open<T = unknown, R = unknown>(\n config: DrawerConfig\n ): TkDialogRef<DrawerComponent<T>, R> {\n if (this.dialogRef) {\n // Clear the previous one without triggering a real \"null\" result\n this.dialogRef.emitClose();\n this.dialogRef.componentRef.destroy();\n this.dialogRef = null;\n }\n\n const componentRef = createComponent(DrawerComponent, {\n environmentInjector: this.appRef.injector,\n }) as ComponentRef<DrawerComponent<T>>;\n\n this.appRef.attachView(componentRef.hostView);\n\n const domElem = (componentRef.hostView as EmbeddedViewRef<unknown>)\n .rootNodes[0] as HTMLElement;\n document.body.appendChild(domElem);\n\n componentRef.setInput('title', config.title);\n componentRef.setInput('content', config.content ?? null);\n componentRef.setInput('headerAction', config.headerAction ?? null);\n componentRef.setInput('size', config.size ?? 'small');\n componentRef.setInput('closable', config.closable ?? true);\n componentRef.setInput('dismissible', config.dismissible ?? true);\n componentRef.setInput('data', config.data ?? {});\n componentRef.setInput('interceptor', config.interceptor ?? undefined);\n\n const dialogRef = new TkDialogRef<DrawerComponent<T>, R>(componentRef);\n componentRef.setInput('dialogRef', dialogRef);\n this.dialogRef = dialogRef as unknown as TkDialogRef<\n DrawerComponent<unknown>\n >;\n\n componentRef.instance.closed.subscribe((value: unknown) => {\n dialogRef.emitClose(value as R);\n\n this.appRef.detachView(componentRef.hostView);\n componentRef.destroy();\n if (this.dialogRef === (dialogRef as unknown)) {\n this.dialogRef = null;\n }\n });\n\n componentRef.instance.open();\n\n return dialogRef;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-drawer.mjs","sources":["../../../projects/design-system/components/drawer/src/drawer.component.ts","../../../projects/design-system/components/drawer/src/drawer.component.html","../../../projects/design-system/components/drawer/src/services/drawer.service.ts","../../../projects/design-system/components/drawer/tekus-design-system-components-drawer.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n model,\n output,\n Type,\n ElementRef,\n ViewContainerRef,\n viewChild,\n ComponentRef,\n effect,\n untracked,\n OnDestroy,\n afterEveryRender,\n inject,\n Injector,\n} from '@angular/core';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { DrawerModule } from 'primeng/drawer';\nimport { DrawerHeaderAction, DrawerSizeType } from './drawer.types';\nimport {\n TkCanClose,\n TkCloseInterceptor,\n TkDialogRef,\n} from '@tekus/design-system/core/types';\n\n/**\n * @component DrawerComponent\n * @description\n * A programmatically controlled drawer overlay used for displaying dynamic content,\n * titles, and header actions. The drawer is opened through a service with a configuration object,\n * similar to tk-modal.\n *\n * This component supports:\n * - Required title with ellipsis for long text.\n * - Optional header action button + close button.\n * - Content as string or component.\n * - Position: always right.\n * - Sizes: small (500px), large (1024px).\n * - Closable and dismissible mask behavior.\n *\n * @usage\n * ### Open a drawer from TypeScript using the drawer service\n * ```ts\n * this.drawerService.open({\n * title: 'Drawer name',\n * content: 'Content text drawer example',\n * headerAction: {\n * label: 'Action',\n * severity: 'primary',\n * action: () => console.log('Action clicked'),\n * returnValue: true,\n * },\n * size: 'small',\n * }).subscribe((result) => {\n * console.log('Drawer closed with value:', result);\n * });\n * ```\n * Modernized for Angular 19 with 100% synchronous Signal-based closing interception.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-drawer',\n imports: [DrawerModule, ButtonComponent],\n templateUrl: './drawer.component.html',\n styleUrl: './drawer.component.scss',\n})\nexport class DrawerComponent<T = unknown> implements OnDestroy {\n private readonly elementRef = inject(ElementRef);\n private readonly injector = inject(Injector);\n\n private readonly contentHost = viewChild('contentHost', {\n read: ViewContainerRef,\n });\n private componentRef?: ComponentRef<T>;\n\n /** The dialog ref associated with this drawer */\n dialogRef = input<TkDialogRef<DrawerComponent<T>, unknown> | null>(null);\n\n /** The required title displayed at the top left of the drawer header */\n title = input.required<string>();\n\n /** The main content of the drawer. Can be a string or a Component Type. */\n content = input<string | Type<T> | null>(null);\n\n /** Optional header action button (displayed before close button) */\n headerAction = input<DrawerHeaderAction | null>(null);\n\n /** Drawer size: 'small' (500px), 'large' (1024px) */\n size = input<DrawerSizeType>('small');\n\n /** Whether the drawer can be closed by the user via close button */\n closable = input<boolean>(true);\n\n /** Whether clicking the mask closes the drawer */\n dismissible = input<boolean>(true);\n\n /** Optional data to be passed as inputs to the dynamic component. */\n data = input<Partial<T>>({});\n\n /** Optional interceptor called before the drawer closes. */\n interceptor = input<TkCloseInterceptor | undefined>(undefined);\n\n isContentString = computed(() => typeof this.content() === 'string');\n hasHeaderAction = computed(() => this.headerAction() != null);\n\n /** Computed: drawer width (responsive) and max-width based on `size`. Always right position. */\n drawerStyle = computed(() => {\n const sz = this.size();\n const maxWidth = sz === 'large' ? '1024px' : '500px';\n return {\n width: 'calc(100vw - 1rem)',\n maxWidth,\n };\n });\n\n /** Visibility flag. Use model for two-way binding when using drawer in template. */\n isOpened = model<boolean>(false);\n\n /** Whether the drawer content has a scrollbar */\n hasScroll = false;\n\n /** Emits when the drawer closes, passing the return value from header action or null */\n readonly closed = output<unknown>();\n private alreadyEmitted = false;\n private returnValueOnClose: unknown = null;\n\n constructor() {\n /**\n * @summary Orchestrates the reactive dynamic lifecycle.\n */\n effect(() => {\n const opened = this.isOpened();\n const host = this.contentHost();\n this.dialogRef();\n\n untracked(() => {\n if (opened && host) {\n this.attachDynamicContent();\n } else if (!opened) {\n this.detachDynamicContent();\n }\n });\n });\n\n effect(() => {\n const currentData = this.data();\n untracked(() => this.syncDynamicInputs(currentData));\n });\n\n afterEveryRender(() => {\n this.checkScroll();\n });\n }\n\n ngOnDestroy(): void {\n this.detachDynamicContent();\n }\n\n private attachDynamicContent(): void {\n const type = this.content();\n const host = this.contentHost();\n\n if (!type || typeof type === 'string' || !host) return;\n this.detachDynamicContent();\n\n const customInjector = Injector.create({\n providers: [{ provide: TkDialogRef, useValue: this.dialogRef() }],\n parent: this.injector,\n });\n\n this.componentRef = host.createComponent(type, {\n injector: customInjector,\n });\n this.syncDynamicInputs(this.data());\n }\n\n private syncDynamicInputs(data: Partial<T>): void {\n if (!this.componentRef) return;\n Object.entries(data).forEach(([key, value]) => {\n this.componentRef?.setInput(key, value);\n });\n }\n\n private detachDynamicContent(): void {\n if (this.componentRef) {\n this.componentRef.destroy();\n this.componentRef = undefined;\n }\n }\n\n /**\n * Checks if the drawer content has a scrollbar and updates `hasScroll` state.\n */\n checkScroll(): void {\n const contentEl =\n this.elementRef.nativeElement.querySelector('.p-drawer-content');\n if (contentEl) {\n this.hasScroll = contentEl.scrollHeight > contentEl.clientHeight;\n }\n }\n\n private wasOpened = false;\n \n /** Opens the drawer */\n open(): void {\n this.isOpened.set(true);\n this.resetClosureState();\n }\n\n /** Marks the drawer as shown to enable closure emission guards */\n handleShow(): void {\n this.wasOpened = true;\n }\n\n /**\n * @summary Main entry point for closure requests.\n * @returns true if closure was executed.\n */\n tryClose(returnValue: unknown = null): boolean {\n if (this.canExecuteClosure()) {\n this.executeClosure(returnValue, arguments.length > 0);\n return true;\n } else {\n const instance = this.componentRef?.instance as TkCanClose | undefined;\n instance?.onBlockedClose?.();\n return false;\n }\n }\n\n private canExecuteClosure(): boolean {\n const instance = this.componentRef?.instance as TkCanClose | undefined;\n const canClose = instance?.canClose ? instance.canClose() : true;\n if (!canClose) return false;\n\n const configInterceptor = this.interceptor();\n if (configInterceptor && !configInterceptor()) return false;\n\n return true;\n }\n\n private executeClosure(returnValue: unknown, hasReturnValue: boolean): void {\n if (hasReturnValue) {\n this.alreadyEmitted = true;\n this.returnValueOnClose = returnValue;\n }\n this.isOpened.set(false);\n this.handleClose();\n }\n\n /** Handles external visibility changes (from p-drawer close button or mask) */\n onVisibleChange(visible: boolean): void {\n if (!visible) {\n const closed = this.tryClose();\n\n if (!closed) {\n this.isOpened.set(true);\n }\n }\n }\n\n /** Closes the drawer and emits onClose */\n handleClose(): void {\n if (this.isOpened()) {\n return;\n }\n const valueToEmit = this.alreadyEmitted ? this.returnValueOnClose : null;\n this.closed.emit(valueToEmit);\n this.resetClosureState();\n }\n\n /** Forcefully closes the drawer without checks */\n close(): void {\n this.tryClose();\n }\n\n /**\n * Handles header action button click.\n */\n handleHeaderAction(\n action: (() => void) | undefined,\n returnValue: unknown\n ): void {\n if (action) action();\n this.tryClose(returnValue);\n }\n\n private resetClosureState(): void {\n this.alreadyEmitted = false;\n this.returnValueOnClose = null;\n }\n}\n","<p-drawer\n [modal]=\"true\"\n [visible]=\"isOpened()\"\n (visibleChange)=\"onVisibleChange($event)\"\n [closable]=\"closable()\"\n [dismissible]=\"dismissible()\"\n [closeOnEscape]=\"true\"\n position=\"right\"\n [style]=\"drawerStyle()\"\n [styleClass]=\"'tk-drawer'\"\n [class.tk-drawer--has-scroll]=\"hasScroll\">\n @if (title() || hasHeaderAction()) {\n <ng-template pTemplate=\"header\">\n <div class=\"tk-drawer__header\">\n <h2 class=\"tk-drawer__title\" [title]=\"title()\">{{ title() }}</h2>\n @if (hasHeaderAction()) {\n <div class=\"tk-drawer__actions\">\n <tk-button\n [label]=\"headerAction()!.label\"\n [severity]=\"headerAction()!.severity\"\n [variant]=\"headerAction()!.variant\"\n (clicked)=\"\n handleHeaderAction(\n headerAction()!.action,\n headerAction()!.returnValue\n )\n \" />\n </div>\n }\n </div>\n </ng-template>\n }\n\n <section class=\"tk-drawer__content\">\n @if (content()) {\n @if (isContentString()) {\n <p [innerHTML]=\"content()\"></p>\n } @else {\n <ng-template #contentHost></ng-template>\n }\n }\n </section>\n</p-drawer>\n","import {\n Injectable,\n ApplicationRef,\n ComponentRef,\n createComponent,\n EmbeddedViewRef,\n inject,\n} from '@angular/core';\nimport { DrawerComponent } from '../drawer.component';\nimport { DrawerConfig } from '../drawer.types';\nimport { TkDialogRef } from '@tekus/design-system/core/types';\n\n@Injectable({ providedIn: 'root' })\nexport class DrawerService {\n private readonly appRef = inject(ApplicationRef);\n\n private dialogRef: TkDialogRef<DrawerComponent<unknown>> | null = null;\n\n get drawerRefForTesting(): ComponentRef<DrawerComponent<unknown>> | null {\n return (\n (this.dialogRef?.componentRef as ComponentRef<\n DrawerComponent<unknown>\n >) || null\n );\n }\n set drawerRefForTesting(ref: ComponentRef<DrawerComponent<unknown>> | null) {\n this.dialogRef = ref ? new TkDialogRef(ref) : null;\n }\n\n open<T = unknown, R = unknown>(\n config: DrawerConfig\n ): TkDialogRef<DrawerComponent<T>, R> {\n if (this.dialogRef) {\n // Clear the previous one without triggering a real \"null\" result\n this.dialogRef.emitClose();\n this.dialogRef.componentRef.destroy();\n this.dialogRef = null;\n }\n\n const componentRef = createComponent(DrawerComponent, {\n environmentInjector: this.appRef.injector,\n }) as ComponentRef<DrawerComponent<T>>;\n\n this.appRef.attachView(componentRef.hostView);\n\n const domElem = (componentRef.hostView as EmbeddedViewRef<unknown>)\n .rootNodes[0] as HTMLElement;\n document.body.appendChild(domElem);\n\n componentRef.setInput('title', config.title);\n componentRef.setInput('content', config.content ?? null);\n componentRef.setInput('headerAction', config.headerAction ?? null);\n componentRef.setInput('size', config.size ?? 'small');\n componentRef.setInput('closable', config.closable ?? true);\n componentRef.setInput('dismissible', config.dismissible ?? true);\n componentRef.setInput('data', config.data ?? {});\n componentRef.setInput('interceptor', config.interceptor ?? undefined);\n\n const dialogRef = new TkDialogRef<DrawerComponent<T>, R>(componentRef);\n componentRef.setInput('dialogRef', dialogRef);\n this.dialogRef = dialogRef as unknown as TkDialogRef<\n DrawerComponent<unknown>\n >;\n\n componentRef.instance.closed.subscribe((value: unknown) => {\n dialogRef.emitClose(value as R);\n\n this.appRef.detachView(componentRef.hostView);\n componentRef.destroy();\n if (this.dialogRef === (dialogRef as unknown)) {\n this.dialogRef = null;\n }\n });\n\n componentRef.instance.open();\n\n return dialogRef;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|