@tekus/design-system 5.35.0 → 5.37.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/fesm2022/tekus-design-system-components-carousel.mjs +32 -7
- package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-color-picker.mjs +203 -29
- package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-grid-container.mjs +181 -0
- package/fesm2022/tekus-design-system-components-grid-container.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-header.mjs +29 -0
- package/fesm2022/tekus-design-system-components-header.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-modal.mjs +49 -29
- package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-process-steps.mjs +24 -3
- package/fesm2022/tekus-design-system-components-process-steps.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-section.mjs +63 -0
- package/fesm2022/tekus-design-system-components-section.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs +20 -6
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-tree-table.mjs +94 -0
- package/fesm2022/tekus-design-system-components-tree-table.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-uploader.mjs +1256 -0
- package/fesm2022/tekus-design-system-components-uploader.mjs.map +1 -0
- package/fesm2022/tekus-design-system-core-types.mjs +22 -7
- package/fesm2022/tekus-design-system-core-types.mjs.map +1 -1
- package/fesm2022/tekus-design-system-core.mjs +22 -7
- package/fesm2022/tekus-design-system-core.mjs.map +1 -1
- package/fesm2022/tekus-design-system-directives-gird-item.mjs +1 -1
- package/fesm2022/tekus-design-system-directives-gird-item.mjs.map +1 -1
- package/package.json +21 -1
- package/types/tekus-design-system-components-carousel.d.ts +6 -2
- package/types/tekus-design-system-components-color-picker.d.ts +75 -12
- package/types/tekus-design-system-components-grid-container.d.ts +123 -0
- package/types/tekus-design-system-components-header.d.ts +33 -0
- package/types/tekus-design-system-components-modal.d.ts +30 -12
- package/types/tekus-design-system-components-process-steps.d.ts +16 -1
- package/types/tekus-design-system-components-section.d.ts +45 -0
- package/types/tekus-design-system-components-sidebar-layout.d.ts +11 -1
- package/types/tekus-design-system-components-tree-table.d.ts +62 -0
- package/types/tekus-design-system-components-uploader.d.ts +524 -0
- package/types/tekus-design-system-core-types.d.ts +7 -7
- package/types/tekus-design-system-core.d.ts +7 -7
- package/types/tekus-design-system-directives-gird-item.d.ts +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { TagComponent } from '@tekus/design-system/components/tag';
|
|
5
|
+
import { IconComponent } from '@tekus/design-system/components/icon';
|
|
6
|
+
import { GridContainerComponent } from '@tekus/design-system/components/grid-container';
|
|
7
|
+
import { GridItemDirective } from '@tekus/design-system/directives/gird-item';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @component SectionComponent
|
|
11
|
+
* @description
|
|
12
|
+
* The Section component provides a structured, responsive layout block with an optional header and content area.
|
|
13
|
+
* It supports standard layouts, split layouts (two columns or two rows) with independent scrollable areas,
|
|
14
|
+
* and custom transclusion slots for headers, tags, and actions.
|
|
15
|
+
*
|
|
16
|
+
* @usage
|
|
17
|
+
* ```html
|
|
18
|
+
* <tk-section title="Licensing" tagText="Active" tagSeverity="success" icon="pi-cog">
|
|
19
|
+
* <div>Standard content area</div>
|
|
20
|
+
* </tk-section>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
class SectionComponent {
|
|
24
|
+
constructor() {
|
|
25
|
+
/** The primary title of the section. Optional. If omitted, the header is not rendered. */
|
|
26
|
+
this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
27
|
+
/** Optional fixed height for the section (e.g. '300px', '100%'). If content exceeds this height, it scrolls. */
|
|
28
|
+
this.height = input(undefined, ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
29
|
+
/** Optional tag text displayed next to the title. */
|
|
30
|
+
this.tagText = input(undefined, ...(ngDevMode ? [{ debugName: "tagText" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/** Optional tag severity for color styling. Defaults to 'info'. */
|
|
32
|
+
this.tagSeverity = input('info', ...(ngDevMode ? [{ debugName: "tagSeverity" }] : /* istanbul ignore next */ []));
|
|
33
|
+
/** Optional prefix icon class (e.g. 'pi-plus'). Shows a circular prefix icon in the header if set. */
|
|
34
|
+
this.icon = input(undefined, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
35
|
+
/** Additional info text for the right side of the main header */
|
|
36
|
+
this.infoText = input(undefined, ...(ngDevMode ? [{ debugName: "infoText" }] : /* istanbul ignore next */ []));
|
|
37
|
+
/** Icon for the right side of the main header */
|
|
38
|
+
this.infoIcon = input(undefined, ...(ngDevMode ? [{ debugName: "infoIcon" }] : /* istanbul ignore next */ []));
|
|
39
|
+
/** Severity color for the main header info text ('default', 'danger', etc.) */
|
|
40
|
+
this.infoSeverity = input('default', ...(ngDevMode ? [{ debugName: "infoSeverity" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** If true, the section body is split into two panels (left/right or top/bottom). */
|
|
42
|
+
this.split = input(false, ...(ngDevMode ? [{ debugName: "split" }] : /* istanbul ignore next */ []));
|
|
43
|
+
/** Layout direction for the split panels: 'row' (side-by-side) or 'column' (stacked). Defaults to 'row'. */
|
|
44
|
+
this.direction = input('row', ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
|
|
45
|
+
/** If true and split mode is enabled, each panel will scroll independently when content overflows. */
|
|
46
|
+
this.scrollable = input(true, ...(ngDevMode ? [{ debugName: "scrollable" }] : /* istanbul ignore next */ []));
|
|
47
|
+
}
|
|
48
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SectionComponent, isStandalone: true, selector: "tk-section", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, tagText: { classPropertyName: "tagText", publicName: "tagText", isSignal: true, isRequired: false, transformFunction: null }, tagSeverity: { classPropertyName: "tagSeverity", publicName: "tagSeverity", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, infoText: { classPropertyName: "infoText", publicName: "infoText", isSignal: true, isRequired: false, transformFunction: null }, infoIcon: { classPropertyName: "infoIcon", publicName: "infoIcon", isSignal: true, isRequired: false, transformFunction: null }, infoSeverity: { classPropertyName: "infoSeverity", publicName: "infoSeverity", isSignal: true, isRequired: false, transformFunction: null }, split: { classPropertyName: "split", publicName: "split", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.height": "height()" } }, ngImport: i0, template: "<div class=\"tk-section\">\n <!-- Header -->\n @if (title()) {\n <div class=\"tk-section__header\">\n <div class=\"tk-section__header-left\">\n <!-- Optional prefix icon -->\n @if (icon()) {\n <div class=\"tk-section__icon-wrapper\">\n <tk-icon [icon]=\"icon()!\" size=\"sm\"></tk-icon>\n </div>\n } @else {\n <!-- Or transcluded prefix icon -->\n <ng-content select=\"[headerIcon]\"></ng-content>\n }\n\n <!-- Title -->\n <h2 class=\"tk-section__title\">{{ title() }}</h2>\n \n <!-- Optional Tag -->\n @if (tagText()) {\n <tk-tag [value]=\"tagText()!\" [severity]=\"tagSeverity()\"></tk-tag>\n } @else {\n <ng-content select=\"[headerTag]\"></ng-content>\n }\n </div>\n\n <!-- Actions slot -->\n <div class=\"tk-section__header-right\">\n @if (infoText() || infoIcon()) {\n <div class=\"tk-section__header-info\" [class]=\"'tk-text-' + infoSeverity()\">\n @if (infoIcon()) { <tk-icon [icon]=\"infoIcon()!\"></tk-icon> }\n @if (infoText()) { <span>{{ infoText() }}</span> }\n </div>\n }\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </div>\n }\n\n <!-- Body Content -->\n <div class=\"tk-section__body\">\n @if (!split()) {\n <div class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\">\n <ng-content></ng-content>\n </div>\n } @else {\n <tk-grid-container [columns]=\"direction() === 'row' ? 2 : 1\" style=\"height: 100%; min-height: 0;\">\n <div tkGridItem class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\" style=\"height: 100%;\">\n <ng-content select=\"[left]\"></ng-content>\n </div>\n <div tkGridItem class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\" style=\"height: 100%;\">\n <ng-content select=\"[right]\"></ng-content>\n </div>\n </tk-grid-container>\n }\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%;min-height:0;box-sizing:border-box}.tk-section{display:flex;flex-direction:column;width:100%;height:100%;min-height:0;box-sizing:border-box;font-family:var(--tk-font-family, \"Outfit\", \"Inter\", -apple-system, sans-serif);background-color:var(--tk-color-base-surface-100);border-radius:var(--tk-borderRadius-s);padding:var(--tk-spacing-padding-s);gap:var(--tk-spacing-gap-s)}.tk-section__header{display:flex;justify-content:space-between;align-items:center;background-color:var(--tk-color-base-surface-0);border-radius:var(--tk-borderRadius-s);padding:var(--tk-spacing-padding-s) var(--tk-spacing-padding-m);min-height:3.5rem;box-sizing:border-box}.tk-section__header-left{display:flex;align-items:center;gap:var(--tk-spacing-base-75, .75rem)}.tk-section__header-left tk-tag ::ng-deep .p-tag{background-color:var(--tk-color-primary-muted)!important;color:var(--tk-color-primary-strong)!important;border-radius:var(--tk-borderRadius-full)!important;font-weight:var(--tk-font-weight-600);font-size:var(--tk-font-size-paragraph-s);padding:var(--tk-spacing-padding-xs) var(--tk-spacing-padding-m);border:none}.tk-section__icon-wrapper{display:flex;justify-content:center;align-items:center;width:2.25rem;height:2.25rem;background-color:var(--tk-color-base-surface-100);border-radius:50%;color:var(--tk-color-text-default)}.tk-section__icon-wrapper ::ng-deep tk-icon{display:flex;align-items:center;justify-content:center}.tk-section__title{font-size:var(--tk-font-size-paragraph-m);font-weight:var(--tk-font-weight-600);color:var(--tk-color-text-default);margin:0;line-height:1.25}.tk-section__header-right{display:flex;align-items:center;gap:var(--tk-spacing-gap-m)}.tk-section__header-right ::ng-deep button,.tk-section__header-right ::ng-deep a{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:var(--tk-spacing-padding-xs);color:var(--tk-color-text-default);transition:color .15s ease}.tk-section__header-right ::ng-deep button:hover,.tk-section__header-right ::ng-deep a:hover{color:var(--tk-color-primary-default)}.tk-section__header-info{display:flex;align-items:center;gap:var(--tk-spacing-gap-s);font-size:var(--tk-font-size-paragraph-s);color:var(--tk-color-text-muted)}.tk-section__header-info ::ng-deep tk-icon{color:inherit}.tk-section__header-info.tk-text-default{color:var(--tk-color-text-muted)}.tk-section__header-info.tk-text-danger{color:var(--tk-color-feedback-danger-default)}.tk-section__header-info.tk-text-success{color:var(--tk-color-feedback-success-default)}.tk-section__header-info.tk-text-warning{color:var(--tk-color-feedback-warn-default)}.tk-section__header-info.tk-text-info{color:var(--tk-color-feedback-info-default)}.tk-section__body{flex:1;display:flex;flex-direction:column;min-height:0;box-sizing:border-box}.tk-section__content{flex:1;min-height:0;background-color:var(--tk-color-base-surface-0);border-radius:var(--tk-borderRadius-s);padding:var(--tk-spacing-padding-m);box-sizing:border-box}.tk-section__content--scrollable{overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--tk-color-base-surface-300) transparent}.tk-section__content--scrollable::-webkit-scrollbar{width:.375rem;height:.375rem}.tk-section__content--scrollable::-webkit-scrollbar-track{background:transparent}.tk-section__content--scrollable::-webkit-scrollbar-thumb{background-color:var(--tk-color-base-surface-300);border-radius:var(--tk-borderRadius-xs)}.tk-section__content--scrollable::-webkit-scrollbar-thumb:hover{background-color:var(--tk-color-base-surface-400)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: GridContainerComponent, selector: "tk-grid-container", inputs: ["columns", "gutter", "size", "containerType"], outputs: ["columnsChange", "gutterChange", "sizeChange", "containerTypeChange"] }, { kind: "directive", type: GridItemDirective, selector: "[tkGridItem]", inputs: ["span"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
50
|
+
}
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SectionComponent, decorators: [{
|
|
52
|
+
type: Component,
|
|
53
|
+
args: [{ selector: 'tk-section', imports: [CommonModule, TagComponent, IconComponent, GridContainerComponent, GridItemDirective], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
54
|
+
'[style.height]': 'height()',
|
|
55
|
+
}, template: "<div class=\"tk-section\">\n <!-- Header -->\n @if (title()) {\n <div class=\"tk-section__header\">\n <div class=\"tk-section__header-left\">\n <!-- Optional prefix icon -->\n @if (icon()) {\n <div class=\"tk-section__icon-wrapper\">\n <tk-icon [icon]=\"icon()!\" size=\"sm\"></tk-icon>\n </div>\n } @else {\n <!-- Or transcluded prefix icon -->\n <ng-content select=\"[headerIcon]\"></ng-content>\n }\n\n <!-- Title -->\n <h2 class=\"tk-section__title\">{{ title() }}</h2>\n \n <!-- Optional Tag -->\n @if (tagText()) {\n <tk-tag [value]=\"tagText()!\" [severity]=\"tagSeverity()\"></tk-tag>\n } @else {\n <ng-content select=\"[headerTag]\"></ng-content>\n }\n </div>\n\n <!-- Actions slot -->\n <div class=\"tk-section__header-right\">\n @if (infoText() || infoIcon()) {\n <div class=\"tk-section__header-info\" [class]=\"'tk-text-' + infoSeverity()\">\n @if (infoIcon()) { <tk-icon [icon]=\"infoIcon()!\"></tk-icon> }\n @if (infoText()) { <span>{{ infoText() }}</span> }\n </div>\n }\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </div>\n }\n\n <!-- Body Content -->\n <div class=\"tk-section__body\">\n @if (!split()) {\n <div class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\">\n <ng-content></ng-content>\n </div>\n } @else {\n <tk-grid-container [columns]=\"direction() === 'row' ? 2 : 1\" style=\"height: 100%; min-height: 0;\">\n <div tkGridItem class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\" style=\"height: 100%;\">\n <ng-content select=\"[left]\"></ng-content>\n </div>\n <div tkGridItem class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\" style=\"height: 100%;\">\n <ng-content select=\"[right]\"></ng-content>\n </div>\n </tk-grid-container>\n }\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%;min-height:0;box-sizing:border-box}.tk-section{display:flex;flex-direction:column;width:100%;height:100%;min-height:0;box-sizing:border-box;font-family:var(--tk-font-family, \"Outfit\", \"Inter\", -apple-system, sans-serif);background-color:var(--tk-color-base-surface-100);border-radius:var(--tk-borderRadius-s);padding:var(--tk-spacing-padding-s);gap:var(--tk-spacing-gap-s)}.tk-section__header{display:flex;justify-content:space-between;align-items:center;background-color:var(--tk-color-base-surface-0);border-radius:var(--tk-borderRadius-s);padding:var(--tk-spacing-padding-s) var(--tk-spacing-padding-m);min-height:3.5rem;box-sizing:border-box}.tk-section__header-left{display:flex;align-items:center;gap:var(--tk-spacing-base-75, .75rem)}.tk-section__header-left tk-tag ::ng-deep .p-tag{background-color:var(--tk-color-primary-muted)!important;color:var(--tk-color-primary-strong)!important;border-radius:var(--tk-borderRadius-full)!important;font-weight:var(--tk-font-weight-600);font-size:var(--tk-font-size-paragraph-s);padding:var(--tk-spacing-padding-xs) var(--tk-spacing-padding-m);border:none}.tk-section__icon-wrapper{display:flex;justify-content:center;align-items:center;width:2.25rem;height:2.25rem;background-color:var(--tk-color-base-surface-100);border-radius:50%;color:var(--tk-color-text-default)}.tk-section__icon-wrapper ::ng-deep tk-icon{display:flex;align-items:center;justify-content:center}.tk-section__title{font-size:var(--tk-font-size-paragraph-m);font-weight:var(--tk-font-weight-600);color:var(--tk-color-text-default);margin:0;line-height:1.25}.tk-section__header-right{display:flex;align-items:center;gap:var(--tk-spacing-gap-m)}.tk-section__header-right ::ng-deep button,.tk-section__header-right ::ng-deep a{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:var(--tk-spacing-padding-xs);color:var(--tk-color-text-default);transition:color .15s ease}.tk-section__header-right ::ng-deep button:hover,.tk-section__header-right ::ng-deep a:hover{color:var(--tk-color-primary-default)}.tk-section__header-info{display:flex;align-items:center;gap:var(--tk-spacing-gap-s);font-size:var(--tk-font-size-paragraph-s);color:var(--tk-color-text-muted)}.tk-section__header-info ::ng-deep tk-icon{color:inherit}.tk-section__header-info.tk-text-default{color:var(--tk-color-text-muted)}.tk-section__header-info.tk-text-danger{color:var(--tk-color-feedback-danger-default)}.tk-section__header-info.tk-text-success{color:var(--tk-color-feedback-success-default)}.tk-section__header-info.tk-text-warning{color:var(--tk-color-feedback-warn-default)}.tk-section__header-info.tk-text-info{color:var(--tk-color-feedback-info-default)}.tk-section__body{flex:1;display:flex;flex-direction:column;min-height:0;box-sizing:border-box}.tk-section__content{flex:1;min-height:0;background-color:var(--tk-color-base-surface-0);border-radius:var(--tk-borderRadius-s);padding:var(--tk-spacing-padding-m);box-sizing:border-box}.tk-section__content--scrollable{overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--tk-color-base-surface-300) transparent}.tk-section__content--scrollable::-webkit-scrollbar{width:.375rem;height:.375rem}.tk-section__content--scrollable::-webkit-scrollbar-track{background:transparent}.tk-section__content--scrollable::-webkit-scrollbar-thumb{background-color:var(--tk-color-base-surface-300);border-radius:var(--tk-borderRadius-xs)}.tk-section__content--scrollable::-webkit-scrollbar-thumb:hover{background-color:var(--tk-color-base-surface-400)}\n"] }]
|
|
56
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], tagText: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagText", required: false }] }], tagSeverity: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagSeverity", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], infoText: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoText", required: false }] }], infoIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoIcon", required: false }] }], infoSeverity: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoSeverity", required: false }] }], split: [{ type: i0.Input, args: [{ isSignal: true, alias: "split", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], scrollable: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollable", required: false }] }] } });
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generated bundle index. Do not edit.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
export { SectionComponent };
|
|
63
|
+
//# sourceMappingURL=tekus-design-system-components-section.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-section.mjs","sources":["../../../projects/design-system/components/section/src/section.component.ts","../../../projects/design-system/components/section/src/section.component.html","../../../projects/design-system/components/section/tekus-design-system-components-section.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TagComponent, TagSeverity } from '@tekus/design-system/components/tag';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { GridContainerComponent } from '@tekus/design-system/components/grid-container';\nimport { GridItemDirective } from '@tekus/design-system/directives/gird-item';\n\n/**\n * @component SectionComponent\n * @description\n * The Section component provides a structured, responsive layout block with an optional header and content area.\n * It supports standard layouts, split layouts (two columns or two rows) with independent scrollable areas,\n * and custom transclusion slots for headers, tags, and actions.\n *\n * @usage\n * ```html\n * <tk-section title=\"Licensing\" tagText=\"Active\" tagSeverity=\"success\" icon=\"pi-cog\">\n * <div>Standard content area</div>\n * </tk-section>\n * ```\n */\n@Component({\n selector: 'tk-section',\n imports: [CommonModule, TagComponent, IconComponent, GridContainerComponent, GridItemDirective],\n templateUrl: './section.component.html',\n styleUrl: './section.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[style.height]': 'height()',\n }\n})\nexport class SectionComponent {\n /** The primary title of the section. Optional. If omitted, the header is not rendered. */\n title = input<string | undefined>(undefined);\n\n /** Optional fixed height for the section (e.g. '300px', '100%'). If content exceeds this height, it scrolls. */\n height = input<string | undefined>(undefined);\n\n /** Optional tag text displayed next to the title. */\n tagText = input<string | undefined>(undefined);\n\n /** Optional tag severity for color styling. Defaults to 'info'. */\n tagSeverity = input<TagSeverity>('info');\n\n /** Optional prefix icon class (e.g. 'pi-plus'). Shows a circular prefix icon in the header if set. */\n icon = input<string | undefined>(undefined);\n\n /** Additional info text for the right side of the main header */\n infoText = input<string | undefined>(undefined);\n\n /** Icon for the right side of the main header */\n infoIcon = input<string | undefined>(undefined);\n\n /** Severity color for the main header info text ('default', 'danger', etc.) */\n infoSeverity = input<'default' | 'danger' | 'success' | 'warning' | 'info'>('default');\n\n /** If true, the section body is split into two panels (left/right or top/bottom). */\n split = input<boolean>(false);\n\n /** Layout direction for the split panels: 'row' (side-by-side) or 'column' (stacked). Defaults to 'row'. */\n direction = input<'row' | 'column'>('row');\n\n /** If true and split mode is enabled, each panel will scroll independently when content overflows. */\n scrollable = input<boolean>(true);\n}\n","<div class=\"tk-section\">\n <!-- Header -->\n @if (title()) {\n <div class=\"tk-section__header\">\n <div class=\"tk-section__header-left\">\n <!-- Optional prefix icon -->\n @if (icon()) {\n <div class=\"tk-section__icon-wrapper\">\n <tk-icon [icon]=\"icon()!\" size=\"sm\"></tk-icon>\n </div>\n } @else {\n <!-- Or transcluded prefix icon -->\n <ng-content select=\"[headerIcon]\"></ng-content>\n }\n\n <!-- Title -->\n <h2 class=\"tk-section__title\">{{ title() }}</h2>\n \n <!-- Optional Tag -->\n @if (tagText()) {\n <tk-tag [value]=\"tagText()!\" [severity]=\"tagSeverity()\"></tk-tag>\n } @else {\n <ng-content select=\"[headerTag]\"></ng-content>\n }\n </div>\n\n <!-- Actions slot -->\n <div class=\"tk-section__header-right\">\n @if (infoText() || infoIcon()) {\n <div class=\"tk-section__header-info\" [class]=\"'tk-text-' + infoSeverity()\">\n @if (infoIcon()) { <tk-icon [icon]=\"infoIcon()!\"></tk-icon> }\n @if (infoText()) { <span>{{ infoText() }}</span> }\n </div>\n }\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </div>\n }\n\n <!-- Body Content -->\n <div class=\"tk-section__body\">\n @if (!split()) {\n <div class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\">\n <ng-content></ng-content>\n </div>\n } @else {\n <tk-grid-container [columns]=\"direction() === 'row' ? 2 : 1\" style=\"height: 100%; min-height: 0;\">\n <div tkGridItem class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\" style=\"height: 100%;\">\n <ng-content select=\"[left]\"></ng-content>\n </div>\n <div tkGridItem class=\"tk-section__content\" [class.tk-section__content--scrollable]=\"scrollable()\" style=\"height: 100%;\">\n <ng-content select=\"[right]\"></ng-content>\n </div>\n </tk-grid-container>\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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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, inject, ChangeDetectorRef, input, output, HostListener, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { CommonModule } from '@angular/common';
|
|
4
3
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
|
5
4
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
6
5
|
import { ButtonComponent } from '@tekus/design-system/components/button';
|
|
6
|
+
import { HeaderComponent } from '@tekus/design-system/components/header';
|
|
7
7
|
|
|
8
8
|
class SidebarService {
|
|
9
9
|
constructor() {
|
|
@@ -58,6 +58,10 @@ class SidebarLayoutComponent {
|
|
|
58
58
|
* If provided, it overrides the service state.
|
|
59
59
|
*/
|
|
60
60
|
this.isCollapsed = input(undefined, ...(ngDevMode ? [{ debugName: "isCollapsed" }] : /* istanbul ignore next */ []));
|
|
61
|
+
/**
|
|
62
|
+
* Actions rendered in the right zone of the header via tk-header.
|
|
63
|
+
*/
|
|
64
|
+
this.headerActions = input([], ...(ngDevMode ? [{ debugName: "headerActions" }] : /* istanbul ignore next */ []));
|
|
61
65
|
/**
|
|
62
66
|
* Emitted when the collapsed state changes.
|
|
63
67
|
*/
|
|
@@ -108,6 +112,16 @@ class SidebarLayoutComponent {
|
|
|
108
112
|
get displayCollapsed() {
|
|
109
113
|
return this.isCollapsed() === undefined ? this.collapsed : this.isCollapsed();
|
|
110
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Returns the left actions for tk-header: includes the toggle button
|
|
117
|
+
* only when the sidebar is collapsed or in tablet/mobile mode.
|
|
118
|
+
*/
|
|
119
|
+
get headerLeftActions() {
|
|
120
|
+
if (this.displayCollapsed || this.isTablet) {
|
|
121
|
+
return [{ icon: 'bars', label: 'Toggle sidebar', action: () => this.toggleSidebar() }];
|
|
122
|
+
}
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
111
125
|
/**
|
|
112
126
|
* Toggles the sidebar state.
|
|
113
127
|
*/
|
|
@@ -158,15 +172,15 @@ class SidebarLayoutComponent {
|
|
|
158
172
|
this.closeSidebar();
|
|
159
173
|
}
|
|
160
174
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SidebarLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
161
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SidebarLayoutComponent, isStandalone: true, selector: "tk-sidebar-layout", inputs: { isCollapsed: { classPropertyName: "isCollapsed", publicName: "isCollapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsedChange: "collapsedChange" }, host: { listeners: { "click": "handleSidebarContentClick($event)" } }, ngImport: i0, template: "<div\n class=\"tk-sidebar-layout\"\n [class.collapsed]=\"displayCollapsed\"\n [class.is-tablet]=\"isTablet\"\n [class.is-mobile]=\"isMobile\"\n>\n <!-- Backdrop for overlay mode -->\n @if (!displayCollapsed && isTablet) {\n <tk-button\n class=\"tk-sidebar-backdrop\"\n (clicked)=\"handleBackdropClick()\"\n aria-label=\"Close sidebar\"\n ></tk-button>\n }\n\n <!-- Sidebar -->\n <aside class=\"tk-sidebar\">\n @if (!displayCollapsed) {\n <div class=\"tk-sidebar-header\">\n <img\n src=\"assets/img/tk-logo-normal-light.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-expanded\"\n />\n <tk-button\n class=\"tk-sidebar-toggle is-sidebar\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"arrow-left\"\n ></tk-button>\n </div>\n }\n\n <ng-content select=\"[sidebar-content]\"></ng-content>\n </aside>\n\n <!-- Main Content -->\n <div class=\"tk-main-container\">\n <
|
|
175
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SidebarLayoutComponent, isStandalone: true, selector: "tk-sidebar-layout", inputs: { isCollapsed: { classPropertyName: "isCollapsed", publicName: "isCollapsed", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsedChange: "collapsedChange" }, host: { listeners: { "click": "handleSidebarContentClick($event)" } }, ngImport: i0, template: "<div\n class=\"tk-sidebar-layout\"\n [class.collapsed]=\"displayCollapsed\"\n [class.is-tablet]=\"isTablet\"\n [class.is-mobile]=\"isMobile\"\n>\n <!-- Backdrop for overlay mode -->\n @if (!displayCollapsed && isTablet) {\n <tk-button\n class=\"tk-sidebar-backdrop\"\n (clicked)=\"handleBackdropClick()\"\n aria-label=\"Close sidebar\"\n ></tk-button>\n }\n\n <!-- Sidebar -->\n <aside class=\"tk-sidebar\">\n @if (!displayCollapsed) {\n <div class=\"tk-sidebar-header\">\n <img\n src=\"assets/img/tk-logo-normal-light.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-expanded\"\n />\n <tk-button\n class=\"tk-sidebar-toggle is-sidebar\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"arrow-left\"\n ></tk-button>\n </div>\n }\n\n <ng-content select=\"[sidebar-content]\"></ng-content>\n </aside>\n\n <!-- Main Content -->\n <div class=\"tk-main-container\">\n <tk-header\n [logoSrc]=\"(displayCollapsed || isTablet) ? 'assets/img/tk-logo-normal-dark.svg' : undefined\"\n logoAlt=\"Tekus Logo\"\n [leftActions]=\"headerLeftActions\"\n [rightActions]=\"headerActions()\">\n </tk-header>\n\n <main class=\"tk-content\">\n <ng-content></ng-content>\n </main>\n </div>\n</div>\n", styles: [":host{display:block;height:100vh;width:100%}.tk-sidebar-layout{display:flex;height:100%;width:100%;overflow:hidden;position:relative}.tk-sidebar-layout .tk-sidebar-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:999;cursor:pointer;animation:fadeIn .3s ease-in-out;display:block}.tk-sidebar-layout .tk-sidebar-backdrop::ng-deep .p-button{width:100%!important;height:100%!important;background-color:#00000080!important;border:none!important;padding:0!important;border-radius:0!important;box-shadow:none!important}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.tk-sidebar-layout .tk-sidebar{background-color:var(--tk-color-background-inverse, #191a1b);color:var(--tk-color-text-inverse, #ffffff);width:var(--tk-sidebar-width, 17.5rem);height:100%;display:flex;flex-direction:column;transition:width .3s ease-in-out,transform .3s ease-in-out;flex-shrink:0;overflow-y:auto;overflow-x:hidden}.tk-sidebar-layout .tk-sidebar::-webkit-scrollbar{width:.25rem}.tk-sidebar-layout .tk-sidebar::-webkit-scrollbar-thumb{background:var(--tk-color-base-surface-700, #424243);border-radius:.125rem}.tk-sidebar-layout .tk-sidebar .tk-sidebar-header{padding:0 var(--tk-spacing-padding-m, 1rem);display:flex;align-items:center;justify-content:space-between;height:3.5rem;flex-shrink:0}.tk-sidebar-layout .tk-sidebar .tk-sidebar-header .tk-logo-expanded{height:1.5rem;width:auto}.tk-sidebar-layout .tk-sidebar .tk-sidebar-header .tk-logo-collapsed{height:2.5rem;width:auto}.tk-sidebar-layout .tk-sidebar .tk-sidebar-menu{flex:1;padding:var(--tk-spacing-padding-m, 1rem)}.tk-sidebar-layout .tk-main-container{flex:1;display:flex;flex-direction:column;min-width:0;background-color:var(--tk-color-background-default, #ffffff)}.tk-sidebar-layout .tk-main-container tk-header{border-bottom:1px solid var(--tk-color-border-subtle, #e4e4e4);flex-shrink:0}.tk-sidebar-layout .tk-sidebar-toggle{appearance:none;background:none;border:none;box-shadow:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;color:var(--tk-color-text-default, #191a1b);border-radius:var(--tk-borderRadius-s, .5rem);transition:all .2s;min-width:unset}.tk-sidebar-layout .tk-sidebar-toggle::ng-deep .p-button{background:none!important;border:none!important;padding:var(--tk-spacing-padding-xs, .25rem)!important;min-width:unset!important;height:auto!important;color:inherit!important;box-shadow:none!important}.tk-sidebar-layout .tk-sidebar-toggle::ng-deep .p-button:hover{background-color:var(--tk-color-background-soft, #f2f1f1)!important}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar{color:#fff!important}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button{color:#fff!important;background:transparent!important;padding:0!important}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button:hover{background-color:transparent!important;opacity:.7}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button ::ng-deep svg,.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button ::ng-deep path{fill:currentColor!important;stroke:currentColor!important}.tk-sidebar-layout .tk-content{flex:1;overflow-y:auto;padding:var(--tk-spacing-padding-l, 1.25rem)}.tk-sidebar-layout.collapsed:not(.is-tablet) .tk-sidebar{width:0;border-right:none}.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-label,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .p-panelmenu-header-label,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-chevron,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .p-icon{display:none!important}.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-link,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .p-panelmenu-header{justify-content:center;padding-left:0!important;padding-right:0!important}.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-content{justify-content:center}.tk-sidebar-layout.is-tablet .tk-sidebar{position:fixed;left:0;top:0;bottom:0;z-index:1000;width:var(--tk-sidebar-width, 17.5rem)!important;transform:translate(0);box-shadow:4px 0 10px #0000001a}.tk-sidebar-layout.is-tablet.collapsed .tk-sidebar{transform:translate(-100%)}.tk-sidebar-layout.is-tablet .tk-main-container{width:100%;flex:1}.tk-sidebar-layout.is-mobile .tk-sidebar{width:100%!important;max-width:none!important}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: HeaderComponent, selector: "tk-header", inputs: ["logoSrc", "logoAlt", "leftActions", "rightActions"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
162
176
|
}
|
|
163
177
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SidebarLayoutComponent, decorators: [{
|
|
164
178
|
type: Component,
|
|
165
179
|
args: [{ selector: 'tk-sidebar-layout', imports: [
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"tk-sidebar-layout\"\n [class.collapsed]=\"displayCollapsed\"\n [class.is-tablet]=\"isTablet\"\n [class.is-mobile]=\"isMobile\"\n>\n <!-- Backdrop for overlay mode -->\n @if (!displayCollapsed && isTablet) {\n <tk-button\n class=\"tk-sidebar-backdrop\"\n (clicked)=\"handleBackdropClick()\"\n aria-label=\"Close sidebar\"\n ></tk-button>\n }\n\n <!-- Sidebar -->\n <aside class=\"tk-sidebar\">\n @if (!displayCollapsed) {\n <div class=\"tk-sidebar-header\">\n <img\n src=\"assets/img/tk-logo-normal-light.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-expanded\"\n />\n <tk-button\n class=\"tk-sidebar-toggle is-sidebar\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"arrow-left\"\n ></tk-button>\n </div>\n }\n\n <ng-content select=\"[sidebar-content]\"></ng-content>\n </aside>\n\n <!-- Main Content -->\n <div class=\"tk-main-container\">\n <
|
|
169
|
-
}], propDecorators: { isCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "isCollapsed", required: false }] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], handleSidebarContentClick: [{
|
|
180
|
+
ButtonComponent,
|
|
181
|
+
HeaderComponent,
|
|
182
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"tk-sidebar-layout\"\n [class.collapsed]=\"displayCollapsed\"\n [class.is-tablet]=\"isTablet\"\n [class.is-mobile]=\"isMobile\"\n>\n <!-- Backdrop for overlay mode -->\n @if (!displayCollapsed && isTablet) {\n <tk-button\n class=\"tk-sidebar-backdrop\"\n (clicked)=\"handleBackdropClick()\"\n aria-label=\"Close sidebar\"\n ></tk-button>\n }\n\n <!-- Sidebar -->\n <aside class=\"tk-sidebar\">\n @if (!displayCollapsed) {\n <div class=\"tk-sidebar-header\">\n <img\n src=\"assets/img/tk-logo-normal-light.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-expanded\"\n />\n <tk-button\n class=\"tk-sidebar-toggle is-sidebar\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"arrow-left\"\n ></tk-button>\n </div>\n }\n\n <ng-content select=\"[sidebar-content]\"></ng-content>\n </aside>\n\n <!-- Main Content -->\n <div class=\"tk-main-container\">\n <tk-header\n [logoSrc]=\"(displayCollapsed || isTablet) ? 'assets/img/tk-logo-normal-dark.svg' : undefined\"\n logoAlt=\"Tekus Logo\"\n [leftActions]=\"headerLeftActions\"\n [rightActions]=\"headerActions()\">\n </tk-header>\n\n <main class=\"tk-content\">\n <ng-content></ng-content>\n </main>\n </div>\n</div>\n", styles: [":host{display:block;height:100vh;width:100%}.tk-sidebar-layout{display:flex;height:100%;width:100%;overflow:hidden;position:relative}.tk-sidebar-layout .tk-sidebar-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:999;cursor:pointer;animation:fadeIn .3s ease-in-out;display:block}.tk-sidebar-layout .tk-sidebar-backdrop::ng-deep .p-button{width:100%!important;height:100%!important;background-color:#00000080!important;border:none!important;padding:0!important;border-radius:0!important;box-shadow:none!important}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.tk-sidebar-layout .tk-sidebar{background-color:var(--tk-color-background-inverse, #191a1b);color:var(--tk-color-text-inverse, #ffffff);width:var(--tk-sidebar-width, 17.5rem);height:100%;display:flex;flex-direction:column;transition:width .3s ease-in-out,transform .3s ease-in-out;flex-shrink:0;overflow-y:auto;overflow-x:hidden}.tk-sidebar-layout .tk-sidebar::-webkit-scrollbar{width:.25rem}.tk-sidebar-layout .tk-sidebar::-webkit-scrollbar-thumb{background:var(--tk-color-base-surface-700, #424243);border-radius:.125rem}.tk-sidebar-layout .tk-sidebar .tk-sidebar-header{padding:0 var(--tk-spacing-padding-m, 1rem);display:flex;align-items:center;justify-content:space-between;height:3.5rem;flex-shrink:0}.tk-sidebar-layout .tk-sidebar .tk-sidebar-header .tk-logo-expanded{height:1.5rem;width:auto}.tk-sidebar-layout .tk-sidebar .tk-sidebar-header .tk-logo-collapsed{height:2.5rem;width:auto}.tk-sidebar-layout .tk-sidebar .tk-sidebar-menu{flex:1;padding:var(--tk-spacing-padding-m, 1rem)}.tk-sidebar-layout .tk-main-container{flex:1;display:flex;flex-direction:column;min-width:0;background-color:var(--tk-color-background-default, #ffffff)}.tk-sidebar-layout .tk-main-container tk-header{border-bottom:1px solid var(--tk-color-border-subtle, #e4e4e4);flex-shrink:0}.tk-sidebar-layout .tk-sidebar-toggle{appearance:none;background:none;border:none;box-shadow:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;color:var(--tk-color-text-default, #191a1b);border-radius:var(--tk-borderRadius-s, .5rem);transition:all .2s;min-width:unset}.tk-sidebar-layout .tk-sidebar-toggle::ng-deep .p-button{background:none!important;border:none!important;padding:var(--tk-spacing-padding-xs, .25rem)!important;min-width:unset!important;height:auto!important;color:inherit!important;box-shadow:none!important}.tk-sidebar-layout .tk-sidebar-toggle::ng-deep .p-button:hover{background-color:var(--tk-color-background-soft, #f2f1f1)!important}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar{color:#fff!important}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button{color:#fff!important;background:transparent!important;padding:0!important}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button:hover{background-color:transparent!important;opacity:.7}.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button ::ng-deep svg,.tk-sidebar-layout .tk-sidebar-toggle.is-sidebar::ng-deep .p-button ::ng-deep path{fill:currentColor!important;stroke:currentColor!important}.tk-sidebar-layout .tk-content{flex:1;overflow-y:auto;padding:var(--tk-spacing-padding-l, 1.25rem)}.tk-sidebar-layout.collapsed:not(.is-tablet) .tk-sidebar{width:0;border-right:none}.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-label,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .p-panelmenu-header-label,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-chevron,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .p-icon{display:none!important}.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-link,.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .p-panelmenu-header{justify-content:center;padding-left:0!important;padding-right:0!important}.tk-sidebar-layout.collapsed:not(.is-tablet) ::ng-deep .tk-sidebar .tk-panel-menu .tk-pm-item-content{justify-content:center}.tk-sidebar-layout.is-tablet .tk-sidebar{position:fixed;left:0;top:0;bottom:0;z-index:1000;width:var(--tk-sidebar-width, 17.5rem)!important;transform:translate(0);box-shadow:4px 0 10px #0000001a}.tk-sidebar-layout.is-tablet.collapsed .tk-sidebar{transform:translate(-100%)}.tk-sidebar-layout.is-tablet .tk-main-container{width:100%;flex:1}.tk-sidebar-layout.is-mobile .tk-sidebar{width:100%!important;max-width:none!important}\n"] }]
|
|
183
|
+
}], propDecorators: { isCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "isCollapsed", required: false }] }], headerActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerActions", required: false }] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], handleSidebarContentClick: [{
|
|
170
184
|
type: HostListener,
|
|
171
185
|
args: ['click', ['$event']]
|
|
172
186
|
}] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tekus-design-system-components-sidebar-layout.mjs","sources":["../../../projects/design-system/components/sidebar-layout/src/sidebar.service.ts","../../../projects/design-system/components/sidebar-layout/src/sidebar-layout.component.ts","../../../projects/design-system/components/sidebar-layout/src/sidebar-layout.component.html","../../../projects/design-system/components/sidebar-layout/tekus-design-system-components-sidebar-layout.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SidebarService {\n private readonly collapsedSubject = new BehaviorSubject<boolean>(false);\n \n /**\n * Observable to track the collapsed state of the sidebar.\n */\n isCollapsed$ = this.collapsedSubject.asObservable();\n\n /**\n * Toggles the collapsed state of the sidebar.\n */\n toggle(): void {\n this.collapsedSubject.next(!this.collapsedSubject.value);\n }\n\n /**\n * Explicitly sets the collapsed state of the sidebar.\n * @param value True to collapse, false to expand.\n */\n setCollapsed(value: boolean): void {\n this.collapsedSubject.next(value);\n }\n\n /**\n * Gets the current collapsed state.\n */\n get isCollapsed(): boolean {\n return this.collapsedSubject.value;\n }\n}\n","import { ChangeDetectionStrategy, Component, inject, input, output, OnInit, OnDestroy, ChangeDetectorRef, HostListener } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport { BreakpointObserver } from '@angular/cdk/layout';\nimport { SidebarService } from './sidebar.service';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\n\n@Component({\n selector: 'tk-sidebar-layout',\n imports: [\n CommonModule,\n ButtonComponent\n ],\n templateUrl: './sidebar-layout.component.html',\n styleUrl: './sidebar-layout.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SidebarLayoutComponent implements OnInit, OnDestroy {\n private readonly sidebarService = inject(SidebarService);\n private readonly breakpointObserver = inject(BreakpointObserver);\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly subscription = new Subscription();\n\n /**\n * Breakpoint constants\n */\n private readonly TABLET_BREAKPOINT = '(max-width: 1023px)';\n private readonly MOBILE_BREAKPOINT = '(max-width: 479px)';\n\n /**\n * Optional manual control of the collapsed state.\n * If provided, it overrides the service state.\n */\n isCollapsed = input<boolean | undefined>(undefined);\n\n\n /**\n * Emitted when the collapsed state changes.\n */\n collapsedChange = output<boolean>();\n\n /**\n * Internal state of the sidebar.\n */\n collapsed = false;\n\n /**\n * Responsive states\n */\n isTablet = false;\n isMobile = false;\n\n ngOnInit(): void {\n // Sync with service\n this.subscription.add(\n this.sidebarService.isCollapsed$.subscribe((state) => {\n if (this.isCollapsed() === undefined) {\n this.collapsed = state;\n this.collapsedChange.emit(state);\n this.cdr.markForCheck();\n }\n })\n );\n\n // Responsive breakpoints\n this.subscription.add(\n this.breakpointObserver\n .observe([this.TABLET_BREAKPOINT, this.MOBILE_BREAKPOINT])\n .subscribe((result) => {\n const wasTablet = this.isTablet;\n this.isTablet = result.breakpoints[this.TABLET_BREAKPOINT];\n this.isMobile = result.breakpoints[this.MOBILE_BREAKPOINT];\n\n // Auto-collapse when entering tablet/mobile mode (< 1024px)\n if (this.isTablet && !wasTablet) {\n this.sidebarService.setCollapsed(true);\n }\n\n // Auto-expand when returning to desktop mode (> 1024px)\n if (!this.isTablet && wasTablet) {\n this.sidebarService.setCollapsed(false);\n }\n\n this.cdr.markForCheck();\n })\n );\n }\n\n ngOnDestroy(): void {\n this.subscription.unsubscribe();\n }\n\n /**\n * Determines if the sidebar is currently collapsed.\n */\n get displayCollapsed(): boolean {\n return this.isCollapsed() === undefined ? this.collapsed : this.isCollapsed()!;\n }\n\n /**\n * Toggles the sidebar state.\n */\n toggleSidebar(): void {\n if (this.isCollapsed() === undefined) {\n this.sidebarService.toggle();\n } else {\n this.collapsedChange.emit(!this.isCollapsed());\n }\n }\n\n /**\n * Closes the sidebar explicitly.\n */\n closeSidebar(): void {\n if (this.isCollapsed() === undefined) {\n this.sidebarService.setCollapsed(true);\n } else {\n this.collapsedChange.emit(true);\n }\n }\n\n /**\n * Handles clicks in the sidebar content to auto-close on mobile.\n * Using HostListener to avoid template accessibility linting on non-interactive aside.\n */\n @HostListener('click', ['$event'])\n handleSidebarContentClick(event: MouseEvent): void {\n if (!this.isMobile) return;\n\n // Check if the click is inside the sidebar\n const sidebar = (event.target as HTMLElement).closest('.tk-sidebar');\n if (!sidebar) return;\n\n const target = event.target as HTMLElement;\n const navItem = target.closest('.tk-menu-item-link, .tk-pm-item-link, a, button');\n\n if (navItem) {\n // Check if it's a toggle for a sub-menu (has children)\n const hasChildren = navItem.querySelector('.tk-menu-item-chevron, .tk-pm-item-chevron');\n if (!hasChildren) {\n this.closeSidebar();\n }\n }\n }\n\n /**\n * Handles backdrop clicks to close the drawer.\n */\n handleBackdropClick(): void {\n this.closeSidebar();\n }\n}\n","<div\n class=\"tk-sidebar-layout\"\n [class.collapsed]=\"displayCollapsed\"\n [class.is-tablet]=\"isTablet\"\n [class.is-mobile]=\"isMobile\"\n>\n <!-- Backdrop for overlay mode -->\n @if (!displayCollapsed && isTablet) {\n <tk-button\n class=\"tk-sidebar-backdrop\"\n (clicked)=\"handleBackdropClick()\"\n aria-label=\"Close sidebar\"\n ></tk-button>\n }\n\n <!-- Sidebar -->\n <aside class=\"tk-sidebar\">\n @if (!displayCollapsed) {\n <div class=\"tk-sidebar-header\">\n <img\n src=\"assets/img/tk-logo-normal-light.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-expanded\"\n />\n <tk-button\n class=\"tk-sidebar-toggle is-sidebar\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"arrow-left\"\n ></tk-button>\n </div>\n }\n\n <ng-content select=\"[sidebar-content]\"></ng-content>\n </aside>\n\n <!-- Main Content -->\n <div class=\"tk-main-container\">\n <header class=\"tk-nav-header\">\n <div class=\"tk-nav-left\">\n @if (displayCollapsed || isTablet) {\n <tk-button\n class=\"tk-sidebar-toggle\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"bars\"\n ></tk-button>\n <img\n src=\"assets/img/tk-logo-normal-dark.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-header\"\n />\n }\n </div>\n\n <div class=\"tk-nav-right\">\n <div class=\"tk-header-actions\">\n <ng-content select=\"[header-actions]\"></ng-content>\n </div>\n </div>\n </header>\n\n <main class=\"tk-content\">\n <ng-content></ng-content>\n </main>\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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"}
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-sidebar-layout.mjs","sources":["../../../projects/design-system/components/sidebar-layout/src/sidebar.service.ts","../../../projects/design-system/components/sidebar-layout/src/sidebar-layout.component.ts","../../../projects/design-system/components/sidebar-layout/src/sidebar-layout.component.html","../../../projects/design-system/components/sidebar-layout/tekus-design-system-components-sidebar-layout.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SidebarService {\n private readonly collapsedSubject = new BehaviorSubject<boolean>(false);\n \n /**\n * Observable to track the collapsed state of the sidebar.\n */\n isCollapsed$ = this.collapsedSubject.asObservable();\n\n /**\n * Toggles the collapsed state of the sidebar.\n */\n toggle(): void {\n this.collapsedSubject.next(!this.collapsedSubject.value);\n }\n\n /**\n * Explicitly sets the collapsed state of the sidebar.\n * @param value True to collapse, false to expand.\n */\n setCollapsed(value: boolean): void {\n this.collapsedSubject.next(value);\n }\n\n /**\n * Gets the current collapsed state.\n */\n get isCollapsed(): boolean {\n return this.collapsedSubject.value;\n }\n}\n","import { ChangeDetectionStrategy, Component, inject, input, output, OnInit, OnDestroy, ChangeDetectorRef, HostListener } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { BreakpointObserver } from '@angular/cdk/layout';\nimport { SidebarService } from './sidebar.service';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { HeaderComponent, TkHeaderAction } from '@tekus/design-system/components/header';\n\n@Component({\n selector: 'tk-sidebar-layout',\n imports: [\n ButtonComponent,\n HeaderComponent,\n ],\n templateUrl: './sidebar-layout.component.html',\n styleUrl: './sidebar-layout.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SidebarLayoutComponent implements OnInit, OnDestroy {\n private readonly sidebarService = inject(SidebarService);\n private readonly breakpointObserver = inject(BreakpointObserver);\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly subscription = new Subscription();\n\n /**\n * Breakpoint constants\n */\n private readonly TABLET_BREAKPOINT = '(max-width: 1023px)';\n private readonly MOBILE_BREAKPOINT = '(max-width: 479px)';\n\n /**\n * Optional manual control of the collapsed state.\n * If provided, it overrides the service state.\n */\n isCollapsed = input<boolean | undefined>(undefined);\n\n /**\n * Actions rendered in the right zone of the header via tk-header.\n */\n headerActions = input<TkHeaderAction[]>([]);\n\n /**\n * Emitted when the collapsed state changes.\n */\n collapsedChange = output<boolean>();\n\n /**\n * Internal state of the sidebar.\n */\n collapsed = false;\n\n /**\n * Responsive states\n */\n isTablet = false;\n isMobile = false;\n\n ngOnInit(): void {\n // Sync with service\n this.subscription.add(\n this.sidebarService.isCollapsed$.subscribe((state) => {\n if (this.isCollapsed() === undefined) {\n this.collapsed = state;\n this.collapsedChange.emit(state);\n this.cdr.markForCheck();\n }\n })\n );\n\n // Responsive breakpoints\n this.subscription.add(\n this.breakpointObserver\n .observe([this.TABLET_BREAKPOINT, this.MOBILE_BREAKPOINT])\n .subscribe((result) => {\n const wasTablet = this.isTablet;\n this.isTablet = result.breakpoints[this.TABLET_BREAKPOINT];\n this.isMobile = result.breakpoints[this.MOBILE_BREAKPOINT];\n\n // Auto-collapse when entering tablet/mobile mode (< 1024px)\n if (this.isTablet && !wasTablet) {\n this.sidebarService.setCollapsed(true);\n }\n\n // Auto-expand when returning to desktop mode (> 1024px)\n if (!this.isTablet && wasTablet) {\n this.sidebarService.setCollapsed(false);\n }\n\n this.cdr.markForCheck();\n })\n );\n }\n\n ngOnDestroy(): void {\n this.subscription.unsubscribe();\n }\n\n /**\n * Determines if the sidebar is currently collapsed.\n */\n get displayCollapsed(): boolean {\n return this.isCollapsed() === undefined ? this.collapsed : this.isCollapsed()!;\n }\n\n /**\n * Returns the left actions for tk-header: includes the toggle button\n * only when the sidebar is collapsed or in tablet/mobile mode.\n */\n get headerLeftActions(): TkHeaderAction[] {\n if (this.displayCollapsed || this.isTablet) {\n return [{ icon: 'bars', label: 'Toggle sidebar', action: () => this.toggleSidebar() }];\n }\n return [];\n }\n\n /**\n * Toggles the sidebar state.\n */\n toggleSidebar(): void {\n if (this.isCollapsed() === undefined) {\n this.sidebarService.toggle();\n } else {\n this.collapsedChange.emit(!this.isCollapsed());\n }\n }\n\n /**\n * Closes the sidebar explicitly.\n */\n closeSidebar(): void {\n if (this.isCollapsed() === undefined) {\n this.sidebarService.setCollapsed(true);\n } else {\n this.collapsedChange.emit(true);\n }\n }\n\n /**\n * Handles clicks in the sidebar content to auto-close on mobile.\n * Using HostListener to avoid template accessibility linting on non-interactive aside.\n */\n @HostListener('click', ['$event'])\n handleSidebarContentClick(event: MouseEvent): void {\n if (!this.isMobile) return;\n\n // Check if the click is inside the sidebar\n const sidebar = (event.target as HTMLElement).closest('.tk-sidebar');\n if (!sidebar) return;\n\n const target = event.target as HTMLElement;\n const navItem = target.closest('.tk-menu-item-link, .tk-pm-item-link, a, button');\n\n if (navItem) {\n // Check if it's a toggle for a sub-menu (has children)\n const hasChildren = navItem.querySelector('.tk-menu-item-chevron, .tk-pm-item-chevron');\n if (!hasChildren) {\n this.closeSidebar();\n }\n }\n }\n\n /**\n * Handles backdrop clicks to close the drawer.\n */\n handleBackdropClick(): void {\n this.closeSidebar();\n }\n}\n","<div\n class=\"tk-sidebar-layout\"\n [class.collapsed]=\"displayCollapsed\"\n [class.is-tablet]=\"isTablet\"\n [class.is-mobile]=\"isMobile\"\n>\n <!-- Backdrop for overlay mode -->\n @if (!displayCollapsed && isTablet) {\n <tk-button\n class=\"tk-sidebar-backdrop\"\n (clicked)=\"handleBackdropClick()\"\n aria-label=\"Close sidebar\"\n ></tk-button>\n }\n\n <!-- Sidebar -->\n <aside class=\"tk-sidebar\">\n @if (!displayCollapsed) {\n <div class=\"tk-sidebar-header\">\n <img\n src=\"assets/img/tk-logo-normal-light.svg\"\n alt=\"Tekus Logo\"\n class=\"tk-logo-expanded\"\n />\n <tk-button\n class=\"tk-sidebar-toggle is-sidebar\"\n (clicked)=\"toggleSidebar()\"\n severity=\"secondary\"\n variant=\"text\"\n icon=\"arrow-left\"\n ></tk-button>\n </div>\n }\n\n <ng-content select=\"[sidebar-content]\"></ng-content>\n </aside>\n\n <!-- Main Content -->\n <div class=\"tk-main-container\">\n <tk-header\n [logoSrc]=\"(displayCollapsed || isTablet) ? 'assets/img/tk-logo-normal-dark.svg' : undefined\"\n logoAlt=\"Tekus Logo\"\n [leftActions]=\"headerLeftActions\"\n [rightActions]=\"headerActions()\">\n </tk-header>\n\n <main class=\"tk-content\">\n <ng-content></ng-content>\n </main>\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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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, contentChild, signal, effect, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as i2 from 'primeng/treetable';
|
|
6
|
+
import { TreeTableModule } from 'primeng/treetable';
|
|
7
|
+
import { IconComponent } from '@tekus/design-system/components/icon';
|
|
8
|
+
import { ButtonComponent } from '@tekus/design-system/components/button';
|
|
9
|
+
import * as i3 from 'primeng/api';
|
|
10
|
+
|
|
11
|
+
class TreeTableComponent {
|
|
12
|
+
constructor() {
|
|
13
|
+
/**
|
|
14
|
+
* Hierarchical list of tree nodes to render.
|
|
15
|
+
*/
|
|
16
|
+
this.data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
17
|
+
/**
|
|
18
|
+
* Custom template slot to render the icon on the left of each node label.
|
|
19
|
+
* Usage: `<ng-template #iconTemplate let-node>...</ng-template>`
|
|
20
|
+
*/
|
|
21
|
+
this.iconTemplate = contentChild('iconTemplate', ...(ngDevMode ? [{ debugName: "iconTemplate" }] : /* istanbul ignore next */ []));
|
|
22
|
+
/**
|
|
23
|
+
* Custom template slot to render center information/indicators.
|
|
24
|
+
* Usage: `<ng-template #centerTemplate let-node>...</ng-template>`
|
|
25
|
+
*/
|
|
26
|
+
this.centerTemplate = contentChild('centerTemplate', ...(ngDevMode ? [{ debugName: "centerTemplate" }] : /* istanbul ignore next */ []));
|
|
27
|
+
/**
|
|
28
|
+
* Custom template slot to render additional actions/content on the right of the row.
|
|
29
|
+
* Usage: `<ng-template #rightTemplate let-node>...</ng-template>`
|
|
30
|
+
*/
|
|
31
|
+
this.rightTemplate = contentChild('rightTemplate', ...(ngDevMode ? [{ debugName: "rightTemplate" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/**
|
|
33
|
+
* Internal representation of the tree nodes mapped to PrimeNG's format.
|
|
34
|
+
*/
|
|
35
|
+
this.primeNodes = signal([], ...(ngDevMode ? [{ debugName: "primeNodes" }] : /* istanbul ignore next */ []));
|
|
36
|
+
effect(() => {
|
|
37
|
+
const mapped = this.mapToPrimeNodes(this.data());
|
|
38
|
+
this.primeNodes.set(mapped);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
mapToPrimeNodes(nodes) {
|
|
42
|
+
return nodes.map(node => ({
|
|
43
|
+
key: node.id?.toString(),
|
|
44
|
+
data: node,
|
|
45
|
+
expanded: node.expanded ?? false,
|
|
46
|
+
children: node.children?.length
|
|
47
|
+
? this.mapToPrimeNodes(node.children)
|
|
48
|
+
: undefined,
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* API Method: Recursively expands all nodes.
|
|
53
|
+
*/
|
|
54
|
+
expandAll() {
|
|
55
|
+
const updated = this.toggleAllNodes(this.primeNodes(), true);
|
|
56
|
+
this.primeNodes.set(updated);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* API Method: Recursively collapses all nodes.
|
|
60
|
+
*/
|
|
61
|
+
collapseAll() {
|
|
62
|
+
const updated = this.toggleAllNodes(this.primeNodes(), false);
|
|
63
|
+
this.primeNodes.set(updated);
|
|
64
|
+
}
|
|
65
|
+
toggleAllNodes(nodes, expanded) {
|
|
66
|
+
return nodes.map(node => ({
|
|
67
|
+
...node,
|
|
68
|
+
expanded,
|
|
69
|
+
children: node.children ? this.toggleAllNodes(node.children, expanded) : [],
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Toggles the expansion state of a specific node.
|
|
74
|
+
*/
|
|
75
|
+
toggleNode(rowNode) {
|
|
76
|
+
if (rowNode?.node) {
|
|
77
|
+
rowNode.node.expanded = !rowNode.node.expanded;
|
|
78
|
+
this.primeNodes.set([...this.primeNodes()]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TreeTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
82
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TreeTableComponent, isStandalone: true, selector: "tk-tree-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "iconTemplate", first: true, predicate: ["iconTemplate"], descendants: true, isSignal: true }, { propertyName: "centerTemplate", first: true, predicate: ["centerTemplate"], descendants: true, isSignal: true }, { propertyName: "rightTemplate", first: true, predicate: ["rightTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<p-treeTable [value]=\"primeNodes()\" class=\"tk-tree-table\">\n <ng-template pTemplate=\"body\" let-rowNode let-rowData=\"rowData\">\n <tr [ttRow]=\"rowNode\" \n class=\"tk-tree-table__row\"\n [class.tk-tree-table__row--level-0]=\"rowNode.level === 0\"\n [class.tk-tree-table__row--level-1]=\"rowNode.level === 1\"\n [class.tk-tree-table__row--level-2]=\"rowNode.level >= 2\">\n <td class=\"tk-tree-table__cell\">\n <div class=\"tk-tree-table__row-container\" \n [class.tk-tree-table__row-container--level-0]=\"rowNode.level === 0\"\n [class.tk-tree-table__row-container--level-1]=\"rowNode.level === 1\"\n [class.tk-tree-table__row-container--level-2]=\"rowNode.level >= 2\"\n [style.padding-left.px]=\"rowNode.level * 32\">\n \n <!-- LEFT SIDE: Chevron + Icon + Label -->\n <div class=\"tk-tree-table__left\">\n <!-- Toggler Chevron -->\n @if (rowNode.node.children && rowNode.node.children.length > 0) {\n <tk-button \n class=\"tk-tree-table__toggler\" \n [class.tk-tree-table__toggler--rotated]=\"rowNode.node.expanded\"\n icon=\"chevron-right\"\n variant=\"text\"\n severity=\"secondary\"\n [ariaLabel]=\"rowNode.node.expanded ? 'Colapsar nodo' : 'Expandir nodo'\"\n (clicked)=\"toggleNode(rowNode)\">\n </tk-button>\n } @else {\n <span class=\"tk-tree-table__toggler-placeholder\"></span>\n }\n\n <!-- Icon Slot -->\n <div class=\"tk-tree-table__icon-wrapper\">\n @if (iconTemplate()) {\n <ng-container *ngTemplateOutlet=\"iconTemplate(); context: { $implicit: rowData }\"></ng-container>\n } @else if (rowData.icon) {\n <tk-icon \n [icon]=\"rowData.icon\" \n [styleIcon]=\"rowData.iconStyle || 'regular'\" \n class=\"tk-tree-table__icon\">\n </tk-icon>\n }\n </div>\n\n <!-- Label -->\n <span class=\"tk-tree-table__label\">{{ rowData.label }}</span>\n </div>\n\n <!-- CENTER SIDE: Custom Information Column -->\n @if (centerTemplate()) {\n <div class=\"tk-tree-table__center\">\n <ng-container *ngTemplateOutlet=\"centerTemplate(); context: { $implicit: rowData }\"></ng-container>\n </div>\n }\n\n <!-- RIGHT SIDE: Custom Dynamic Content Slot -->\n @if (rightTemplate()) {\n <div class=\"tk-tree-table__right\">\n <ng-container *ngTemplateOutlet=\"rightTemplate(); context: { $implicit: rowData }\"></ng-container>\n </div>\n }\n \n </div>\n </td>\n </tr>\n </ng-template>\n</p-treeTable>\n", styles: [":host{display:block;width:100%}:host ::ng-deep .tk-tree-table .p-treetable{border:1px solid var(--tk-color-base-surface-200, #e4e4e4);border-radius:var(--tk-borderRadius-m, 8px);overflow:hidden;background-color:var(--tk-color-base-surface-0, #ffffff);box-shadow:0 1px 3px #0000000d}:host ::ng-deep .tk-tree-table .p-treetable-scrollable-header,:host ::ng-deep .tk-tree-table .p-treetable-thead{display:none}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr{background-color:var(--tk-color-base-surface-0, #ffffff);border-bottom:1px solid var(--tk-color-base-surface-100, #f2f1f1);transition:background-color .2s ease}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr:last-child{border-bottom:none}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr:hover{background-color:var(--tk-color-base-surface-50, #fbfafa)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr.tk-tree-table__row--level-0{background-color:var(--tk-color-base-surface-50, #fbfafa)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr.tk-tree-table__row--level-1:hover{background-color:var(--tk-color-base-primary-50, #e8e6f1)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr.tk-tree-table__row--level-2:hover{background-color:var(--tk-color-base-primary-50, #e8e6f1)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr>td{padding:0!important;border:none!important;background:transparent!important}.tk-tree-table__row-container{display:flex;align-items:center;justify-content:flex-start;padding:var(--tk-spacing-padding-s, 12px) var(--tk-spacing-padding-m, 16px);width:100%;box-sizing:border-box;min-height:56px;gap:var(--tk-spacing-base-100, 12px)}.tk-tree-table__row-container--level-0 .tk-tree-table__label{font-size:var(--tk-font-size-base-100, 1rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-base-surface-950, #191a1b)}.tk-tree-table__row-container--level-0 .tk-tree-table__icon-wrapper{color:var(--tk-color-base-primary-300, #948abd)}.tk-tree-table__row-container--level-1 .tk-tree-table__label{font-size:var(--tk-font-size-base-100, 1rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-base-surface-800, #303031)}.tk-tree-table__row-container--level-1 .tk-tree-table__icon-wrapper{color:var(--tk-color-base-primary-300, #948abd)}.tk-tree-table__row-container--level-2 .tk-tree-table__label{font-size:var(--tk-font-size-base-100, 1rem);font-weight:var(--tk-font-weight-400, 400);color:var(--tk-color-base-surface-700, #424243)}.tk-tree-table__row-container--level-2 .tk-tree-table__icon-wrapper{color:var(--tk-color-base-surface-300, #d2d2d2)}.tk-tree-table__left{display:flex;align-items:center;gap:var(--tk-spacing-base-100, 12px);flex-shrink:0}.tk-tree-table__center{display:flex;align-items:center;gap:var(--tk-spacing-base-100, 12px);margin-left:24px;flex-grow:1}.tk-tree-table__toggler{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px}.tk-tree-table__toggler ::ng-deep .tk-button.p-button{background:transparent!important;border:none!important;padding:0!important;width:24px!important;height:24px!important;color:var(--tk-color-base-surface-500, #8a8a8b)!important;border-radius:var(--tk-border-radius-xs, 4px)!important;min-width:auto!important;transition:background-color .2s ease,color .2s ease}.tk-tree-table__toggler ::ng-deep .tk-button.p-button:hover{background-color:var(--tk-color-base-surface-100, #f2f1f1)!important;color:var(--tk-color-base-surface-800, #303031)!important}.tk-tree-table__toggler ::ng-deep tk-icon{transition:transform .2s cubic-bezier(.4,0,.2,1);display:inline-block}.tk-tree-table__toggler--rotated ::ng-deep tk-icon{transform:rotate(90deg)}.tk-tree-table__toggler-placeholder{width:24px;height:24px;display:inline-block}.tk-tree-table__icon-wrapper{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;font-size:1.2rem}.tk-tree-table__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tk-tree-table__right{display:flex;align-items:center;gap:var(--tk-spacing-base-100, 12px);margin-left:auto}@media(max-width:640px){.tk-tree-table__row-container{flex-wrap:wrap;align-items:flex-start;gap:var(--tk-spacing-base-50, 8px);padding:var(--tk-spacing-padding-s, 12px)}.tk-tree-table__center{margin-left:0;padding-left:var(--tk-spacing-base-300, 36px);width:100%;flex-grow:0}.tk-tree-table__right{margin-left:0;padding-left:var(--tk-spacing-base-300, 36px);width:100%;margin-top:4px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TreeTableModule }, { kind: "component", type: i2.TreeTable, selector: "p-treeTable, p-treetable, p-tree-table", inputs: ["columns", "styleClass", "tableStyle", "tableStyleClass", "autoLayout", "lazy", "lazyLoadOnInit", "paginator", "rows", "first", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "customSort", "selectionMode", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "compareSelectionBy", "rowHover", "loading", "loadingIcon", "showLoader", "scrollable", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "frozenColumns", "resizableColumns", "columnResizeMode", "reorderableColumns", "contextMenu", "rowTrackBy", "filters", "globalFilterFields", "filterDelay", "filterMode", "filterLocale", "paginatorLocale", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "value", "virtualRowHeight", "selectionKeys", "showGridlines"], outputs: ["selectionChange", "contextMenuSelectionChange", "onFilter", "onNodeExpand", "onNodeCollapse", "onPage", "onSort", "onLazyLoad", "sortFunction", "onColResize", "onColReorder", "onNodeSelect", "onNodeUnselect", "onContextMenuSelect", "onHeaderCheckboxToggle", "onEditInit", "onEditComplete", "onEditCancel", "selectionKeysChange"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.TTRow, selector: "[ttRow]", inputs: ["ttRow"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
83
|
+
}
|
|
84
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TreeTableComponent, decorators: [{
|
|
85
|
+
type: Component,
|
|
86
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'tk-tree-table', imports: [CommonModule, TreeTableModule, IconComponent, ButtonComponent], template: "<p-treeTable [value]=\"primeNodes()\" class=\"tk-tree-table\">\n <ng-template pTemplate=\"body\" let-rowNode let-rowData=\"rowData\">\n <tr [ttRow]=\"rowNode\" \n class=\"tk-tree-table__row\"\n [class.tk-tree-table__row--level-0]=\"rowNode.level === 0\"\n [class.tk-tree-table__row--level-1]=\"rowNode.level === 1\"\n [class.tk-tree-table__row--level-2]=\"rowNode.level >= 2\">\n <td class=\"tk-tree-table__cell\">\n <div class=\"tk-tree-table__row-container\" \n [class.tk-tree-table__row-container--level-0]=\"rowNode.level === 0\"\n [class.tk-tree-table__row-container--level-1]=\"rowNode.level === 1\"\n [class.tk-tree-table__row-container--level-2]=\"rowNode.level >= 2\"\n [style.padding-left.px]=\"rowNode.level * 32\">\n \n <!-- LEFT SIDE: Chevron + Icon + Label -->\n <div class=\"tk-tree-table__left\">\n <!-- Toggler Chevron -->\n @if (rowNode.node.children && rowNode.node.children.length > 0) {\n <tk-button \n class=\"tk-tree-table__toggler\" \n [class.tk-tree-table__toggler--rotated]=\"rowNode.node.expanded\"\n icon=\"chevron-right\"\n variant=\"text\"\n severity=\"secondary\"\n [ariaLabel]=\"rowNode.node.expanded ? 'Colapsar nodo' : 'Expandir nodo'\"\n (clicked)=\"toggleNode(rowNode)\">\n </tk-button>\n } @else {\n <span class=\"tk-tree-table__toggler-placeholder\"></span>\n }\n\n <!-- Icon Slot -->\n <div class=\"tk-tree-table__icon-wrapper\">\n @if (iconTemplate()) {\n <ng-container *ngTemplateOutlet=\"iconTemplate(); context: { $implicit: rowData }\"></ng-container>\n } @else if (rowData.icon) {\n <tk-icon \n [icon]=\"rowData.icon\" \n [styleIcon]=\"rowData.iconStyle || 'regular'\" \n class=\"tk-tree-table__icon\">\n </tk-icon>\n }\n </div>\n\n <!-- Label -->\n <span class=\"tk-tree-table__label\">{{ rowData.label }}</span>\n </div>\n\n <!-- CENTER SIDE: Custom Information Column -->\n @if (centerTemplate()) {\n <div class=\"tk-tree-table__center\">\n <ng-container *ngTemplateOutlet=\"centerTemplate(); context: { $implicit: rowData }\"></ng-container>\n </div>\n }\n\n <!-- RIGHT SIDE: Custom Dynamic Content Slot -->\n @if (rightTemplate()) {\n <div class=\"tk-tree-table__right\">\n <ng-container *ngTemplateOutlet=\"rightTemplate(); context: { $implicit: rowData }\"></ng-container>\n </div>\n }\n \n </div>\n </td>\n </tr>\n </ng-template>\n</p-treeTable>\n", styles: [":host{display:block;width:100%}:host ::ng-deep .tk-tree-table .p-treetable{border:1px solid var(--tk-color-base-surface-200, #e4e4e4);border-radius:var(--tk-borderRadius-m, 8px);overflow:hidden;background-color:var(--tk-color-base-surface-0, #ffffff);box-shadow:0 1px 3px #0000000d}:host ::ng-deep .tk-tree-table .p-treetable-scrollable-header,:host ::ng-deep .tk-tree-table .p-treetable-thead{display:none}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr{background-color:var(--tk-color-base-surface-0, #ffffff);border-bottom:1px solid var(--tk-color-base-surface-100, #f2f1f1);transition:background-color .2s ease}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr:last-child{border-bottom:none}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr:hover{background-color:var(--tk-color-base-surface-50, #fbfafa)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr.tk-tree-table__row--level-0{background-color:var(--tk-color-base-surface-50, #fbfafa)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr.tk-tree-table__row--level-1:hover{background-color:var(--tk-color-base-primary-50, #e8e6f1)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr.tk-tree-table__row--level-2:hover{background-color:var(--tk-color-base-primary-50, #e8e6f1)}:host ::ng-deep .tk-tree-table .p-treetable-tbody>tr>td{padding:0!important;border:none!important;background:transparent!important}.tk-tree-table__row-container{display:flex;align-items:center;justify-content:flex-start;padding:var(--tk-spacing-padding-s, 12px) var(--tk-spacing-padding-m, 16px);width:100%;box-sizing:border-box;min-height:56px;gap:var(--tk-spacing-base-100, 12px)}.tk-tree-table__row-container--level-0 .tk-tree-table__label{font-size:var(--tk-font-size-base-100, 1rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-base-surface-950, #191a1b)}.tk-tree-table__row-container--level-0 .tk-tree-table__icon-wrapper{color:var(--tk-color-base-primary-300, #948abd)}.tk-tree-table__row-container--level-1 .tk-tree-table__label{font-size:var(--tk-font-size-base-100, 1rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-base-surface-800, #303031)}.tk-tree-table__row-container--level-1 .tk-tree-table__icon-wrapper{color:var(--tk-color-base-primary-300, #948abd)}.tk-tree-table__row-container--level-2 .tk-tree-table__label{font-size:var(--tk-font-size-base-100, 1rem);font-weight:var(--tk-font-weight-400, 400);color:var(--tk-color-base-surface-700, #424243)}.tk-tree-table__row-container--level-2 .tk-tree-table__icon-wrapper{color:var(--tk-color-base-surface-300, #d2d2d2)}.tk-tree-table__left{display:flex;align-items:center;gap:var(--tk-spacing-base-100, 12px);flex-shrink:0}.tk-tree-table__center{display:flex;align-items:center;gap:var(--tk-spacing-base-100, 12px);margin-left:24px;flex-grow:1}.tk-tree-table__toggler{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px}.tk-tree-table__toggler ::ng-deep .tk-button.p-button{background:transparent!important;border:none!important;padding:0!important;width:24px!important;height:24px!important;color:var(--tk-color-base-surface-500, #8a8a8b)!important;border-radius:var(--tk-border-radius-xs, 4px)!important;min-width:auto!important;transition:background-color .2s ease,color .2s ease}.tk-tree-table__toggler ::ng-deep .tk-button.p-button:hover{background-color:var(--tk-color-base-surface-100, #f2f1f1)!important;color:var(--tk-color-base-surface-800, #303031)!important}.tk-tree-table__toggler ::ng-deep tk-icon{transition:transform .2s cubic-bezier(.4,0,.2,1);display:inline-block}.tk-tree-table__toggler--rotated ::ng-deep tk-icon{transform:rotate(90deg)}.tk-tree-table__toggler-placeholder{width:24px;height:24px;display:inline-block}.tk-tree-table__icon-wrapper{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;font-size:1.2rem}.tk-tree-table__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tk-tree-table__right{display:flex;align-items:center;gap:var(--tk-spacing-base-100, 12px);margin-left:auto}@media(max-width:640px){.tk-tree-table__row-container{flex-wrap:wrap;align-items:flex-start;gap:var(--tk-spacing-base-50, 8px);padding:var(--tk-spacing-padding-s, 12px)}.tk-tree-table__center{margin-left:0;padding-left:var(--tk-spacing-base-300, 36px);width:100%;flex-grow:0}.tk-tree-table__right{margin-left:0;padding-left:var(--tk-spacing-base-300, 36px);width:100%;margin-top:4px}}\n"] }]
|
|
87
|
+
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], iconTemplate: [{ type: i0.ContentChild, args: ['iconTemplate', { isSignal: true }] }], centerTemplate: [{ type: i0.ContentChild, args: ['centerTemplate', { isSignal: true }] }], rightTemplate: [{ type: i0.ContentChild, args: ['rightTemplate', { isSignal: true }] }] } });
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Generated bundle index. Do not edit.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
export { TreeTableComponent };
|
|
94
|
+
//# sourceMappingURL=tekus-design-system-components-tree-table.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-tree-table.mjs","sources":["../../../projects/design-system/components/tree-table/src/tree-table.component.ts","../../../projects/design-system/components/tree-table/src/tree-table.component.html","../../../projects/design-system/components/tree-table/tekus-design-system-components-tree-table.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n contentChild,\n effect,\n input,\n signal,\n TemplateRef,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TreeTableModule } from 'primeng/treetable';\nimport { TreeNode } from 'primeng/api';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { TkTreeNode } from './tree-table.types';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-tree-table',\n imports: [CommonModule, TreeTableModule, IconComponent, ButtonComponent],\n templateUrl: './tree-table.component.html',\n styleUrl: './tree-table.component.scss',\n})\nexport class TreeTableComponent {\n /**\n * Hierarchical list of tree nodes to render.\n */\n data = input<TkTreeNode[]>([]);\n\n /**\n * Custom template slot to render the icon on the left of each node label.\n * Usage: `<ng-template #iconTemplate let-node>...</ng-template>`\n */\n readonly iconTemplate = contentChild<TemplateRef<unknown>>('iconTemplate');\n\n /**\n * Custom template slot to render center information/indicators.\n * Usage: `<ng-template #centerTemplate let-node>...</ng-template>`\n */\n readonly centerTemplate = contentChild<TemplateRef<unknown>>('centerTemplate');\n\n /**\n * Custom template slot to render additional actions/content on the right of the row.\n * Usage: `<ng-template #rightTemplate let-node>...</ng-template>`\n */\n readonly rightTemplate = contentChild<TemplateRef<unknown>>('rightTemplate');\n\n /**\n * Internal representation of the tree nodes mapped to PrimeNG's format.\n */\n readonly primeNodes = signal<TreeNode[]>([]);\n\n constructor() {\n effect(() => {\n const mapped = this.mapToPrimeNodes(this.data());\n this.primeNodes.set(mapped);\n });\n }\n\n private mapToPrimeNodes(nodes: TkTreeNode[]): TreeNode[] {\n return nodes.map(node => ({\n key: node.id?.toString(),\n data: node,\n expanded: node.expanded ?? false,\n children: node.children?.length\n ? this.mapToPrimeNodes(node.children)\n : undefined,\n }));\n }\n\n /**\n * API Method: Recursively expands all nodes.\n */\n expandAll(): void {\n const updated = this.toggleAllNodes(this.primeNodes(), true);\n this.primeNodes.set(updated);\n }\n\n /**\n * API Method: Recursively collapses all nodes.\n */\n collapseAll(): void {\n const updated = this.toggleAllNodes(this.primeNodes(), false);\n this.primeNodes.set(updated);\n }\n\n private toggleAllNodes(nodes: TreeNode[], expanded: boolean): TreeNode[] {\n return nodes.map(node => ({\n ...node,\n expanded,\n children: node.children ? this.toggleAllNodes(node.children, expanded) : [],\n }));\n }\n\n /**\n * Toggles the expansion state of a specific node.\n */\n toggleNode(rowNode: { node: TreeNode; level?: number }): void {\n if (rowNode?.node) {\n rowNode.node.expanded = !rowNode.node.expanded;\n this.primeNodes.set([...this.primeNodes()]);\n }\n }\n}\n","<p-treeTable [value]=\"primeNodes()\" class=\"tk-tree-table\">\n <ng-template pTemplate=\"body\" let-rowNode let-rowData=\"rowData\">\n <tr [ttRow]=\"rowNode\" \n class=\"tk-tree-table__row\"\n [class.tk-tree-table__row--level-0]=\"rowNode.level === 0\"\n [class.tk-tree-table__row--level-1]=\"rowNode.level === 1\"\n [class.tk-tree-table__row--level-2]=\"rowNode.level >= 2\">\n <td class=\"tk-tree-table__cell\">\n <div class=\"tk-tree-table__row-container\" \n [class.tk-tree-table__row-container--level-0]=\"rowNode.level === 0\"\n [class.tk-tree-table__row-container--level-1]=\"rowNode.level === 1\"\n [class.tk-tree-table__row-container--level-2]=\"rowNode.level >= 2\"\n [style.padding-left.px]=\"rowNode.level * 32\">\n \n <!-- LEFT SIDE: Chevron + Icon + Label -->\n <div class=\"tk-tree-table__left\">\n <!-- Toggler Chevron -->\n @if (rowNode.node.children && rowNode.node.children.length > 0) {\n <tk-button \n class=\"tk-tree-table__toggler\" \n [class.tk-tree-table__toggler--rotated]=\"rowNode.node.expanded\"\n icon=\"chevron-right\"\n variant=\"text\"\n severity=\"secondary\"\n [ariaLabel]=\"rowNode.node.expanded ? 'Colapsar nodo' : 'Expandir nodo'\"\n (clicked)=\"toggleNode(rowNode)\">\n </tk-button>\n } @else {\n <span class=\"tk-tree-table__toggler-placeholder\"></span>\n }\n\n <!-- Icon Slot -->\n <div class=\"tk-tree-table__icon-wrapper\">\n @if (iconTemplate()) {\n <ng-container *ngTemplateOutlet=\"iconTemplate(); context: { $implicit: rowData }\"></ng-container>\n } @else if (rowData.icon) {\n <tk-icon \n [icon]=\"rowData.icon\" \n [styleIcon]=\"rowData.iconStyle || 'regular'\" \n class=\"tk-tree-table__icon\">\n </tk-icon>\n }\n </div>\n\n <!-- Label -->\n <span class=\"tk-tree-table__label\">{{ rowData.label }}</span>\n </div>\n\n <!-- CENTER SIDE: Custom Information Column -->\n @if (centerTemplate()) {\n <div class=\"tk-tree-table__center\">\n <ng-container *ngTemplateOutlet=\"centerTemplate(); context: { $implicit: rowData }\"></ng-container>\n </div>\n }\n\n <!-- RIGHT SIDE: Custom Dynamic Content Slot -->\n @if (rightTemplate()) {\n <div class=\"tk-tree-table__right\">\n <ng-container *ngTemplateOutlet=\"rightTemplate(); context: { $implicit: rowData }\"></ng-container>\n </div>\n }\n \n </div>\n </td>\n </tr>\n </ng-template>\n</p-treeTable>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;MAuBa,kBAAkB,CAAA;AA6B7B,IAAA,WAAA,GAAA;AA5BA;;AAEG;AACH,QAAA,IAAA,CAAA,IAAI,GAAG,KAAK,CAAe,EAAE,2EAAC;AAE9B;;;AAGG;AACM,QAAA,IAAA,CAAA,YAAY,GAAG,YAAY,CAAuB,cAAc,mFAAC;AAE1E;;;AAGG;AACM,QAAA,IAAA,CAAA,cAAc,GAAG,YAAY,CAAuB,gBAAgB,qFAAC;AAE9E;;;AAGG;AACM,QAAA,IAAA,CAAA,aAAa,GAAG,YAAY,CAAuB,eAAe,oFAAC;AAE5E;;AAEG;AACM,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAa,EAAE,iFAAC;QAG1C,MAAM,CAAC,MAAK;YACV,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AAChD,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;AAC7B,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,eAAe,CAAC,KAAmB,EAAA;QACzC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK;AACxB,YAAA,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE;AACxB,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;AAChC,YAAA,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;kBACrB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ;AACpC,kBAAE,SAAS;AACd,SAAA,CAAC,CAAC;IACL;AAEA;;AAEG;IACH,SAAS,GAAA;AACP,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC;AAC5D,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9B;AAEA;;AAEG;IACH,WAAW,GAAA;AACT,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC;AAC7D,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;IAC9B;IAEQ,cAAc,CAAC,KAAiB,EAAE,QAAiB,EAAA;QACzD,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK;AACxB,YAAA,GAAG,IAAI;YACP,QAAQ;YACR,QAAQ,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE;AAC5E,SAAA,CAAC,CAAC;IACL;AAEA;;AAEG;AACH,IAAA,UAAU,CAAC,OAA2C,EAAA;AACpD,QAAA,IAAI,OAAO,EAAE,IAAI,EAAE;YACjB,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ;AAC9C,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC7C;IACF;+GA/EW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,cAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,cAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,eAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,eAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvB/B,64FAmEA,EAAA,MAAA,EAAA,CAAA,40IAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDhDY,YAAY,qMAAE,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,wCAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,MAAA,EAAA,gBAAA,EAAA,WAAA,EAAA,MAAA,EAAA,OAAA,EAAA,WAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,2BAAA,EAAA,2BAAA,EAAA,uBAAA,EAAA,wBAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,0BAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,SAAA,EAAA,aAAA,EAAA,YAAA,EAAA,YAAA,EAAA,cAAA,EAAA,eAAA,EAAA,uBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,aAAA,EAAA,eAAA,EAAA,kBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,aAAA,EAAA,YAAA,EAAA,SAAA,EAAA,oBAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,WAAA,EAAA,WAAA,EAAA,eAAA,EAAA,WAAA,EAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,4BAAA,EAAA,UAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,YAAA,EAAA,cAAA,EAAA,aAAA,EAAA,cAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,qBAAA,EAAA,wBAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,aAAa,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,WAAA,EAAA,OAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,eAAe,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,UAAA,EAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,MAAA,EAAA,MAAA,EAAA,cAAA,EAAA,aAAA,EAAA,MAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAI5D,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;AACS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,eAAe,EAAA,OAAA,EAChB,CAAC,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,CAAC,EAAA,QAAA,EAAA,64FAAA,EAAA,MAAA,EAAA,CAAA,40IAAA,CAAA,EAAA;+LAcb,cAAc,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,cAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,IAAA,EAAA,CAMZ,gBAAgB,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,IAAA,EAAA,CAMjB,eAAe,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AE7C7E;;AAEG;;;;"}
|