@sarasanalytics-com/design-system 0.0.164 → 0.0.165

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, ViewEncapsulation, EventEmitter, Input, Output, Injectable, inject, Inject, ChangeDetectionStrategy, ViewChild, HostListener, signal, computed, Optional, ElementRef, effect, forwardRef, Directive, HostBinding } from '@angular/core';
2
+ import { Component, ViewEncapsulation, EventEmitter, Input, Output, Injectable, inject, Inject, ChangeDetectionStrategy, ViewChild, HostListener, signal, computed, Optional, ElementRef, effect, forwardRef, HostBinding, Directive } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule, NgIf, NgStyle, NgFor } from '@angular/common';
5
5
  import * as i1 from '@angular/material/tooltip';
@@ -3925,113 +3925,565 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
3925
3925
  args: [forwardRef(() => MenuDirective)]
3926
3926
  }] } });
3927
3927
 
3928
- class SAMenuComponent {
3929
- constructor(overlay) {
3930
- this.overlay = overlay;
3931
- this.position = 'bottom'; // Default position
3932
- this.onEvent = new EventEmitter();
3933
- this.onKeyUpEvent = new EventEmitter();
3934
- this.closeEvent = new EventEmitter();
3935
- // @ViewChild('menu', {static: true}) menu;
3936
- this.isExpanded = false;
3937
- this.activeTabIndex = 0; // Track the active tab index
3928
+ class SkeletonBaseComponent {
3929
+ constructor() {
3930
+ this.width = '100%';
3931
+ this.height = '1rem';
3932
+ this.darkMode = false;
3938
3933
  }
3939
- ngOnChanges(changes) {
3940
- if (changes['menu'] && changes['menu'].currentValue) {
3941
- console.log('Menu component detected changes:', changes['menu'].currentValue);
3942
- // Reset active tab index if tabs have changed
3943
- if (this.menu?.tabs?.length && this.activeTabIndex >= this.menu.tabs.length) {
3944
- this.activeTabIndex = 0;
3945
- }
3946
- // Prevent the menu from closing by stopping propagation of any events
3947
- // that might trigger menu closing during this update cycle
3948
- setTimeout(() => {
3949
- // This ensures the menu stays open after the change detection cycle completes
3950
- console.log('Menu update complete, menu should remain open');
3951
- }, 0);
3952
- }
3934
+ get isDark() { return this.darkMode; }
3935
+ get getWidth() {
3936
+ return this.width;
3953
3937
  }
3954
- ngAfterViewInit() {
3955
- this.isExpanded = true;
3938
+ get getHeight() {
3939
+ return this.height;
3956
3940
  }
3957
- setPosition() {
3958
- // const positions: { [key: string]: ConnectedPosition } = {
3959
- // left: { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' },
3960
- // right: { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'top' },
3961
- // top: { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top' },
3962
- // bottom: { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom' }
3963
- // };
3964
- // const overlayRef = this.overlay.create();
3965
- // const userProfilePortal = new ComponentPortal(CardComponent);
3966
- // const compRef = overlayRef.attach(userProfilePortal);
3967
- // compRef.instance.title = 'need nduk ra bhai'
3968
- // compRef.instance.body = 'sometime little bit this sometimes little bit that. Comming not comming'
3969
- // compRef.instance.avatar = '../assets/avatar.svg'
3941
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3942
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonBaseComponent, isStandalone: true, selector: "sa-skeleton-base", inputs: { width: "width", height: "height", darkMode: "darkMode" }, host: { properties: { "class.sa-dark": "this.isDark", "style.width": "this.getWidth", "style.height": "this.getHeight" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:block;position:relative;overflow:hidden;background:var(--sa-skeleton-background, #e9ecef);border-radius:var(--sa-skeleton-radius, 4px)}:host.sa-dark{background:var(--sa-skeleton-background-dark, #344054)}:host:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,var(--sa-skeleton-shine, rgba(255, 255, 255, .3)),transparent);animation:shimmer var(--sa-skeleton-animation-duration, 1.5s) infinite}:host.sa-dark:after{background:linear-gradient(90deg,transparent,var(--sa-skeleton-shine-dark, #98A2B3),transparent)}@keyframes shimmer{to{transform:translate(100%)}}\n"] }); }
3943
+ }
3944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonBaseComponent, decorators: [{
3945
+ type: Component,
3946
+ args: [{ selector: 'sa-skeleton-base', standalone: true, template: `<ng-content></ng-content>`, styles: [":host{display:block;position:relative;overflow:hidden;background:var(--sa-skeleton-background, #e9ecef);border-radius:var(--sa-skeleton-radius, 4px)}:host.sa-dark{background:var(--sa-skeleton-background-dark, #344054)}:host:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,var(--sa-skeleton-shine, rgba(255, 255, 255, .3)),transparent);animation:shimmer var(--sa-skeleton-animation-duration, 1.5s) infinite}:host.sa-dark:after{background:linear-gradient(90deg,transparent,var(--sa-skeleton-shine-dark, #98A2B3),transparent)}@keyframes shimmer{to{transform:translate(100%)}}\n"] }]
3947
+ }], propDecorators: { width: [{
3948
+ type: Input
3949
+ }], height: [{
3950
+ type: Input
3951
+ }], darkMode: [{
3952
+ type: Input
3953
+ }], isDark: [{
3954
+ type: HostBinding,
3955
+ args: ['class.sa-dark']
3956
+ }], getWidth: [{
3957
+ type: HostBinding,
3958
+ args: ['style.width']
3959
+ }], getHeight: [{
3960
+ type: HostBinding,
3961
+ args: ['style.height']
3962
+ }] } });
3963
+
3964
+ class SkeletonTextComponent {
3965
+ constructor() {
3966
+ this.width = '100%';
3967
+ this.height = '1rem';
3970
3968
  }
3971
- itemClicked(event) {
3972
- this.onMenuItemClick(null, event.item);
3969
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3970
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonTextComponent, isStandalone: true, selector: "sa-skeleton-text", inputs: { width: "width", height: "height", darkMode: "darkMode" }, ngImport: i0, template: `<sa-skeleton-base [width]="width" [height]="height" [darkMode]="darkMode"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height", "darkMode"] }] }); }
3971
+ }
3972
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonTextComponent, decorators: [{
3973
+ type: Component,
3974
+ args: [{
3975
+ selector: 'sa-skeleton-text',
3976
+ standalone: true,
3977
+ imports: [SkeletonBaseComponent],
3978
+ template: `<sa-skeleton-base [width]="width" [height]="height" [darkMode]="darkMode"></sa-skeleton-base>`,
3979
+ }]
3980
+ }], propDecorators: { width: [{
3981
+ type: Input
3982
+ }], height: [{
3983
+ type: Input
3984
+ }], darkMode: [{
3985
+ type: Input
3986
+ }] } });
3987
+ class SkeletonCircleComponent {
3988
+ constructor() {
3989
+ this.size = '3rem';
3973
3990
  }
3974
- onMenuItemClick(event, item) {
3975
- // item.isSelected = !item.isSelected;
3976
- this.onEvent.emit({ type: 'CLICK', item, menu: this.menu });
3977
- // Close the menu after the item is clicked, just like the close button
3978
- if (item.subMenu === null || item.subMenu === undefined) {
3979
- this.closeEvent.emit(event);
3980
- }
3991
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonCircleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3992
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonCircleComponent, isStandalone: true, selector: "sa-skeleton-circle", inputs: { size: "size", darkMode: "darkMode" }, ngImport: i0, template: `<sa-skeleton-base [width]="size" [height]="size" [darkMode]="darkMode" style="border-radius: 50%"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height", "darkMode"] }] }); }
3993
+ }
3994
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonCircleComponent, decorators: [{
3995
+ type: Component,
3996
+ args: [{
3997
+ selector: 'sa-skeleton-circle',
3998
+ standalone: true,
3999
+ imports: [SkeletonBaseComponent],
4000
+ template: `<sa-skeleton-base [width]="size" [height]="size" [darkMode]="darkMode" style="border-radius: 50%"></sa-skeleton-base>`,
4001
+ }]
4002
+ }], propDecorators: { size: [{
4003
+ type: Input
4004
+ }], darkMode: [{
4005
+ type: Input
4006
+ }] } });
4007
+ class SkeletonRectangleComponent {
4008
+ constructor() {
4009
+ this.width = '100%';
4010
+ this.height = '100px';
3981
4011
  }
3982
- onSearch(event) {
3983
- this.onEvent.emit({ type: 'SEARCH', value: event.target.value });
4012
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonRectangleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4013
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonRectangleComponent, isStandalone: true, selector: "sa-skeleton-rectangle", inputs: { width: "width", height: "height", darkMode: "darkMode" }, ngImport: i0, template: `<sa-skeleton-base [width]="width" [height]="height" [darkMode]="darkMode"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height", "darkMode"] }] }); }
4014
+ }
4015
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonRectangleComponent, decorators: [{
4016
+ type: Component,
4017
+ args: [{
4018
+ selector: 'sa-skeleton-rectangle',
4019
+ standalone: true,
4020
+ imports: [SkeletonBaseComponent],
4021
+ template: `<sa-skeleton-base [width]="width" [height]="height" [darkMode]="darkMode"></sa-skeleton-base>`,
4022
+ }]
4023
+ }], propDecorators: { width: [{
4024
+ type: Input
4025
+ }], height: [{
4026
+ type: Input
4027
+ }], darkMode: [{
4028
+ type: Input
4029
+ }] } });
4030
+ class SkeletonEllipticalComponent {
4031
+ constructor() {
4032
+ this.width = '200px';
4033
+ this.height = '48px';
3984
4034
  }
3985
- setActiveTab(index, tabname) {
3986
- this.activeTabIndex = index; // Update the active tab index
3987
- this.onEvent.emit({ type: 'TAB_CLICK', activeTab: tabname, menu: this.menu });
4035
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonEllipticalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4036
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonEllipticalComponent, isStandalone: true, selector: "sa-skeleton-elliptical", inputs: { width: "width", height: "height", darkMode: "darkMode" }, ngImport: i0, template: `<sa-skeleton-base [width]="width" [height]="height" [darkMode]="darkMode" style="border-radius: 100px;"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height", "darkMode"] }] }); }
4037
+ }
4038
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonEllipticalComponent, decorators: [{
4039
+ type: Component,
4040
+ args: [{
4041
+ selector: 'sa-skeleton-elliptical',
4042
+ standalone: true,
4043
+ imports: [SkeletonBaseComponent],
4044
+ template: `<sa-skeleton-base [width]="width" [height]="height" [darkMode]="darkMode" style="border-radius: 100px;"></sa-skeleton-base>`,
4045
+ }]
4046
+ }], propDecorators: { width: [{
4047
+ type: Input
4048
+ }], height: [{
4049
+ type: Input
4050
+ }], darkMode: [{
4051
+ type: Input
4052
+ }] } });
4053
+
4054
+ class SkeletonContainerComponent {
4055
+ constructor() {
4056
+ this.direction = 'column';
3988
4057
  }
3989
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SAMenuComponent, deps: [{ token: i1$4.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
3990
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: SAMenuComponent, isStandalone: true, selector: "sa-menu", inputs: { position: "position", menu: "menu", hostEl: "hostEl" }, outputs: { onEvent: "onEvent", onKeyUpEvent: "onKeyUpEvent", closeEvent: "closeEvent" }, providers: [IconService], usesOnChanges: true, ngImport: i0, template: "<div class=\"sa-menu\" [ngClass]=\"menu.showTray ? 'sa-menu-tray sa-round-border' : ''\"\r\n [ngStyle]=\"{width: menu.width || 'max-content'}\">\r\n @if(menu?.title){\r\n <div class=\"sa-menu-title\">\r\n <h1>{{menu?.title}}</h1>\r\n <sa-icon [icon]=\"'closeOutlined'\" [size]=\"'20'\" color=\"var(--grey-200, #D0D5DD)\" class=\"sa-menu-close-icon\"\r\n (click)=\"closeEvent.emit($event)\"></sa-icon>\r\n </div>\r\n }\r\n\r\n <!-- @if(menu?.itemGroups && menu.itemGroups.length){\r\n @for (groupItem of menu.itemGroups; track groupItem) {\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n \r\n @for (item of groupItem.items; track $index) {\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n }\r\n } @else if(menu?.items && menu.items.length){\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n } -->\r\n\r\n\r\n <!-- Tab Content or Item Groups -->\r\n <div class=\"sa-menu-content\">\r\n <div class=\"sa-menu-content-inner {{menu?.showSearch ? 'sa-menu-content-with-search' : ''}}\">\r\n @if(menu?.showSearch){\r\n <div class=\"search-container\">\r\n <sa-icon icon=\"search\"></sa-icon>\r\n <input name=\"menu-search-bar\" class=\"search-input\" (keyup)=\"onSearch($event)\" type=\"text\" [placeholder]=\"menu.searchPlaceholder\" \r\n />\r\n <button *ngIf=\"menu?.showAddIcon\"><i class=\"fas fa-plus\"></i></button>\r\n </div>\r\n }\r\n \r\n <!-- Tabs -->\r\n @if(menu?.tabs){\r\n <div class=\"sa-menu-tabs\">\r\n <button *ngFor=\"let tab of menu.tabs; let i = index\" [class.active]=\"i === activeTabIndex\"\r\n (click)=\"setActiveTab(i,tab.label)\">\r\n {{ tab.label }}\r\n <!-- ({{ tab.itemGroups.length }}) -->\r\n </button>\r\n </div>\r\n }\r\n <!-- Tabs End -->\r\n\r\n @if(menu?.tabs?.length){\r\n @if(menu.tabs[activeTabIndex]?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.tabs[activeTabIndex].itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n } @else if(menu?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if(menu?.items && menu?.items?.length){\r\n <div *ngIf=\"menu?.user\" class=\"profile-badge\">\r\n <div class=\"avatar\">\r\n <sa-avatar [altText]=\"menu?.user?.altText\" [imagePath]=\"''\" [size]=\"'large'\"></sa-avatar>\r\n </div>\r\n <div class=\"profile-info\">\r\n <p class=\"profile-name\">{{menu?.user?.name}}</p>\r\n <p class=\"profile-email\">{{menu?.user?.email}}</p>\r\n </div>\r\n </div>\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (onEvent)=\"itemClicked($event)\"> </sa-menu-item>\r\n }\r\n </div>\r\n }\r\n\r\n</div>", styles: [".sa-menu{background-color:var(--primary-800);box-shadow:3px 4px 16px 4px #00000014;width:max-content;border-radius:5px;overflow-y:auto;max-height:100%}.sa-round-border{border-radius:8px}.sa-menu-tray{height:calc(100vh - 16px);margin-top:8px;border-top-left-radius:0;border-bottom-left-radius:0;background:var(--grey-700, #1D2939);padding:0 1rem 1rem;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.sa-menu-tray::-webkit-scrollbar{width:6px}.sa-menu-tray::-webkit-scrollbar-track{background:transparent}.sa-menu-tray::-webkit-scrollbar-thumb{background-color:#ffffff4d;border-radius:3px}sa-menu-item{cursor:pointer;display:block;color:var(--grey-100, #EAECF0)}.sa-menu-title{display:flex;justify-content:space-between;align-items:center;position:fixed;padding:1rem 0 .5rem;height:64px;width:calc(100% - 2rem);border-bottom:1px solid var(--primary-50, #F4EBFF);background:var(--grey-700, #1D2939);z-index:1}.sa-menu-title h1{color:var(--grey-100, #EAECF0);font-family:var(--font-family, Roboto);font-size:16px;font-style:normal;font-weight:400;line-height:24px;letter-spacing:.5px;margin-bottom:0;margin-top:0}.sa-menu-close-icon{cursor:pointer;margin-left:auto;height:20px}.search-container{position:relative;display:flex;align-items:center;margin-bottom:1rem;margin-top:4.75rem}.search-container input{flex:1;padding:.5rem .5rem .5rem 2rem;background-color:#4a5568;border-radius:.25rem;font-size:.875rem;border:none;outline:none;border-radius:4px;color:var(--grey-200, #D0D5DD);border:1px solid var(--grey-900, #0C111D);background:var(--grey-900, #0C111D);box-sizing:border-box}.search-container .search-icon{position:absolute;left:.5rem;font-size:1rem;color:#888;pointer-events:none}.search-container button{margin-left:.5rem;background-color:#6b46c1;padding:.5rem;border-radius:.25rem;border:none;cursor:pointer}.sa-menu-group{margin-bottom:1rem;padding-bottom:.8rem;border-bottom:1px solid var(--grey-400, #475467)}.sa-menu-group:last-child{border-bottom:none}.sa-menu-group h2{color:var(--grey-300, #D0D5DD);font-family:var(--font-family, Roboto);font-size:11px;font-style:normal;font-weight:400;line-height:16px;letter-spacing:.5px;text-transform:uppercase;margin-bottom:.5rem}.MenuBar{width:max-content;margin-top:8px;background-color:var(--grey-400);border-top-left-radius:0;border-bottom-left-radius:0;background-color:#2d3748;padding:0}.sa-menu-tabs{display:flex;border-bottom:1px solid #ccc;margin-bottom:1rem}.sa-menu-tabs button{flex:1;padding:.5rem 1rem;background:none;border:none;cursor:pointer;font-size:12px;font-style:normal;font-weight:400;line-height:16px;color:#888;border-bottom:2px solid transparent;transition:all .5s ease}.sa-menu-tabs button.active{color:#f7f3f3;border-bottom:2px solid #f7f7f7;font-size:12px;font-style:normal;font-weight:600;line-height:16px;letter-spacing:.5px}.sa-menu-content{padding:0rem 0}.sa-menu-content-inner{padding-top:0}.sa-menu-content .sa-menu-content-with-search,.sa-menu-content-with-search.sa-menu-content-inner{padding:0}.features-tray-menu .sa-menu-content-inner{padding-top:5rem}.features-tray-menu .sa-menu-content-with-search.sa-menu-content-inner{padding-top:0}.sa-menu-group h2{margin-top:1rem}.sa-menu-group:first-child h2{margin-top:0}.sa-menu-group{margin-bottom:1rem}.profile-badge{display:flex;align-items:center;gap:8px;padding:12px;width:100%;border-bottom:1px solid var(--grey-400)}.avatar{display:flex;justify-content:center;align-items:center}.profile-info{display:flex;flex-direction:column;justify-content:center;font-weight:300}.profile-name{color:var(--structural-white);font-weight:500;font-size:12px;line-height:1.2;margin:0}.profile-email{color:var(--grey-200);font-size:11px;line-height:1.2;font-weight:400;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SAMenuItemComponent, selector: "sa-menu-item", inputs: ["item", "showRound"], outputs: ["onEvent"] }, { kind: "ngmodule", type: HttpClientModule }, { kind: "component", type: IconComponent, selector: "sa-icon", inputs: ["img", "imgWidth", "imgHeight", "icon", "size", "color", "iconPath", "iconUrl", "customClass", "href", "hrefTarget", "iconPosition"], outputs: ["onClickEvent"] }, { kind: "component", type: AvatarComponent, selector: "sa-avatar", inputs: ["id", "imagePath", "altText", "size"], outputs: ["onClickEvent", "onMouseInEvent", "onMouseOutEvent"] }] }); }
4058
+ get containerStyles() {
4059
+ return {
4060
+ gap: this.gap,
4061
+ padding: this.padding,
4062
+ flexDirection: this.direction
4063
+ };
4064
+ }
4065
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4066
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonContainerComponent, isStandalone: true, selector: "sa-skeleton-container", inputs: { gap: "gap", padding: "padding", direction: "direction" }, ngImport: i0, template: `
4067
+ <div class="skeleton-container" [ngStyle]="containerStyles">
4068
+ <ng-content></ng-content>
4069
+ </div>
4070
+ `, isInline: true, styles: [".skeleton-container{display:flex;flex-direction:column;gap:var(--sa-skeleton-gap, 1rem);padding:var(--sa-skeleton-padding, 1rem)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
3991
4071
  }
3992
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SAMenuComponent, decorators: [{
4072
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonContainerComponent, decorators: [{
3993
4073
  type: Component,
3994
- args: [{ selector: 'sa-menu', standalone: true, imports: [
3995
- CommonModule,
3996
- SAMenuItemComponent,
3997
- MatMenu,
3998
- MatMenuItem,
3999
- ChipsComponent,
4000
- HttpClientModule,
4001
- IconComponent,
4002
- AvatarComponent,
4003
- ], providers: [IconService], template: "<div class=\"sa-menu\" [ngClass]=\"menu.showTray ? 'sa-menu-tray sa-round-border' : ''\"\r\n [ngStyle]=\"{width: menu.width || 'max-content'}\">\r\n @if(menu?.title){\r\n <div class=\"sa-menu-title\">\r\n <h1>{{menu?.title}}</h1>\r\n <sa-icon [icon]=\"'closeOutlined'\" [size]=\"'20'\" color=\"var(--grey-200, #D0D5DD)\" class=\"sa-menu-close-icon\"\r\n (click)=\"closeEvent.emit($event)\"></sa-icon>\r\n </div>\r\n }\r\n\r\n <!-- @if(menu?.itemGroups && menu.itemGroups.length){\r\n @for (groupItem of menu.itemGroups; track groupItem) {\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n \r\n @for (item of groupItem.items; track $index) {\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n }\r\n } @else if(menu?.items && menu.items.length){\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n } -->\r\n\r\n\r\n <!-- Tab Content or Item Groups -->\r\n <div class=\"sa-menu-content\">\r\n <div class=\"sa-menu-content-inner {{menu?.showSearch ? 'sa-menu-content-with-search' : ''}}\">\r\n @if(menu?.showSearch){\r\n <div class=\"search-container\">\r\n <sa-icon icon=\"search\"></sa-icon>\r\n <input name=\"menu-search-bar\" class=\"search-input\" (keyup)=\"onSearch($event)\" type=\"text\" [placeholder]=\"menu.searchPlaceholder\" \r\n />\r\n <button *ngIf=\"menu?.showAddIcon\"><i class=\"fas fa-plus\"></i></button>\r\n </div>\r\n }\r\n \r\n <!-- Tabs -->\r\n @if(menu?.tabs){\r\n <div class=\"sa-menu-tabs\">\r\n <button *ngFor=\"let tab of menu.tabs; let i = index\" [class.active]=\"i === activeTabIndex\"\r\n (click)=\"setActiveTab(i,tab.label)\">\r\n {{ tab.label }}\r\n <!-- ({{ tab.itemGroups.length }}) -->\r\n </button>\r\n </div>\r\n }\r\n <!-- Tabs End -->\r\n\r\n @if(menu?.tabs?.length){\r\n @if(menu.tabs[activeTabIndex]?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.tabs[activeTabIndex].itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n } @else if(menu?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if(menu?.items && menu?.items?.length){\r\n <div *ngIf=\"menu?.user\" class=\"profile-badge\">\r\n <div class=\"avatar\">\r\n <sa-avatar [altText]=\"menu?.user?.altText\" [imagePath]=\"''\" [size]=\"'large'\"></sa-avatar>\r\n </div>\r\n <div class=\"profile-info\">\r\n <p class=\"profile-name\">{{menu?.user?.name}}</p>\r\n <p class=\"profile-email\">{{menu?.user?.email}}</p>\r\n </div>\r\n </div>\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (onEvent)=\"itemClicked($event)\"> </sa-menu-item>\r\n }\r\n </div>\r\n }\r\n\r\n</div>", styles: [".sa-menu{background-color:var(--primary-800);box-shadow:3px 4px 16px 4px #00000014;width:max-content;border-radius:5px;overflow-y:auto;max-height:100%}.sa-round-border{border-radius:8px}.sa-menu-tray{height:calc(100vh - 16px);margin-top:8px;border-top-left-radius:0;border-bottom-left-radius:0;background:var(--grey-700, #1D2939);padding:0 1rem 1rem;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.sa-menu-tray::-webkit-scrollbar{width:6px}.sa-menu-tray::-webkit-scrollbar-track{background:transparent}.sa-menu-tray::-webkit-scrollbar-thumb{background-color:#ffffff4d;border-radius:3px}sa-menu-item{cursor:pointer;display:block;color:var(--grey-100, #EAECF0)}.sa-menu-title{display:flex;justify-content:space-between;align-items:center;position:fixed;padding:1rem 0 .5rem;height:64px;width:calc(100% - 2rem);border-bottom:1px solid var(--primary-50, #F4EBFF);background:var(--grey-700, #1D2939);z-index:1}.sa-menu-title h1{color:var(--grey-100, #EAECF0);font-family:var(--font-family, Roboto);font-size:16px;font-style:normal;font-weight:400;line-height:24px;letter-spacing:.5px;margin-bottom:0;margin-top:0}.sa-menu-close-icon{cursor:pointer;margin-left:auto;height:20px}.search-container{position:relative;display:flex;align-items:center;margin-bottom:1rem;margin-top:4.75rem}.search-container input{flex:1;padding:.5rem .5rem .5rem 2rem;background-color:#4a5568;border-radius:.25rem;font-size:.875rem;border:none;outline:none;border-radius:4px;color:var(--grey-200, #D0D5DD);border:1px solid var(--grey-900, #0C111D);background:var(--grey-900, #0C111D);box-sizing:border-box}.search-container .search-icon{position:absolute;left:.5rem;font-size:1rem;color:#888;pointer-events:none}.search-container button{margin-left:.5rem;background-color:#6b46c1;padding:.5rem;border-radius:.25rem;border:none;cursor:pointer}.sa-menu-group{margin-bottom:1rem;padding-bottom:.8rem;border-bottom:1px solid var(--grey-400, #475467)}.sa-menu-group:last-child{border-bottom:none}.sa-menu-group h2{color:var(--grey-300, #D0D5DD);font-family:var(--font-family, Roboto);font-size:11px;font-style:normal;font-weight:400;line-height:16px;letter-spacing:.5px;text-transform:uppercase;margin-bottom:.5rem}.MenuBar{width:max-content;margin-top:8px;background-color:var(--grey-400);border-top-left-radius:0;border-bottom-left-radius:0;background-color:#2d3748;padding:0}.sa-menu-tabs{display:flex;border-bottom:1px solid #ccc;margin-bottom:1rem}.sa-menu-tabs button{flex:1;padding:.5rem 1rem;background:none;border:none;cursor:pointer;font-size:12px;font-style:normal;font-weight:400;line-height:16px;color:#888;border-bottom:2px solid transparent;transition:all .5s ease}.sa-menu-tabs button.active{color:#f7f3f3;border-bottom:2px solid #f7f7f7;font-size:12px;font-style:normal;font-weight:600;line-height:16px;letter-spacing:.5px}.sa-menu-content{padding:0rem 0}.sa-menu-content-inner{padding-top:0}.sa-menu-content .sa-menu-content-with-search,.sa-menu-content-with-search.sa-menu-content-inner{padding:0}.features-tray-menu .sa-menu-content-inner{padding-top:5rem}.features-tray-menu .sa-menu-content-with-search.sa-menu-content-inner{padding-top:0}.sa-menu-group h2{margin-top:1rem}.sa-menu-group:first-child h2{margin-top:0}.sa-menu-group{margin-bottom:1rem}.profile-badge{display:flex;align-items:center;gap:8px;padding:12px;width:100%;border-bottom:1px solid var(--grey-400)}.avatar{display:flex;justify-content:center;align-items:center}.profile-info{display:flex;flex-direction:column;justify-content:center;font-weight:300}.profile-name{color:var(--structural-white);font-weight:500;font-size:12px;line-height:1.2;margin:0}.profile-email{color:var(--grey-200);font-size:11px;line-height:1.2;font-weight:400;margin:0}\n"] }]
4004
- }], ctorParameters: () => [{ type: i1$4.Overlay }], propDecorators: { position: [{
4074
+ args: [{ selector: 'sa-skeleton-container', standalone: true, imports: [NgStyle], template: `
4075
+ <div class="skeleton-container" [ngStyle]="containerStyles">
4076
+ <ng-content></ng-content>
4077
+ </div>
4078
+ `, styles: [".skeleton-container{display:flex;flex-direction:column;gap:var(--sa-skeleton-gap, 1rem);padding:var(--sa-skeleton-padding, 1rem)}\n"] }]
4079
+ }], propDecorators: { gap: [{
4005
4080
  type: Input
4006
- }], menu: [{
4081
+ }], padding: [{
4007
4082
  type: Input
4008
- }], hostEl: [{
4083
+ }], direction: [{
4009
4084
  type: Input
4010
- }], onEvent: [{
4011
- type: Output
4012
- }], onKeyUpEvent: [{
4013
- type: Output
4014
- }], closeEvent: [{
4015
- type: Output
4016
4085
  }] } });
4017
4086
 
4018
- class MenuDirective {
4019
- get saMenu() {
4020
- return this._saMenu;
4087
+ const SKELETON_PRESETS = {
4088
+ // Preset for a card with title, subtitle and content
4089
+ card: {
4090
+ items: [
4091
+ { type: 'text', width: '60%', height: '1.5rem' },
4092
+ { type: 'text', width: '40%', height: '1rem' },
4093
+ { type: 'rectangle', height: '100px' }
4094
+ ],
4095
+ containerConfig: {
4096
+ padding: '1rem',
4097
+ gap: '0.75rem'
4098
+ }
4099
+ },
4100
+ // Preset for a list item with avatar
4101
+ listItem: {
4102
+ items: [
4103
+ { type: 'circle', size: '2.5rem' },
4104
+ { type: 'text', width: '70%', height: '1rem' }
4105
+ ],
4106
+ containerConfig: {
4107
+ direction: 'row',
4108
+ gap: '1rem',
4109
+ padding: '0.5rem'
4110
+ }
4111
+ },
4112
+ // Preset for form fields
4113
+ formField: {
4114
+ items: [
4115
+ { type: 'text', width: '30%', height: '1rem' },
4116
+ { type: 'rectangle', height: '2.5rem' }
4117
+ ],
4118
+ containerConfig: {
4119
+ gap: '0.5rem'
4120
+ }
4021
4121
  }
4022
- set saMenu(value) {
4023
- this._saMenu = value;
4024
- // Emit the new configuration to the stream
4025
- this.menuConfig$.next(value);
4122
+ };
4123
+
4124
+ class SkeletonLoaderComponent {
4125
+ ngOnInit() {
4126
+ this.updateConfig();
4026
4127
  }
4027
- get position() {
4028
- return this._position;
4128
+ ngOnChanges(changes) {
4129
+ this.updateConfig();
4029
4130
  }
4030
- set position(value) {
4031
- this._position = value;
4131
+ updateConfig() {
4132
+ if (this.preset && (!this.config || !this.config.items?.length)) {
4133
+ this.config = SKELETON_PRESETS[this.preset];
4134
+ }
4032
4135
  }
4033
- constructor(overlay, overlayContainer, elRef) {
4034
- this.overlay = overlay;
4136
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4137
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: SkeletonLoaderComponent, isStandalone: true, selector: "sa-skeleton-loader", inputs: { preset: "preset", config: "config", darkMode: "darkMode" }, usesOnChanges: true, ngImport: i0, template: `
4138
+ <sa-skeleton-container
4139
+ [gap]="config?.containerConfig?.gap"
4140
+ [padding]="config?.containerConfig?.padding"
4141
+ [direction]="config?.containerConfig?.direction || 'column'"
4142
+ >
4143
+ @for (item of config?.items; track $index) {
4144
+ @switch (item.type) {
4145
+ @case ('text') {
4146
+ <sa-skeleton-text
4147
+ [width]="item.width"
4148
+ [height]="item.height"
4149
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4150
+ ></sa-skeleton-text>
4151
+ }
4152
+ @case ('circle') {
4153
+ <sa-skeleton-circle
4154
+ [size]="item.size"
4155
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4156
+ ></sa-skeleton-circle>
4157
+ }
4158
+ @case ('rectangle') {
4159
+ <sa-skeleton-rectangle
4160
+ [width]="item.width"
4161
+ [height]="item.height"
4162
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4163
+ ></sa-skeleton-rectangle>
4164
+ }
4165
+ @case ('elliptical') {
4166
+ <sa-skeleton-elliptical
4167
+ [width]="item.width"
4168
+ [height]="item.height"
4169
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4170
+ ></sa-skeleton-elliptical>
4171
+ }
4172
+ @case ('container') {
4173
+ <sa-skeleton-container [direction]="item.direction" [gap]="item.gap">
4174
+ @for (subItem of item.items; track $index) {
4175
+ @switch (subItem.type) {
4176
+ @case ('text') {
4177
+ <sa-skeleton-text
4178
+ [width]="subItem.width"
4179
+ [height]="subItem.height"
4180
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4181
+ ></sa-skeleton-text>
4182
+ }
4183
+ @case ('circle') {
4184
+ <sa-skeleton-circle
4185
+ [size]="subItem.size"
4186
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4187
+ ></sa-skeleton-circle>
4188
+ }
4189
+ @case ('rectangle') {
4190
+ <sa-skeleton-rectangle
4191
+ [width]="subItem.width"
4192
+ [height]="subItem.height"
4193
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4194
+ ></sa-skeleton-rectangle>
4195
+ }
4196
+ @case ('elliptical') {
4197
+ <sa-skeleton-elliptical
4198
+ [width]="subItem.width"
4199
+ [height]="subItem.height"
4200
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4201
+ ></sa-skeleton-elliptical>
4202
+ }
4203
+ @case ('container') {
4204
+ <sa-skeleton-container [direction]="subItem.direction" [gap]="subItem.gap">
4205
+ @for (subSubItem of subItem.items; track $index) {
4206
+ @switch (subSubItem.type) {
4207
+ @case ('text') {
4208
+ <sa-skeleton-text
4209
+ [width]="subSubItem.width"
4210
+ [height]="subSubItem.height"
4211
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4212
+ ></sa-skeleton-text>
4213
+ }
4214
+ @case ('circle') {
4215
+ <sa-skeleton-circle
4216
+ [size]="subSubItem.size"
4217
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4218
+ ></sa-skeleton-circle>
4219
+ }
4220
+ @case ('rectangle') {
4221
+ <sa-skeleton-rectangle
4222
+ [width]="subSubItem.width"
4223
+ [height]="subSubItem.height"
4224
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4225
+ ></sa-skeleton-rectangle>
4226
+ }
4227
+ @case ('elliptical') {
4228
+ <sa-skeleton-elliptical
4229
+ [width]="subSubItem.width"
4230
+ [height]="subSubItem.height"
4231
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4232
+ ></sa-skeleton-elliptical>
4233
+ }
4234
+ }
4235
+ }
4236
+ </sa-skeleton-container>
4237
+ }
4238
+ }
4239
+ }
4240
+ </sa-skeleton-container>
4241
+ }
4242
+ }
4243
+ }
4244
+ </sa-skeleton-container>
4245
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SkeletonTextComponent, selector: "sa-skeleton-text", inputs: ["width", "height", "darkMode"] }, { kind: "component", type: SkeletonCircleComponent, selector: "sa-skeleton-circle", inputs: ["size", "darkMode"] }, { kind: "component", type: SkeletonRectangleComponent, selector: "sa-skeleton-rectangle", inputs: ["width", "height", "darkMode"] }, { kind: "component", type: SkeletonEllipticalComponent, selector: "sa-skeleton-elliptical", inputs: ["width", "height", "darkMode"] }, { kind: "component", type: SkeletonContainerComponent, selector: "sa-skeleton-container", inputs: ["gap", "padding", "direction"] }] }); }
4246
+ }
4247
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonLoaderComponent, decorators: [{
4248
+ type: Component,
4249
+ args: [{
4250
+ selector: 'sa-skeleton-loader',
4251
+ standalone: true,
4252
+ imports: [
4253
+ CommonModule,
4254
+ SkeletonBaseComponent,
4255
+ SkeletonTextComponent,
4256
+ SkeletonCircleComponent,
4257
+ SkeletonRectangleComponent,
4258
+ SkeletonEllipticalComponent,
4259
+ SkeletonContainerComponent
4260
+ ],
4261
+ template: `
4262
+ <sa-skeleton-container
4263
+ [gap]="config?.containerConfig?.gap"
4264
+ [padding]="config?.containerConfig?.padding"
4265
+ [direction]="config?.containerConfig?.direction || 'column'"
4266
+ >
4267
+ @for (item of config?.items; track $index) {
4268
+ @switch (item.type) {
4269
+ @case ('text') {
4270
+ <sa-skeleton-text
4271
+ [width]="item.width"
4272
+ [height]="item.height"
4273
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4274
+ ></sa-skeleton-text>
4275
+ }
4276
+ @case ('circle') {
4277
+ <sa-skeleton-circle
4278
+ [size]="item.size"
4279
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4280
+ ></sa-skeleton-circle>
4281
+ }
4282
+ @case ('rectangle') {
4283
+ <sa-skeleton-rectangle
4284
+ [width]="item.width"
4285
+ [height]="item.height"
4286
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4287
+ ></sa-skeleton-rectangle>
4288
+ }
4289
+ @case ('elliptical') {
4290
+ <sa-skeleton-elliptical
4291
+ [width]="item.width"
4292
+ [height]="item.height"
4293
+ [darkMode]="darkMode ?? config?.darkMode ?? item.darkMode"
4294
+ ></sa-skeleton-elliptical>
4295
+ }
4296
+ @case ('container') {
4297
+ <sa-skeleton-container [direction]="item.direction" [gap]="item.gap">
4298
+ @for (subItem of item.items; track $index) {
4299
+ @switch (subItem.type) {
4300
+ @case ('text') {
4301
+ <sa-skeleton-text
4302
+ [width]="subItem.width"
4303
+ [height]="subItem.height"
4304
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4305
+ ></sa-skeleton-text>
4306
+ }
4307
+ @case ('circle') {
4308
+ <sa-skeleton-circle
4309
+ [size]="subItem.size"
4310
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4311
+ ></sa-skeleton-circle>
4312
+ }
4313
+ @case ('rectangle') {
4314
+ <sa-skeleton-rectangle
4315
+ [width]="subItem.width"
4316
+ [height]="subItem.height"
4317
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4318
+ ></sa-skeleton-rectangle>
4319
+ }
4320
+ @case ('elliptical') {
4321
+ <sa-skeleton-elliptical
4322
+ [width]="subItem.width"
4323
+ [height]="subItem.height"
4324
+ [darkMode]="darkMode ?? config?.darkMode ?? subItem.darkMode"
4325
+ ></sa-skeleton-elliptical>
4326
+ }
4327
+ @case ('container') {
4328
+ <sa-skeleton-container [direction]="subItem.direction" [gap]="subItem.gap">
4329
+ @for (subSubItem of subItem.items; track $index) {
4330
+ @switch (subSubItem.type) {
4331
+ @case ('text') {
4332
+ <sa-skeleton-text
4333
+ [width]="subSubItem.width"
4334
+ [height]="subSubItem.height"
4335
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4336
+ ></sa-skeleton-text>
4337
+ }
4338
+ @case ('circle') {
4339
+ <sa-skeleton-circle
4340
+ [size]="subSubItem.size"
4341
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4342
+ ></sa-skeleton-circle>
4343
+ }
4344
+ @case ('rectangle') {
4345
+ <sa-skeleton-rectangle
4346
+ [width]="subSubItem.width"
4347
+ [height]="subSubItem.height"
4348
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4349
+ ></sa-skeleton-rectangle>
4350
+ }
4351
+ @case ('elliptical') {
4352
+ <sa-skeleton-elliptical
4353
+ [width]="subSubItem.width"
4354
+ [height]="subSubItem.height"
4355
+ [darkMode]="darkMode ?? config?.darkMode ?? subSubItem.darkMode"
4356
+ ></sa-skeleton-elliptical>
4357
+ }
4358
+ }
4359
+ }
4360
+ </sa-skeleton-container>
4361
+ }
4362
+ }
4363
+ }
4364
+ </sa-skeleton-container>
4365
+ }
4366
+ }
4367
+ }
4368
+ </sa-skeleton-container>
4369
+ `
4370
+ }]
4371
+ }], propDecorators: { preset: [{
4372
+ type: Input
4373
+ }], config: [{
4374
+ type: Input
4375
+ }], darkMode: [{
4376
+ type: Input
4377
+ }] } });
4378
+
4379
+ class SAMenuComponent {
4380
+ constructor(overlay) {
4381
+ this.overlay = overlay;
4382
+ this.position = 'bottom'; // Default position
4383
+ this.onEvent = new EventEmitter();
4384
+ this.onKeyUpEvent = new EventEmitter();
4385
+ this.closeEvent = new EventEmitter();
4386
+ // @ViewChild('menu', {static: true}) menu;
4387
+ this.isExpanded = false;
4388
+ this.activeTabIndex = 0; // Track the active tab index
4389
+ }
4390
+ ngOnChanges(changes) {
4391
+ if (changes['menu'] && changes['menu'].currentValue) {
4392
+ console.log('Menu component detected changes:', changes['menu'].currentValue);
4393
+ // Reset active tab index if tabs have changed
4394
+ if (this.menu?.tabs?.length && this.activeTabIndex >= this.menu.tabs.length) {
4395
+ this.activeTabIndex = 0;
4396
+ }
4397
+ // Prevent the menu from closing by stopping propagation of any events
4398
+ // that might trigger menu closing during this update cycle
4399
+ setTimeout(() => {
4400
+ // This ensures the menu stays open after the change detection cycle completes
4401
+ console.log('Menu update complete, menu should remain open');
4402
+ }, 0);
4403
+ }
4404
+ }
4405
+ ngAfterViewInit() {
4406
+ this.isExpanded = true;
4407
+ }
4408
+ setPosition() {
4409
+ // const positions: { [key: string]: ConnectedPosition } = {
4410
+ // left: { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' },
4411
+ // right: { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'top' },
4412
+ // top: { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top' },
4413
+ // bottom: { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom' }
4414
+ // };
4415
+ // const overlayRef = this.overlay.create();
4416
+ // const userProfilePortal = new ComponentPortal(CardComponent);
4417
+ // const compRef = overlayRef.attach(userProfilePortal);
4418
+ // compRef.instance.title = 'need nduk ra bhai'
4419
+ // compRef.instance.body = 'sometime little bit this sometimes little bit that. Comming not comming'
4420
+ // compRef.instance.avatar = '../assets/avatar.svg'
4421
+ }
4422
+ itemClicked(event) {
4423
+ this.onMenuItemClick(null, event.item);
4424
+ }
4425
+ onMenuItemClick(event, item) {
4426
+ // item.isSelected = !item.isSelected;
4427
+ this.onEvent.emit({ type: 'CLICK', item, menu: this.menu });
4428
+ // Close the menu after the item is clicked, just like the close button
4429
+ if (item.subMenu === null || item.subMenu === undefined) {
4430
+ this.closeEvent.emit(event);
4431
+ }
4432
+ }
4433
+ onSearch(event) {
4434
+ this.onEvent.emit({ type: 'SEARCH', value: event.target.value });
4435
+ }
4436
+ setActiveTab(index, tabname) {
4437
+ this.activeTabIndex = index; // Update the active tab index
4438
+ this.onEvent.emit({ type: 'TAB_CLICK', activeTab: tabname, menu: this.menu });
4439
+ }
4440
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SAMenuComponent, deps: [{ token: i1$4.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
4441
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: SAMenuComponent, isStandalone: true, selector: "sa-menu", inputs: { position: "position", menu: "menu", hostEl: "hostEl" }, outputs: { onEvent: "onEvent", onKeyUpEvent: "onKeyUpEvent", closeEvent: "closeEvent" }, providers: [IconService], usesOnChanges: true, ngImport: i0, template: "<div class=\"sa-menu\" [ngClass]=\"menu.showTray ? 'sa-menu-tray sa-round-border' : ''\"\r\n [ngStyle]=\"{width: menu.width || 'max-content'}\">\r\n @if(menu?.title){\r\n <div class=\"sa-menu-title\">\r\n <h1>{{menu?.title}}</h1>\r\n <sa-icon [icon]=\"'closeOutlined'\" [size]=\"'20'\" color=\"var(--grey-200, #D0D5DD)\" class=\"sa-menu-close-icon\"\r\n (click)=\"closeEvent.emit($event)\"></sa-icon>\r\n </div>\r\n }\r\n\r\n <!-- @if(menu?.itemGroups && menu.itemGroups.length){\r\n @for (groupItem of menu.itemGroups; track groupItem) {\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n \r\n @for (item of groupItem.items; track $index) {\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n }\r\n } @else if(menu?.items && menu.items.length){\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n } -->\r\n\r\n\r\n <!-- Tab Content or Item Groups -->\r\n <div class=\"sa-menu-content\">\r\n <div class=\"sa-menu-content-inner {{menu?.showSearch ? 'sa-menu-content-with-search' : ''}}\">\r\n @if(menu?.showSearch){\r\n <div class=\"search-container\">\r\n <sa-icon icon=\"search\"></sa-icon>\r\n <input name=\"menu-search-bar\" class=\"search-input\" (keyup)=\"onSearch($event)\" type=\"text\" [placeholder]=\"menu.searchPlaceholder\" \r\n />\r\n <button *ngIf=\"menu?.showAddIcon\"><i class=\"fas fa-plus\"></i></button>\r\n </div>\r\n }\r\n \r\n <!-- Tabs -->\r\n @if(menu?.tabs){\r\n <div class=\"sa-menu-tabs\">\r\n <button *ngFor=\"let tab of menu.tabs; let i = index\" [class.active]=\"i === activeTabIndex\"\r\n (click)=\"setActiveTab(i,tab.label)\">\r\n {{ tab.label }}\r\n <!-- ({{ tab.itemGroups.length }}) -->\r\n </button>\r\n </div>\r\n }\r\n <!-- Tabs End -->\r\n\r\n @if(menu?.tabs?.length){\r\n @if(menu?.loading && menu?.itemGroupsSkeletonConfig && !menu.tabs[activeTabIndex]?.itemGroups?.length){\r\n <sa-skeleton-loader [config]=\"menu.itemGroupsSkeletonConfig\"></sa-skeleton-loader>\r\n } @else if(menu.tabs[activeTabIndex]?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.tabs[activeTabIndex].itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n } @else if(menu?.loading && menu?.itemGroupsSkeletonConfig && !menu?.itemGroups?.length){\r\n <sa-skeleton-loader [config]=\"menu.itemGroupsSkeletonConfig\"></sa-skeleton-loader>\r\n } @else if(menu?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if(menu?.items && menu?.items?.length){\r\n <div *ngIf=\"menu?.user\" class=\"profile-badge\">\r\n <div class=\"avatar\">\r\n <sa-avatar [altText]=\"menu?.user?.altText\" [imagePath]=\"''\" [size]=\"'large'\"></sa-avatar>\r\n </div>\r\n <div class=\"profile-info\">\r\n <p class=\"profile-name\">{{menu?.user?.name}}</p>\r\n <p class=\"profile-email\">{{menu?.user?.email}}</p>\r\n </div>\r\n </div>\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (onEvent)=\"itemClicked($event)\"> </sa-menu-item>\r\n }\r\n </div>\r\n }\r\n\r\n</div>", styles: [".sa-menu{background-color:var(--primary-800);box-shadow:3px 4px 16px 4px #00000014;width:max-content;border-radius:5px;overflow-y:auto;max-height:100%}.sa-round-border{border-radius:8px}.sa-menu-tray{height:calc(100vh - 16px);margin-top:8px;border-top-left-radius:0;border-bottom-left-radius:0;background:var(--grey-700, #1D2939);padding:0 1rem 1rem;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.sa-menu-tray::-webkit-scrollbar{width:6px}.sa-menu-tray::-webkit-scrollbar-track{background:transparent}.sa-menu-tray::-webkit-scrollbar-thumb{background-color:#ffffff4d;border-radius:3px}sa-menu-item{cursor:pointer;display:block;color:var(--grey-100, #EAECF0)}.sa-menu-title{display:flex;justify-content:space-between;align-items:center;position:fixed;padding:1rem 0 .5rem;height:64px;width:calc(100% - 2rem);border-bottom:1px solid var(--primary-50, #F4EBFF);background:var(--grey-700, #1D2939);z-index:1}.sa-menu-title h1{color:var(--grey-100, #EAECF0);font-family:var(--font-family, Roboto);font-size:16px;font-style:normal;font-weight:400;line-height:24px;letter-spacing:.5px;margin-bottom:0;margin-top:0}.sa-menu-close-icon{cursor:pointer;margin-left:auto;height:20px}.search-container{position:relative;display:flex;align-items:center;margin-bottom:1rem;margin-top:4.75rem}.search-container input{flex:1;padding:.5rem .5rem .5rem 2rem;background-color:#4a5568;border-radius:.25rem;font-size:.875rem;border:none;outline:none;border-radius:4px;color:var(--grey-200, #D0D5DD);border:1px solid var(--grey-900, #0C111D);background:var(--grey-900, #0C111D);box-sizing:border-box}.search-container .search-icon{position:absolute;left:.5rem;font-size:1rem;color:#888;pointer-events:none}.search-container button{margin-left:.5rem;background-color:#6b46c1;padding:.5rem;border-radius:.25rem;border:none;cursor:pointer}.sa-menu-group{margin-bottom:1rem;padding-bottom:.8rem;border-bottom:1px solid var(--grey-400, #475467)}.sa-menu-group:last-child{border-bottom:none}.sa-menu-group h2{color:var(--grey-300, #D0D5DD);font-family:var(--font-family, Roboto);font-size:11px;font-style:normal;font-weight:400;line-height:16px;letter-spacing:.5px;text-transform:uppercase;margin-bottom:.5rem}.MenuBar{width:max-content;margin-top:8px;background-color:var(--grey-400);border-top-left-radius:0;border-bottom-left-radius:0;background-color:#2d3748;padding:0}.sa-menu-tabs{display:flex;border-bottom:1px solid #ccc;margin-bottom:1rem}.sa-menu-tabs button{flex:1;padding:.5rem 1rem;background:none;border:none;cursor:pointer;font-size:12px;font-style:normal;font-weight:400;line-height:16px;color:#888;border-bottom:2px solid transparent;transition:all .5s ease}.sa-menu-tabs button.active{color:#f7f3f3;border-bottom:2px solid #f7f7f7;font-size:12px;font-style:normal;font-weight:600;line-height:16px;letter-spacing:.5px}.sa-menu-content{padding:0rem 0}.sa-menu-content-inner{padding-top:0}.sa-menu-content .sa-menu-content-with-search,.sa-menu-content-with-search.sa-menu-content-inner{padding:0}.features-tray-menu .sa-menu-content-inner{padding-top:5rem}.features-tray-menu .sa-menu-content-with-search.sa-menu-content-inner{padding-top:0}.sa-menu-group h2{margin-top:1rem}.sa-menu-group:first-child h2{margin-top:0}.sa-menu-group{margin-bottom:1rem}.profile-badge{display:flex;align-items:center;gap:8px;padding:12px;width:100%;border-bottom:1px solid var(--grey-400)}.avatar{display:flex;justify-content:center;align-items:center}.profile-info{display:flex;flex-direction:column;justify-content:center;font-weight:300}.profile-name{color:var(--structural-white);font-weight:500;font-size:12px;line-height:1.2;margin:0}.profile-email{color:var(--grey-200);font-size:11px;line-height:1.2;font-weight:400;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SAMenuItemComponent, selector: "sa-menu-item", inputs: ["item", "showRound"], outputs: ["onEvent"] }, { kind: "ngmodule", type: HttpClientModule }, { kind: "component", type: IconComponent, selector: "sa-icon", inputs: ["img", "imgWidth", "imgHeight", "icon", "size", "color", "iconPath", "iconUrl", "customClass", "href", "hrefTarget", "iconPosition"], outputs: ["onClickEvent"] }, { kind: "component", type: AvatarComponent, selector: "sa-avatar", inputs: ["id", "imagePath", "altText", "size"], outputs: ["onClickEvent", "onMouseInEvent", "onMouseOutEvent"] }, { kind: "component", type: SkeletonLoaderComponent, selector: "sa-skeleton-loader", inputs: ["preset", "config", "darkMode"] }] }); }
4442
+ }
4443
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SAMenuComponent, decorators: [{
4444
+ type: Component,
4445
+ args: [{ selector: 'sa-menu', standalone: true, imports: [
4446
+ CommonModule,
4447
+ SAMenuItemComponent,
4448
+ MatMenu,
4449
+ MatMenuItem,
4450
+ ChipsComponent,
4451
+ HttpClientModule,
4452
+ IconComponent,
4453
+ AvatarComponent,
4454
+ SkeletonLoaderComponent,
4455
+ ], providers: [IconService], template: "<div class=\"sa-menu\" [ngClass]=\"menu.showTray ? 'sa-menu-tray sa-round-border' : ''\"\r\n [ngStyle]=\"{width: menu.width || 'max-content'}\">\r\n @if(menu?.title){\r\n <div class=\"sa-menu-title\">\r\n <h1>{{menu?.title}}</h1>\r\n <sa-icon [icon]=\"'closeOutlined'\" [size]=\"'20'\" color=\"var(--grey-200, #D0D5DD)\" class=\"sa-menu-close-icon\"\r\n (click)=\"closeEvent.emit($event)\"></sa-icon>\r\n </div>\r\n }\r\n\r\n <!-- @if(menu?.itemGroups && menu.itemGroups.length){\r\n @for (groupItem of menu.itemGroups; track groupItem) {\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n \r\n @for (item of groupItem.items; track $index) {\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n }\r\n } @else if(menu?.items && menu.items.length){\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n }\r\n </div>\r\n } -->\r\n\r\n\r\n <!-- Tab Content or Item Groups -->\r\n <div class=\"sa-menu-content\">\r\n <div class=\"sa-menu-content-inner {{menu?.showSearch ? 'sa-menu-content-with-search' : ''}}\">\r\n @if(menu?.showSearch){\r\n <div class=\"search-container\">\r\n <sa-icon icon=\"search\"></sa-icon>\r\n <input name=\"menu-search-bar\" class=\"search-input\" (keyup)=\"onSearch($event)\" type=\"text\" [placeholder]=\"menu.searchPlaceholder\" \r\n />\r\n <button *ngIf=\"menu?.showAddIcon\"><i class=\"fas fa-plus\"></i></button>\r\n </div>\r\n }\r\n \r\n <!-- Tabs -->\r\n @if(menu?.tabs){\r\n <div class=\"sa-menu-tabs\">\r\n <button *ngFor=\"let tab of menu.tabs; let i = index\" [class.active]=\"i === activeTabIndex\"\r\n (click)=\"setActiveTab(i,tab.label)\">\r\n {{ tab.label }}\r\n <!-- ({{ tab.itemGroups.length }}) -->\r\n </button>\r\n </div>\r\n }\r\n <!-- Tabs End -->\r\n\r\n @if(menu?.tabs?.length){\r\n @if(menu?.loading && menu?.itemGroupsSkeletonConfig && !menu.tabs[activeTabIndex]?.itemGroups?.length){\r\n <sa-skeleton-loader [config]=\"menu.itemGroupsSkeletonConfig\"></sa-skeleton-loader>\r\n } @else if(menu.tabs[activeTabIndex]?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.tabs[activeTabIndex].itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n } @else if(menu?.loading && menu?.itemGroupsSkeletonConfig && !menu?.itemGroups?.length){\r\n <sa-skeleton-loader [config]=\"menu.itemGroupsSkeletonConfig\"></sa-skeleton-loader>\r\n } @else if(menu?.itemGroups?.length){\r\n <ng-container *ngFor=\"let groupItem of menu.itemGroups\">\r\n <div class=\"sa-menu-group\">\r\n <h2>{{groupItem.groupTitle}}</h2>\r\n <ng-container *ngFor=\"let item of groupItem.items\">\r\n <sa-menu-item [item]=\"item\" [showRound]=\"menu.showTray\"\r\n (click)=\"onMenuItemClick($event, item)\"></sa-menu-item>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if(menu?.items && menu?.items?.length){\r\n <div *ngIf=\"menu?.user\" class=\"profile-badge\">\r\n <div class=\"avatar\">\r\n <sa-avatar [altText]=\"menu?.user?.altText\" [imagePath]=\"''\" [size]=\"'large'\"></sa-avatar>\r\n </div>\r\n <div class=\"profile-info\">\r\n <p class=\"profile-name\">{{menu?.user?.name}}</p>\r\n <p class=\"profile-email\">{{menu?.user?.email}}</p>\r\n </div>\r\n </div>\r\n <div class=\"sa-menu-items\">\r\n @for (item of menu.items; track item) {\r\n <sa-menu-item [item]=\"item\" (onEvent)=\"itemClicked($event)\"> </sa-menu-item>\r\n }\r\n </div>\r\n }\r\n\r\n</div>", styles: [".sa-menu{background-color:var(--primary-800);box-shadow:3px 4px 16px 4px #00000014;width:max-content;border-radius:5px;overflow-y:auto;max-height:100%}.sa-round-border{border-radius:8px}.sa-menu-tray{height:calc(100vh - 16px);margin-top:8px;border-top-left-radius:0;border-bottom-left-radius:0;background:var(--grey-700, #1D2939);padding:0 1rem 1rem;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.sa-menu-tray::-webkit-scrollbar{width:6px}.sa-menu-tray::-webkit-scrollbar-track{background:transparent}.sa-menu-tray::-webkit-scrollbar-thumb{background-color:#ffffff4d;border-radius:3px}sa-menu-item{cursor:pointer;display:block;color:var(--grey-100, #EAECF0)}.sa-menu-title{display:flex;justify-content:space-between;align-items:center;position:fixed;padding:1rem 0 .5rem;height:64px;width:calc(100% - 2rem);border-bottom:1px solid var(--primary-50, #F4EBFF);background:var(--grey-700, #1D2939);z-index:1}.sa-menu-title h1{color:var(--grey-100, #EAECF0);font-family:var(--font-family, Roboto);font-size:16px;font-style:normal;font-weight:400;line-height:24px;letter-spacing:.5px;margin-bottom:0;margin-top:0}.sa-menu-close-icon{cursor:pointer;margin-left:auto;height:20px}.search-container{position:relative;display:flex;align-items:center;margin-bottom:1rem;margin-top:4.75rem}.search-container input{flex:1;padding:.5rem .5rem .5rem 2rem;background-color:#4a5568;border-radius:.25rem;font-size:.875rem;border:none;outline:none;border-radius:4px;color:var(--grey-200, #D0D5DD);border:1px solid var(--grey-900, #0C111D);background:var(--grey-900, #0C111D);box-sizing:border-box}.search-container .search-icon{position:absolute;left:.5rem;font-size:1rem;color:#888;pointer-events:none}.search-container button{margin-left:.5rem;background-color:#6b46c1;padding:.5rem;border-radius:.25rem;border:none;cursor:pointer}.sa-menu-group{margin-bottom:1rem;padding-bottom:.8rem;border-bottom:1px solid var(--grey-400, #475467)}.sa-menu-group:last-child{border-bottom:none}.sa-menu-group h2{color:var(--grey-300, #D0D5DD);font-family:var(--font-family, Roboto);font-size:11px;font-style:normal;font-weight:400;line-height:16px;letter-spacing:.5px;text-transform:uppercase;margin-bottom:.5rem}.MenuBar{width:max-content;margin-top:8px;background-color:var(--grey-400);border-top-left-radius:0;border-bottom-left-radius:0;background-color:#2d3748;padding:0}.sa-menu-tabs{display:flex;border-bottom:1px solid #ccc;margin-bottom:1rem}.sa-menu-tabs button{flex:1;padding:.5rem 1rem;background:none;border:none;cursor:pointer;font-size:12px;font-style:normal;font-weight:400;line-height:16px;color:#888;border-bottom:2px solid transparent;transition:all .5s ease}.sa-menu-tabs button.active{color:#f7f3f3;border-bottom:2px solid #f7f7f7;font-size:12px;font-style:normal;font-weight:600;line-height:16px;letter-spacing:.5px}.sa-menu-content{padding:0rem 0}.sa-menu-content-inner{padding-top:0}.sa-menu-content .sa-menu-content-with-search,.sa-menu-content-with-search.sa-menu-content-inner{padding:0}.features-tray-menu .sa-menu-content-inner{padding-top:5rem}.features-tray-menu .sa-menu-content-with-search.sa-menu-content-inner{padding-top:0}.sa-menu-group h2{margin-top:1rem}.sa-menu-group:first-child h2{margin-top:0}.sa-menu-group{margin-bottom:1rem}.profile-badge{display:flex;align-items:center;gap:8px;padding:12px;width:100%;border-bottom:1px solid var(--grey-400)}.avatar{display:flex;justify-content:center;align-items:center}.profile-info{display:flex;flex-direction:column;justify-content:center;font-weight:300}.profile-name{color:var(--structural-white);font-weight:500;font-size:12px;line-height:1.2;margin:0}.profile-email{color:var(--grey-200);font-size:11px;line-height:1.2;font-weight:400;margin:0}\n"] }]
4456
+ }], ctorParameters: () => [{ type: i1$4.Overlay }], propDecorators: { position: [{
4457
+ type: Input
4458
+ }], menu: [{
4459
+ type: Input
4460
+ }], hostEl: [{
4461
+ type: Input
4462
+ }], onEvent: [{
4463
+ type: Output
4464
+ }], onKeyUpEvent: [{
4465
+ type: Output
4466
+ }], closeEvent: [{
4467
+ type: Output
4468
+ }] } });
4469
+
4470
+ class MenuDirective {
4471
+ get saMenu() {
4472
+ return this._saMenu;
4473
+ }
4474
+ set saMenu(value) {
4475
+ this._saMenu = value;
4476
+ // Emit the new configuration to the stream
4477
+ this.menuConfig$.next(value);
4478
+ }
4479
+ get position() {
4480
+ return this._position;
4481
+ }
4482
+ set position(value) {
4483
+ this._position = value;
4484
+ }
4485
+ constructor(overlay, overlayContainer, elRef) {
4486
+ this.overlay = overlay;
4035
4487
  this.overlayContainer = overlayContainer;
4036
4488
  this.elRef = elRef;
4037
4489
  // Stream to track menu configuration changes
@@ -6333,462 +6785,52 @@ class ScrollingCardsComponent {
6333
6785
  return;
6334
6786
  const container = this.cardContainer.nativeElement;
6335
6787
  this.isVertical = this.direction === 'up' || this.direction === 'down';
6336
- // Set vertical/horizontal classes
6337
- container.classList.toggle('vertical', this.isVertical);
6338
- container.classList.toggle('horizontal', !this.isVertical);
6339
- const containerSize = this.isVertical ? container.scrollHeight : container.scrollWidth;
6340
- const duration = containerSize / this.duration;
6341
- container.style.setProperty('--scroll-duration', `${duration}s`);
6342
- container.style.setProperty('--scroll-direction', this.direction === 'down' || this.direction === 'right' ? 'reverse' : 'normal');
6343
- // Reset animation
6344
- container.style.animation = 'none';
6345
- container.offsetHeight; // Trigger reflow
6346
- container.style.animation = null;
6347
- this.cdr.markForCheck();
6348
- }
6349
- pauseScroll() {
6350
- if (!this.cardContainer?.nativeElement)
6351
- return;
6352
- this.animationPaused = true;
6353
- this.cardContainer.nativeElement.style.animationPlayState = 'paused';
6354
- }
6355
- resumeScroll() {
6356
- if (!this.cardContainer?.nativeElement)
6357
- return;
6358
- this.animationPaused = false;
6359
- this.cardContainer.nativeElement.style.animationPlayState = 'running';
6360
- }
6361
- ngOnDestroy() {
6362
- if (this.animationFrame) {
6363
- cancelAnimationFrame(this.animationFrame);
6364
- }
6365
- }
6366
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ScrollingCardsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6367
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: ScrollingCardsComponent, isStandalone: true, selector: "sa-scrolling-cards", inputs: { cards: "cards", duration: "duration", direction: "direction" }, providers: [IconService], viewQueries: [{ propertyName: "cardContainer", first: true, predicate: ["cardContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"scrolling-cards-container {{this.isVertical ? 'vertical': 'horizontal'}}\" (mouseenter)=\"pauseScroll()\"\r\n (mouseleave)=\"resumeScroll()\">\r\n <div #cardContainer class=\"card-container\">\r\n @for (card of displayCards; track card.title) {\r\n <sa-card [title]=\"card.title\" [body]=\"card.body\" [avatar]=\"card?.avatar\" [icon]=\"card.icon\" [iconSize]=\"'54'\"\r\n [customWrapperClass]=\"'sa-card-secondary-wrapper'\" [width]=\"'24.063rem'\" [column]=\"false\"\r\n [showCardBody]=\"true\">\r\n </sa-card>\r\n }\r\n </div>\r\n</div>", styles: [".scrolling-cards-container{overflow:hidden;width:fit-content}.scrolling-cards-container.vertical{height:100%;position:relative}.scrolling-cards-container.vertical:before,.scrolling-cards-container.vertical:after{content:\"\";position:absolute;width:100%;height:var(--medium-36px);z-index:1}.scrolling-cards-container.vertical:before{background:#fbfaff;background:-moz-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.scrolling-cards-container.vertical:after{bottom:0;background:#fbfaff;background:-moz-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.card-container{display:flex;gap:var(--small-16px);animation-duration:var(--scroll-duration, 30s);animation-timing-function:linear;animation-iteration-count:infinite;animation-direction:var(--scroll-direction, normal);width:fit-content}.card-container.horizontal{flex-direction:row;animation-name:scroll-horizontal}@keyframes scroll-vertical{0%{transform:translateY(0)}to{transform:translateY(calc(-50% - var(--small-16px)))}}@keyframes scroll-horizontal{0%{transform:translate(0)}to{transform:translate(calc(-50% - var(--small-16px)))}}sa-card{flex-shrink:0}.card-container.vertical{flex-direction:column;animation-name:scroll-vertical}@keyframes scroll-continuous{0%{transform:translate(100%)}to{transform:translate(-100%)}}\n"], dependencies: [{ kind: "ngmodule", type: HttpClientModule }, { kind: "component", type: CardComponent, selector: "sa-card", inputs: ["title", "showCardHeader", "showCardBody", "showHeaderBodyDivider", "showCustomCardBody", "customWrapperClass", "chip", "body", "avatar", "image", "imageWidth", "avatarSize", "href", "hrefTarget", "icon", "iconSize", "subtitle", "logoIcon", "width", "height", "column"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6368
- }
6369
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ScrollingCardsComponent, decorators: [{
6370
- type: Component,
6371
- args: [{ selector: 'sa-scrolling-cards', standalone: true, imports: [HttpClientModule, CardComponent], providers: [IconService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"scrolling-cards-container {{this.isVertical ? 'vertical': 'horizontal'}}\" (mouseenter)=\"pauseScroll()\"\r\n (mouseleave)=\"resumeScroll()\">\r\n <div #cardContainer class=\"card-container\">\r\n @for (card of displayCards; track card.title) {\r\n <sa-card [title]=\"card.title\" [body]=\"card.body\" [avatar]=\"card?.avatar\" [icon]=\"card.icon\" [iconSize]=\"'54'\"\r\n [customWrapperClass]=\"'sa-card-secondary-wrapper'\" [width]=\"'24.063rem'\" [column]=\"false\"\r\n [showCardBody]=\"true\">\r\n </sa-card>\r\n }\r\n </div>\r\n</div>", styles: [".scrolling-cards-container{overflow:hidden;width:fit-content}.scrolling-cards-container.vertical{height:100%;position:relative}.scrolling-cards-container.vertical:before,.scrolling-cards-container.vertical:after{content:\"\";position:absolute;width:100%;height:var(--medium-36px);z-index:1}.scrolling-cards-container.vertical:before{background:#fbfaff;background:-moz-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.scrolling-cards-container.vertical:after{bottom:0;background:#fbfaff;background:-moz-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.card-container{display:flex;gap:var(--small-16px);animation-duration:var(--scroll-duration, 30s);animation-timing-function:linear;animation-iteration-count:infinite;animation-direction:var(--scroll-direction, normal);width:fit-content}.card-container.horizontal{flex-direction:row;animation-name:scroll-horizontal}@keyframes scroll-vertical{0%{transform:translateY(0)}to{transform:translateY(calc(-50% - var(--small-16px)))}}@keyframes scroll-horizontal{0%{transform:translate(0)}to{transform:translate(calc(-50% - var(--small-16px)))}}sa-card{flex-shrink:0}.card-container.vertical{flex-direction:column;animation-name:scroll-vertical}@keyframes scroll-continuous{0%{transform:translate(100%)}to{transform:translate(-100%)}}\n"] }]
6372
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { cards: [{
6373
- type: Input,
6374
- args: [{ required: true }]
6375
- }], duration: [{
6376
- type: Input
6377
- }], direction: [{
6378
- type: Input
6379
- }], cardContainer: [{
6380
- type: ViewChild,
6381
- args: ['cardContainer']
6382
- }] } });
6383
-
6384
- class SkeletonBaseComponent {
6385
- constructor() {
6386
- this.width = '100%';
6387
- this.height = '1rem';
6388
- }
6389
- get getWidth() {
6390
- return this.width;
6391
- }
6392
- get getHeight() {
6393
- return this.height;
6394
- }
6395
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6396
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonBaseComponent, isStandalone: true, selector: "sa-skeleton-base", inputs: { width: "width", height: "height" }, host: { properties: { "style.width": "this.getWidth", "style.height": "this.getHeight" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{display:block;position:relative;overflow:hidden;background:var(--sa-skeleton-background, #e9ecef);border-radius:var(--sa-skeleton-radius, 4px)}:host:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,var(--sa-skeleton-shine, rgba(255, 255, 255, .3)),transparent);animation:shimmer var(--sa-skeleton-animation-duration, 1.5s) infinite}@keyframes shimmer{to{transform:translate(100%)}}\n"] }); }
6397
- }
6398
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonBaseComponent, decorators: [{
6399
- type: Component,
6400
- args: [{ selector: 'sa-skeleton-base', standalone: true, template: `<ng-content></ng-content>`, styles: [":host{display:block;position:relative;overflow:hidden;background:var(--sa-skeleton-background, #e9ecef);border-radius:var(--sa-skeleton-radius, 4px)}:host:after{content:\"\";position:absolute;inset:0;transform:translate(-100%);background:linear-gradient(90deg,transparent,var(--sa-skeleton-shine, rgba(255, 255, 255, .3)),transparent);animation:shimmer var(--sa-skeleton-animation-duration, 1.5s) infinite}@keyframes shimmer{to{transform:translate(100%)}}\n"] }]
6401
- }], propDecorators: { width: [{
6402
- type: Input
6403
- }], height: [{
6404
- type: Input
6405
- }], getWidth: [{
6406
- type: HostBinding,
6407
- args: ['style.width']
6408
- }], getHeight: [{
6409
- type: HostBinding,
6410
- args: ['style.height']
6411
- }] } });
6412
-
6413
- class SkeletonContainerComponent {
6414
- constructor() {
6415
- this.direction = 'column';
6416
- }
6417
- get containerStyles() {
6418
- return {
6419
- gap: this.gap,
6420
- padding: this.padding,
6421
- flexDirection: this.direction
6422
- };
6423
- }
6424
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6425
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonContainerComponent, isStandalone: true, selector: "sa-skeleton-container", inputs: { gap: "gap", padding: "padding", direction: "direction" }, ngImport: i0, template: `
6426
- <div class="skeleton-container" [ngStyle]="containerStyles">
6427
- <ng-content></ng-content>
6428
- </div>
6429
- `, isInline: true, styles: [".skeleton-container{display:flex;flex-direction:column;gap:var(--sa-skeleton-gap, 1rem);padding:var(--sa-skeleton-padding, 1rem)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
6430
- }
6431
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonContainerComponent, decorators: [{
6432
- type: Component,
6433
- args: [{ selector: 'sa-skeleton-container', standalone: true, imports: [NgStyle], template: `
6434
- <div class="skeleton-container" [ngStyle]="containerStyles">
6435
- <ng-content></ng-content>
6436
- </div>
6437
- `, styles: [".skeleton-container{display:flex;flex-direction:column;gap:var(--sa-skeleton-gap, 1rem);padding:var(--sa-skeleton-padding, 1rem)}\n"] }]
6438
- }], propDecorators: { gap: [{
6439
- type: Input
6440
- }], padding: [{
6441
- type: Input
6442
- }], direction: [{
6443
- type: Input
6444
- }] } });
6445
-
6446
- class SkeletonTextComponent {
6447
- constructor() {
6448
- this.width = '100%';
6449
- this.height = '1rem';
6450
- }
6451
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6452
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonTextComponent, isStandalone: true, selector: "sa-skeleton-text", inputs: { width: "width", height: "height" }, ngImport: i0, template: `<sa-skeleton-base [width]="width" [height]="height"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height"] }] }); }
6453
- }
6454
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonTextComponent, decorators: [{
6455
- type: Component,
6456
- args: [{
6457
- selector: 'sa-skeleton-text',
6458
- standalone: true,
6459
- imports: [SkeletonBaseComponent],
6460
- template: `<sa-skeleton-base [width]="width" [height]="height"></sa-skeleton-base>`,
6461
- }]
6462
- }], propDecorators: { width: [{
6463
- type: Input
6464
- }], height: [{
6465
- type: Input
6466
- }] } });
6467
- class SkeletonCircleComponent {
6468
- constructor() {
6469
- this.size = '3rem';
6470
- }
6471
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonCircleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6472
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonCircleComponent, isStandalone: true, selector: "sa-skeleton-circle", inputs: { size: "size" }, ngImport: i0, template: `<sa-skeleton-base [width]="size" [height]="size" style="border-radius: 50%"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height"] }] }); }
6473
- }
6474
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonCircleComponent, decorators: [{
6475
- type: Component,
6476
- args: [{
6477
- selector: 'sa-skeleton-circle',
6478
- standalone: true,
6479
- imports: [SkeletonBaseComponent],
6480
- template: `<sa-skeleton-base [width]="size" [height]="size" style="border-radius: 50%"></sa-skeleton-base>`,
6481
- }]
6482
- }], propDecorators: { size: [{
6483
- type: Input
6484
- }] } });
6485
- class SkeletonRectangleComponent {
6486
- constructor() {
6487
- this.width = '100%';
6488
- this.height = '100px';
6489
- }
6490
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonRectangleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6491
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonRectangleComponent, isStandalone: true, selector: "sa-skeleton-rectangle", inputs: { width: "width", height: "height" }, ngImport: i0, template: `<sa-skeleton-base [width]="width" [height]="height"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height"] }] }); }
6492
- }
6493
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonRectangleComponent, decorators: [{
6494
- type: Component,
6495
- args: [{
6496
- selector: 'sa-skeleton-rectangle',
6497
- standalone: true,
6498
- imports: [SkeletonBaseComponent],
6499
- template: `<sa-skeleton-base [width]="width" [height]="height"></sa-skeleton-base>`,
6500
- }]
6501
- }], propDecorators: { width: [{
6502
- type: Input
6503
- }], height: [{
6504
- type: Input
6505
- }] } });
6506
- class SkeletonEllipticalComponent {
6507
- constructor() {
6508
- this.width = '200px';
6509
- this.height = '48px';
6510
- }
6511
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonEllipticalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6512
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: SkeletonEllipticalComponent, isStandalone: true, selector: "sa-skeleton-elliptical", inputs: { width: "width", height: "height" }, ngImport: i0, template: `<sa-skeleton-base [width]="width" [height]="height" style="border-radius: 100px;"></sa-skeleton-base>`, isInline: true, dependencies: [{ kind: "component", type: SkeletonBaseComponent, selector: "sa-skeleton-base", inputs: ["width", "height"] }] }); }
6513
- }
6514
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonEllipticalComponent, decorators: [{
6515
- type: Component,
6516
- args: [{
6517
- selector: 'sa-skeleton-elliptical',
6518
- standalone: true,
6519
- imports: [SkeletonBaseComponent],
6520
- template: `<sa-skeleton-base [width]="width" [height]="height" style="border-radius: 100px;"></sa-skeleton-base>`,
6521
- }]
6522
- }], propDecorators: { width: [{
6523
- type: Input
6524
- }], height: [{
6525
- type: Input
6526
- }] } });
6527
-
6528
- const SKELETON_PRESETS = {
6529
- // Preset for a card with title, subtitle and content
6530
- card: {
6531
- items: [
6532
- { type: 'text', width: '60%', height: '1.5rem' },
6533
- { type: 'text', width: '40%', height: '1rem' },
6534
- { type: 'rectangle', height: '100px' }
6535
- ],
6536
- containerConfig: {
6537
- padding: '1rem',
6538
- gap: '0.75rem'
6539
- }
6540
- },
6541
- // Preset for a list item with avatar
6542
- listItem: {
6543
- items: [
6544
- { type: 'circle', size: '2.5rem' },
6545
- { type: 'text', width: '70%', height: '1rem' }
6546
- ],
6547
- containerConfig: {
6548
- direction: 'row',
6549
- gap: '1rem',
6550
- padding: '0.5rem'
6551
- }
6552
- },
6553
- // Preset for form fields
6554
- formField: {
6555
- items: [
6556
- { type: 'text', width: '30%', height: '1rem' },
6557
- { type: 'rectangle', height: '2.5rem' }
6558
- ],
6559
- containerConfig: {
6560
- gap: '0.5rem'
6561
- }
6788
+ // Set vertical/horizontal classes
6789
+ container.classList.toggle('vertical', this.isVertical);
6790
+ container.classList.toggle('horizontal', !this.isVertical);
6791
+ const containerSize = this.isVertical ? container.scrollHeight : container.scrollWidth;
6792
+ const duration = containerSize / this.duration;
6793
+ container.style.setProperty('--scroll-duration', `${duration}s`);
6794
+ container.style.setProperty('--scroll-direction', this.direction === 'down' || this.direction === 'right' ? 'reverse' : 'normal');
6795
+ // Reset animation
6796
+ container.style.animation = 'none';
6797
+ container.offsetHeight; // Trigger reflow
6798
+ container.style.animation = null;
6799
+ this.cdr.markForCheck();
6562
6800
  }
6563
- };
6564
-
6565
- class SkeletonLoaderComponent {
6566
- ngOnInit() {
6567
- this.updateConfig();
6801
+ pauseScroll() {
6802
+ if (!this.cardContainer?.nativeElement)
6803
+ return;
6804
+ this.animationPaused = true;
6805
+ this.cardContainer.nativeElement.style.animationPlayState = 'paused';
6568
6806
  }
6569
- ngOnChanges(changes) {
6570
- this.updateConfig();
6807
+ resumeScroll() {
6808
+ if (!this.cardContainer?.nativeElement)
6809
+ return;
6810
+ this.animationPaused = false;
6811
+ this.cardContainer.nativeElement.style.animationPlayState = 'running';
6571
6812
  }
6572
- updateConfig() {
6573
- if (this.preset && (!this.config || !this.config.items?.length)) {
6574
- this.config = SKELETON_PRESETS[this.preset];
6813
+ ngOnDestroy() {
6814
+ if (this.animationFrame) {
6815
+ cancelAnimationFrame(this.animationFrame);
6575
6816
  }
6576
6817
  }
6577
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6578
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: SkeletonLoaderComponent, isStandalone: true, selector: "sa-skeleton-loader", inputs: { preset: "preset", config: "config" }, usesOnChanges: true, ngImport: i0, template: `
6579
- <sa-skeleton-container
6580
- [gap]="config?.containerConfig?.gap"
6581
- [padding]="config?.containerConfig?.padding"
6582
- [direction]="config?.containerConfig?.direction || 'column'"
6583
- >
6584
- @for (item of config?.items; track $index) {
6585
- @switch (item.type) {
6586
- @case ('text') {
6587
- <sa-skeleton-text
6588
- [width]="item.width"
6589
- [height]="item.height"
6590
- ></sa-skeleton-text>
6591
- }
6592
- @case ('circle') {
6593
- <sa-skeleton-circle
6594
- [size]="item.size"
6595
- ></sa-skeleton-circle>
6596
- }
6597
- @case ('rectangle') {
6598
- <sa-skeleton-rectangle
6599
- [width]="item.width"
6600
- [height]="item.height"
6601
- ></sa-skeleton-rectangle>
6602
- }
6603
- @case ('elliptical') {
6604
- <sa-skeleton-elliptical
6605
- [width]="item.width"
6606
- [height]="item.height"
6607
- ></sa-skeleton-elliptical>
6608
- }
6609
- @case ('container') {
6610
- <sa-skeleton-container [direction]="item.direction" [gap]="item.gap">
6611
- @for (subItem of item.items; track $index) {
6612
- @switch (subItem.type) {
6613
- @case ('text') {
6614
- <sa-skeleton-text
6615
- [width]="subItem.width"
6616
- [height]="subItem.height"
6617
- ></sa-skeleton-text>
6618
- }
6619
- @case ('circle') {
6620
- <sa-skeleton-circle
6621
- [size]="subItem.size"
6622
- ></sa-skeleton-circle>
6623
- }
6624
- @case ('rectangle') {
6625
- <sa-skeleton-rectangle
6626
- [width]="subItem.width"
6627
- [height]="subItem.height"
6628
- ></sa-skeleton-rectangle>
6629
- }
6630
- @case ('elliptical') {
6631
- <sa-skeleton-elliptical
6632
- [width]="subItem.width"
6633
- [height]="subItem.height"
6634
- ></sa-skeleton-elliptical>
6635
- }
6636
- @case ('container') {
6637
- <sa-skeleton-container [direction]="subItem.direction" [gap]="subItem.gap">
6638
- @for (subSubItem of subItem.items; track $index) {
6639
- @switch (subSubItem.type) {
6640
- @case ('text') {
6641
- <sa-skeleton-text
6642
- [width]="subSubItem.width"
6643
- [height]="subSubItem.height"
6644
- ></sa-skeleton-text>
6645
- }
6646
- @case ('circle') {
6647
- <sa-skeleton-circle
6648
- [size]="subSubItem.size"
6649
- ></sa-skeleton-circle>
6650
- }
6651
- @case ('rectangle') {
6652
- <sa-skeleton-rectangle
6653
- [width]="subSubItem.width"
6654
- [height]="subSubItem.height"
6655
- ></sa-skeleton-rectangle>
6656
- }
6657
- @case ('elliptical') {
6658
- <sa-skeleton-elliptical
6659
- [width]="subSubItem.width"
6660
- [height]="subSubItem.height"
6661
- ></sa-skeleton-elliptical>
6662
- }
6663
- }
6664
- }
6665
- </sa-skeleton-container>
6666
- }
6667
- }
6668
- }
6669
- </sa-skeleton-container>
6670
- }
6671
- }
6672
- }
6673
- </sa-skeleton-container>
6674
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SkeletonTextComponent, selector: "sa-skeleton-text", inputs: ["width", "height"] }, { kind: "component", type: SkeletonCircleComponent, selector: "sa-skeleton-circle", inputs: ["size"] }, { kind: "component", type: SkeletonRectangleComponent, selector: "sa-skeleton-rectangle", inputs: ["width", "height"] }, { kind: "component", type: SkeletonEllipticalComponent, selector: "sa-skeleton-elliptical", inputs: ["width", "height"] }, { kind: "component", type: SkeletonContainerComponent, selector: "sa-skeleton-container", inputs: ["gap", "padding", "direction"] }] }); }
6818
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ScrollingCardsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6819
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.4", type: ScrollingCardsComponent, isStandalone: true, selector: "sa-scrolling-cards", inputs: { cards: "cards", duration: "duration", direction: "direction" }, providers: [IconService], viewQueries: [{ propertyName: "cardContainer", first: true, predicate: ["cardContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"scrolling-cards-container {{this.isVertical ? 'vertical': 'horizontal'}}\" (mouseenter)=\"pauseScroll()\"\r\n (mouseleave)=\"resumeScroll()\">\r\n <div #cardContainer class=\"card-container\">\r\n @for (card of displayCards; track card.title) {\r\n <sa-card [title]=\"card.title\" [body]=\"card.body\" [avatar]=\"card?.avatar\" [icon]=\"card.icon\" [iconSize]=\"'54'\"\r\n [customWrapperClass]=\"'sa-card-secondary-wrapper'\" [width]=\"'24.063rem'\" [column]=\"false\"\r\n [showCardBody]=\"true\">\r\n </sa-card>\r\n }\r\n </div>\r\n</div>", styles: [".scrolling-cards-container{overflow:hidden;width:fit-content}.scrolling-cards-container.vertical{height:100%;position:relative}.scrolling-cards-container.vertical:before,.scrolling-cards-container.vertical:after{content:\"\";position:absolute;width:100%;height:var(--medium-36px);z-index:1}.scrolling-cards-container.vertical:before{background:#fbfaff;background:-moz-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.scrolling-cards-container.vertical:after{bottom:0;background:#fbfaff;background:-moz-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.card-container{display:flex;gap:var(--small-16px);animation-duration:var(--scroll-duration, 30s);animation-timing-function:linear;animation-iteration-count:infinite;animation-direction:var(--scroll-direction, normal);width:fit-content}.card-container.horizontal{flex-direction:row;animation-name:scroll-horizontal}@keyframes scroll-vertical{0%{transform:translateY(0)}to{transform:translateY(calc(-50% - var(--small-16px)))}}@keyframes scroll-horizontal{0%{transform:translate(0)}to{transform:translate(calc(-50% - var(--small-16px)))}}sa-card{flex-shrink:0}.card-container.vertical{flex-direction:column;animation-name:scroll-vertical}@keyframes scroll-continuous{0%{transform:translate(100%)}to{transform:translate(-100%)}}\n"], dependencies: [{ kind: "ngmodule", type: HttpClientModule }, { kind: "component", type: CardComponent, selector: "sa-card", inputs: ["title", "showCardHeader", "showCardBody", "showHeaderBodyDivider", "showCustomCardBody", "customWrapperClass", "chip", "body", "avatar", "image", "imageWidth", "avatarSize", "href", "hrefTarget", "icon", "iconSize", "subtitle", "logoIcon", "width", "height", "column"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6675
6820
  }
6676
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: SkeletonLoaderComponent, decorators: [{
6821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ScrollingCardsComponent, decorators: [{
6677
6822
  type: Component,
6678
- args: [{
6679
- selector: 'sa-skeleton-loader',
6680
- standalone: true,
6681
- imports: [
6682
- CommonModule,
6683
- SkeletonBaseComponent,
6684
- SkeletonTextComponent,
6685
- SkeletonCircleComponent,
6686
- SkeletonRectangleComponent,
6687
- SkeletonEllipticalComponent,
6688
- SkeletonContainerComponent
6689
- ],
6690
- template: `
6691
- <sa-skeleton-container
6692
- [gap]="config?.containerConfig?.gap"
6693
- [padding]="config?.containerConfig?.padding"
6694
- [direction]="config?.containerConfig?.direction || 'column'"
6695
- >
6696
- @for (item of config?.items; track $index) {
6697
- @switch (item.type) {
6698
- @case ('text') {
6699
- <sa-skeleton-text
6700
- [width]="item.width"
6701
- [height]="item.height"
6702
- ></sa-skeleton-text>
6703
- }
6704
- @case ('circle') {
6705
- <sa-skeleton-circle
6706
- [size]="item.size"
6707
- ></sa-skeleton-circle>
6708
- }
6709
- @case ('rectangle') {
6710
- <sa-skeleton-rectangle
6711
- [width]="item.width"
6712
- [height]="item.height"
6713
- ></sa-skeleton-rectangle>
6714
- }
6715
- @case ('elliptical') {
6716
- <sa-skeleton-elliptical
6717
- [width]="item.width"
6718
- [height]="item.height"
6719
- ></sa-skeleton-elliptical>
6720
- }
6721
- @case ('container') {
6722
- <sa-skeleton-container [direction]="item.direction" [gap]="item.gap">
6723
- @for (subItem of item.items; track $index) {
6724
- @switch (subItem.type) {
6725
- @case ('text') {
6726
- <sa-skeleton-text
6727
- [width]="subItem.width"
6728
- [height]="subItem.height"
6729
- ></sa-skeleton-text>
6730
- }
6731
- @case ('circle') {
6732
- <sa-skeleton-circle
6733
- [size]="subItem.size"
6734
- ></sa-skeleton-circle>
6735
- }
6736
- @case ('rectangle') {
6737
- <sa-skeleton-rectangle
6738
- [width]="subItem.width"
6739
- [height]="subItem.height"
6740
- ></sa-skeleton-rectangle>
6741
- }
6742
- @case ('elliptical') {
6743
- <sa-skeleton-elliptical
6744
- [width]="subItem.width"
6745
- [height]="subItem.height"
6746
- ></sa-skeleton-elliptical>
6747
- }
6748
- @case ('container') {
6749
- <sa-skeleton-container [direction]="subItem.direction" [gap]="subItem.gap">
6750
- @for (subSubItem of subItem.items; track $index) {
6751
- @switch (subSubItem.type) {
6752
- @case ('text') {
6753
- <sa-skeleton-text
6754
- [width]="subSubItem.width"
6755
- [height]="subSubItem.height"
6756
- ></sa-skeleton-text>
6757
- }
6758
- @case ('circle') {
6759
- <sa-skeleton-circle
6760
- [size]="subSubItem.size"
6761
- ></sa-skeleton-circle>
6762
- }
6763
- @case ('rectangle') {
6764
- <sa-skeleton-rectangle
6765
- [width]="subSubItem.width"
6766
- [height]="subSubItem.height"
6767
- ></sa-skeleton-rectangle>
6768
- }
6769
- @case ('elliptical') {
6770
- <sa-skeleton-elliptical
6771
- [width]="subSubItem.width"
6772
- [height]="subSubItem.height"
6773
- ></sa-skeleton-elliptical>
6774
- }
6775
- }
6776
- }
6777
- </sa-skeleton-container>
6778
- }
6779
- }
6780
- }
6781
- </sa-skeleton-container>
6782
- }
6783
- }
6784
- }
6785
- </sa-skeleton-container>
6786
- `
6787
- }]
6788
- }], propDecorators: { preset: [{
6823
+ args: [{ selector: 'sa-scrolling-cards', standalone: true, imports: [HttpClientModule, CardComponent], providers: [IconService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"scrolling-cards-container {{this.isVertical ? 'vertical': 'horizontal'}}\" (mouseenter)=\"pauseScroll()\"\r\n (mouseleave)=\"resumeScroll()\">\r\n <div #cardContainer class=\"card-container\">\r\n @for (card of displayCards; track card.title) {\r\n <sa-card [title]=\"card.title\" [body]=\"card.body\" [avatar]=\"card?.avatar\" [icon]=\"card.icon\" [iconSize]=\"'54'\"\r\n [customWrapperClass]=\"'sa-card-secondary-wrapper'\" [width]=\"'24.063rem'\" [column]=\"false\"\r\n [showCardBody]=\"true\">\r\n </sa-card>\r\n }\r\n </div>\r\n</div>", styles: [".scrolling-cards-container{overflow:hidden;width:fit-content}.scrolling-cards-container.vertical{height:100%;position:relative}.scrolling-cards-container.vertical:before,.scrolling-cards-container.vertical:after{content:\"\";position:absolute;width:100%;height:var(--medium-36px);z-index:1}.scrolling-cards-container.vertical:before{background:#fbfaff;background:-moz-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(180deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.scrolling-cards-container.vertical:after{bottom:0;background:#fbfaff;background:-moz-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:-webkit-linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);background:linear-gradient(360deg,var(--structural-primarytint) 10%,rgba(255,255,255,.12) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\"var(--structural-primarytint)\",endColorstr=\"#ffffff\",GradientType=1)}.card-container{display:flex;gap:var(--small-16px);animation-duration:var(--scroll-duration, 30s);animation-timing-function:linear;animation-iteration-count:infinite;animation-direction:var(--scroll-direction, normal);width:fit-content}.card-container.horizontal{flex-direction:row;animation-name:scroll-horizontal}@keyframes scroll-vertical{0%{transform:translateY(0)}to{transform:translateY(calc(-50% - var(--small-16px)))}}@keyframes scroll-horizontal{0%{transform:translate(0)}to{transform:translate(calc(-50% - var(--small-16px)))}}sa-card{flex-shrink:0}.card-container.vertical{flex-direction:column;animation-name:scroll-vertical}@keyframes scroll-continuous{0%{transform:translate(100%)}to{transform:translate(-100%)}}\n"] }]
6824
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { cards: [{
6825
+ type: Input,
6826
+ args: [{ required: true }]
6827
+ }], duration: [{
6789
6828
  type: Input
6790
- }], config: [{
6829
+ }], direction: [{
6791
6830
  type: Input
6831
+ }], cardContainer: [{
6832
+ type: ViewChild,
6833
+ args: ['cardContainer']
6792
6834
  }] } });
6793
6835
 
6794
6836
  let nextId$1 = 0; // used to give unique ids to inputs used in html