@crowdfarming/oliva-ds 1.28.2 → 1.29.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/crowdfarming-oliva-ds.mjs +638 -611
- package/fesm2022/crowdfarming-oliva-ds.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/alert/src/lib/alert/alert.component.d.ts +2 -2
- package/lib/overlay/src/lib/overlay/overlay.component.d.ts +49 -0
- package/lib/sidebar/src/index.d.ts +0 -2
- package/lib/sidebar/src/lib/sidebar/sidebar.component.d.ts +11 -22
- package/lib/sidebar-programmatic/src/index.d.ts +3 -0
- package/lib/sidebar-programmatic/src/lib/sidebar/sidebar-programmatic-examples.component.d.ts +44 -0
- package/lib/sidebar-programmatic/src/lib/sidebar/sidebar-programmatic.component.d.ts +34 -0
- package/lib/{sidebar/src/lib/sidebar/sidebar.interfaces.d.ts → sidebar-programmatic/src/lib/sidebar/sidebar-programmatic.interfaces.d.ts} +1 -0
- package/lib/{sidebar/src/lib/sidebar/sidebar.service.d.ts → sidebar-programmatic/src/lib/sidebar/sidebar-programmatic.service.d.ts} +4 -1
- package/package.json +1 -1
- package/lib/sidebar/src/lib/sidebar/sidebar-examples.component.d.ts +0 -53
|
@@ -6,7 +6,8 @@ import * as i1 from '@angular/platform-browser';
|
|
|
6
6
|
import * as i1$2 from '@angular/forms';
|
|
7
7
|
import { NG_VALUE_ACCESSOR, ReactiveFormsModule, FormControl, FormsModule } from '@angular/forms';
|
|
8
8
|
import { TemplatePortal, DomPortalOutlet, PortalModule, ComponentPortal } from '@angular/cdk/portal';
|
|
9
|
-
import {
|
|
9
|
+
import { FocusTrapFactory } from '@angular/cdk/a11y';
|
|
10
|
+
import { Router, NavigationStart, RouterLink } from '@angular/router';
|
|
10
11
|
import * as i1$3 from '@angular/cdk/overlay';
|
|
11
12
|
|
|
12
13
|
// Auto-generated icons from Figma
|
|
@@ -2484,8 +2485,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
2484
2485
|
|
|
2485
2486
|
class AlertComponent {
|
|
2486
2487
|
variant = input('neutral');
|
|
2487
|
-
text = input('');
|
|
2488
2488
|
title = input('');
|
|
2489
|
+
text = input('');
|
|
2489
2490
|
extraClass = input('');
|
|
2490
2491
|
showIcon = input(true);
|
|
2491
2492
|
removable = input(true);
|
|
@@ -2524,11 +2525,11 @@ class AlertComponent {
|
|
|
2524
2525
|
}
|
|
2525
2526
|
}
|
|
2526
2527
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: AlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2527
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: AlertComponent, isStandalone: true, selector: "lib-alert", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null },
|
|
2528
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: AlertComponent, isStandalone: true, selector: "lib-alert", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, extraClass: { classPropertyName: "extraClass", publicName: "extraClass", isSignal: true, isRequired: false, transformFunction: null }, showIcon: { classPropertyName: "showIcon", publicName: "showIcon", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (visibility) {\n<div\n role=\"alert\"\n [ngClass]=\"[\n 'c-alert',\n variant() ? 'c-alert--' + variant() : '',\n extraClass() ? extraClass() : '',\n closeActive ? 'c-alert--hide' : ''\n ]\"\n>\n @if (showIcon()) {\n <lib-icon [name]=\"getIconName()\" [color]=\"getIconColor()\" size=\"lg\" />\n }\n\n <div class=\"c-alert__content\">\n @if (title()) {\n <p class=\"c-alert__title\">{{ title() }}</p>\n } @if (text()) {\n <p class=\"c-alert__text\">{{ text() }}</p>\n }\n </div>\n\n @if (removable()) {\n <lib-button-icon\n role=\"button\"\n [ariaLabel]=\"variant()\"\n [loading]=\"false\"\n variant=\"neutral\"\n size=\"sm\"\n class=\"c-alert__close\"\n iconName=\"x-regular\"\n (click)=\"close()\"\n />\n }\n</div>\n}\n", styles: [".c-alert{width:100%;width:-moz-available;width:-webkit-fill-available;width:stretch;padding:var(--space-component-padding-md);border-radius:var(--size-textfield-border-radius);border:var(--size-border-width-sm) solid var(--color-core-border-soft);background:var(--color-core-background-surface-raised);display:flex;align-items:flex-start;gap:var(--space-component-gap-md)}.c-alert--danger{border-color:var(--color-feedback-danger-surface-border);background:var(--color-feedback-danger-surface-background)}.c-alert--success{border-color:var(--color-feedback-success-surface-border);background:var(--color-feedback-success-surface-background)}.c-alert--warning{border-color:var(--color-feedback-warning-surface-border);background:var(--color-feedback-warning-surface-background)}.c-alert--info{border-color:var(--color-feedback-info-surface-border);background:var(--color-feedback-info-surface-background)}.c-alert--neutral{border-color:var(--color-core-border-default);background:var(--color-core-background-neutral-soft)}.c-alert__content{display:flex;flex:1;flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--space-component-gap-sm)}.c-alert__close{justify-self:flex-end;margin:0 0 0 auto}.c-alert__title{color:var(--color-core-content-default);font-family:var(--typography-title-sm-family);font-size:var(--typography-title-sm-size);font-style:normal;font-weight:var(--typography-title-sm-weight);line-height:var(--typography-title-sm-line-height);letter-spacing:var(--typography-title-sm-letter-spacing);margin:0 0 auto}.c-alert__text{color:var(--color-core-content-soft);font-family:var(--typography-body-sm-family);font-size:var(--typography-body-sm-size);font-style:normal;font-weight:var(--typography-body-sm-weight);line-height:var(--typography-body-sm-line-height);letter-spacing:var(--typography-body-sm-letter-spacing);margin:0 0 auto}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: IconComponent, selector: "lib-icon", inputs: ["size", "icon", "name", "color"] }, { kind: "component", type: ButtonIconComponent, selector: "lib-button-icon", inputs: ["ariaLabel", "variant", "size", "iconName", "disabled", "loading", "skeletonActive"], outputs: ["clicked"] }] });
|
|
2528
2529
|
}
|
|
2529
2530
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: AlertComponent, decorators: [{
|
|
2530
2531
|
type: Component,
|
|
2531
|
-
args: [{ selector: 'lib-alert', imports: [NgClass, IconComponent, ButtonIconComponent], template: "@if (visibility) {\n<div\n role=\"alert\"\n [ngClass]=\"[\n 'c-alert',\n variant() ? 'c-alert--' + variant() : '',\n extraClass() ? extraClass() : '',\n closeActive ? 'c-alert--hide' : ''\n ]\"\n>\n @if (showIcon()) {\n <lib-icon [name]=\"getIconName()\" [color]=\"getIconColor()\" size=\"lg\" />\n }\n\n <div class=\"c-alert__content\">\n <p class=\"c-alert__title\">{{ title() }}</p>\n <p class=\"c-alert__text\">{{ text() }}</p>\n </div>\n\n @if (removable()) {\n <lib-button-icon\n role=\"button\"\n [ariaLabel]=\"variant()\"\n [loading]=\"false\"\n variant=\"neutral\"\n size=\"sm\"\n class=\"c-alert__close\"\n iconName=\"x-regular\"\n (click)=\"close()\"\n />\n }\n</div>\n}\n", styles: [".c-alert{width:100%;width:-moz-available;width:-webkit-fill-available;width:stretch;padding:var(--space-component-padding-md);border-radius:var(--size-textfield-border-radius);border:var(--size-border-width-sm) solid var(--color-core-border-soft);background:var(--color-core-background-surface-raised);display:flex;align-items:flex-start;gap:var(--space-component-gap-md)}.c-alert--danger{border-color:var(--color-feedback-danger-surface-border);background:var(--color-feedback-danger-surface-background)}.c-alert--success{border-color:var(--color-feedback-success-surface-border);background:var(--color-feedback-success-surface-background)}.c-alert--warning{border-color:var(--color-feedback-warning-surface-border);background:var(--color-feedback-warning-surface-background)}.c-alert--info{border-color:var(--color-feedback-info-surface-border);background:var(--color-feedback-info-surface-background)}.c-alert--neutral{border-color:var(--color-core-border-default);background:var(--color-core-background-neutral-soft)}.c-alert__content{display:flex;flex:1;flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--space-component-gap-sm)}.c-alert__close{justify-self:flex-end;margin:0 0 0 auto}.c-alert__title{color:var(--color-core-content-default);font-family:var(--typography-title-sm-family);font-size:var(--typography-title-sm-size);font-style:normal;font-weight:var(--typography-title-sm-weight);line-height:var(--typography-title-sm-line-height);letter-spacing:var(--typography-title-sm-letter-spacing);margin:0 0 auto}.c-alert__text{color:var(--color-core-content-soft);font-family:var(--typography-body-sm-family);font-size:var(--typography-body-sm-size);font-style:normal;font-weight:var(--typography-body-sm-weight);line-height:var(--typography-body-sm-line-height);letter-spacing:var(--typography-body-sm-letter-spacing);margin:0 0 auto}\n"] }]
|
|
2532
|
+
args: [{ selector: 'lib-alert', imports: [NgClass, IconComponent, ButtonIconComponent], template: "@if (visibility) {\n<div\n role=\"alert\"\n [ngClass]=\"[\n 'c-alert',\n variant() ? 'c-alert--' + variant() : '',\n extraClass() ? extraClass() : '',\n closeActive ? 'c-alert--hide' : ''\n ]\"\n>\n @if (showIcon()) {\n <lib-icon [name]=\"getIconName()\" [color]=\"getIconColor()\" size=\"lg\" />\n }\n\n <div class=\"c-alert__content\">\n @if (title()) {\n <p class=\"c-alert__title\">{{ title() }}</p>\n } @if (text()) {\n <p class=\"c-alert__text\">{{ text() }}</p>\n }\n </div>\n\n @if (removable()) {\n <lib-button-icon\n role=\"button\"\n [ariaLabel]=\"variant()\"\n [loading]=\"false\"\n variant=\"neutral\"\n size=\"sm\"\n class=\"c-alert__close\"\n iconName=\"x-regular\"\n (click)=\"close()\"\n />\n }\n</div>\n}\n", styles: [".c-alert{width:100%;width:-moz-available;width:-webkit-fill-available;width:stretch;padding:var(--space-component-padding-md);border-radius:var(--size-textfield-border-radius);border:var(--size-border-width-sm) solid var(--color-core-border-soft);background:var(--color-core-background-surface-raised);display:flex;align-items:flex-start;gap:var(--space-component-gap-md)}.c-alert--danger{border-color:var(--color-feedback-danger-surface-border);background:var(--color-feedback-danger-surface-background)}.c-alert--success{border-color:var(--color-feedback-success-surface-border);background:var(--color-feedback-success-surface-background)}.c-alert--warning{border-color:var(--color-feedback-warning-surface-border);background:var(--color-feedback-warning-surface-background)}.c-alert--info{border-color:var(--color-feedback-info-surface-border);background:var(--color-feedback-info-surface-background)}.c-alert--neutral{border-color:var(--color-core-border-default);background:var(--color-core-background-neutral-soft)}.c-alert__content{display:flex;flex:1;flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:var(--space-component-gap-sm)}.c-alert__close{justify-self:flex-end;margin:0 0 0 auto}.c-alert__title{color:var(--color-core-content-default);font-family:var(--typography-title-sm-family);font-size:var(--typography-title-sm-size);font-style:normal;font-weight:var(--typography-title-sm-weight);line-height:var(--typography-title-sm-line-height);letter-spacing:var(--typography-title-sm-letter-spacing);margin:0 0 auto}.c-alert__text{color:var(--color-core-content-soft);font-family:var(--typography-body-sm-family);font-size:var(--typography-body-sm-size);font-style:normal;font-weight:var(--typography-body-sm-weight);line-height:var(--typography-body-sm-line-height);letter-spacing:var(--typography-body-sm-letter-spacing);margin:0 0 auto}\n"] }]
|
|
2532
2533
|
}] });
|
|
2533
2534
|
|
|
2534
2535
|
class ArrowsComponent {
|
|
@@ -2957,7 +2958,7 @@ class CheckboxComponent {
|
|
|
2957
2958
|
useExisting: forwardRef(() => CheckboxComponent),
|
|
2958
2959
|
multi: true,
|
|
2959
2960
|
},
|
|
2960
|
-
], ngImport: i0, template: "<div [ngClass]=\"classes()\" class=\"c-checkbox\">\n <div class=\"c-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [id]=\"name()\"\n [ngClass]=\"inputClasses()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"isIndeterminate()\"\n [disabled]=\"isDisabled()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-checked]=\"ariaChecked()\"\n (change)=\"handleChange($event)\"\n (keydown)=\"handleKeyDown($event)\"\n />\n </div>\n @if(isSkeleton()) {\n <div class=\"c-checkbox__label__skeleton\">\n <span></span>\n </div>\n } @else { @if(label()) {\n <lib-input-label\n size=\"md\"\n [text]=\"label()\"\n [disabled]=\"disabled()\"\n [required]=\"true\"\n [for]=\"name()\"\n [innerHTML]=\"innerHTML()\"\n ></lib-input-label>\n } }\n</div>\n", styles: [".c-checkbox{display:flex;align-items:flex-start;gap:var(--space-component-gap-sm)}.c-checkbox__input-wrapper{height:var(--typography-label-md-default-line-height);display:flex;align-items:center}.c-checkbox__label{cursor:pointer}.c-checkbox__label__skeleton{width:64px;height:24px;display:flex;align-items:center}.c-checkbox__label__skeleton span{width:100%;height:8px;background-color:var(--color-effect-skeleton-default);border-radius:var(--size-border-radius-sm, 4px)}.c-checkbox--skeleton .c-checkbox__label{cursor:default;pointer-events:none}.c-checkbox input[type=checkbox]{-webkit-appearance:none;appearance:none;width:18px;height:18px;border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-default, #929a99);background-color:var(--color-textfield-background-default);border-radius:var(--size-border-radius-sm, 4px);display:grid;place-content:center;cursor:pointer}.c-checkbox input[type=checkbox]:hover{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-hover, #7d8483)}.c-checkbox input[type=checkbox]:not(:disabled):not(.c-checkbox__input--skeleton):focus-visible{box-shadow:var(--focus-outset);outline:none}.c-checkbox input[type=checkbox].c-checkbox__input--error{border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox].c-checkbox__input--error:checked,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate,.c-checkbox input[type=checkbox].c-checkbox__input--error:checked:hover,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate:hover{background-color:var(--color-feedback-danger-default, #ba2f1e);border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox]:checked,.c-checkbox input[type=checkbox]:indeterminate{border-color:var(--color-action-primary-selected-background-default, #217870);background-color:var(--color-action-primary-selected-background-default, #217870)}.c-checkbox input[type=checkbox]:checked:hover,.c-checkbox input[type=checkbox]:indeterminate:hover{background-color:var(--color-action-primary-selected-background-hover, #19625b);border-color:var(--color-action-primary-selected-background-hover, #19625b)}.c-checkbox input[type=checkbox]:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:disabled+.c-checkbox__label{pointer-events:none;cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:disabled,.c-checkbox input[type=checkbox]:indeterminate:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0%,43% 62%)}.c-checkbox input[type=checkbox]:indeterminate:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(0% 38%,100% 38%,100% 62%,0 62%)}.c-checkbox input[type=checkbox]:checked:disabled:before,.c-checkbox input[type=checkbox]:indeterminate:disabled:before{box-shadow:inset 1em 1em #7d8483}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton{border-color:var(--color-effect-skeleton-soft);background-color:var(--color-textfield-background-disabled);cursor:not-allowed;pointer-events:none}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton:before{content:none!important}.c-checkbox ::ng-deep lib-input-label span{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: InputLabelComponent, selector: "lib-input-label", inputs: ["text", "required", "size", "disabled", "for", "innerHTML"] }] });
|
|
2961
|
+
], ngImport: i0, template: "<div [ngClass]=\"classes()\" class=\"c-checkbox\">\n <div class=\"c-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [id]=\"name()\"\n [ngClass]=\"inputClasses()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"isIndeterminate()\"\n [disabled]=\"isDisabled()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-checked]=\"ariaChecked()\"\n (change)=\"handleChange($event)\"\n (keydown)=\"handleKeyDown($event)\"\n />\n </div>\n @if(isSkeleton()) {\n <div class=\"c-checkbox__label__skeleton\">\n <span></span>\n </div>\n } @else { @if(label() || innerHTML()) {\n <lib-input-label\n size=\"md\"\n [text]=\"label()\"\n [disabled]=\"disabled()\"\n [required]=\"true\"\n [for]=\"name()\"\n [innerHTML]=\"innerHTML()\"\n ></lib-input-label>\n } }\n</div>\n", styles: [".c-checkbox{display:flex;align-items:flex-start;gap:var(--space-component-gap-sm)}.c-checkbox__input-wrapper{height:var(--typography-label-md-default-line-height);display:flex;align-items:center}.c-checkbox__label{cursor:pointer}.c-checkbox__label__skeleton{width:64px;height:24px;display:flex;align-items:center}.c-checkbox__label__skeleton span{width:100%;height:8px;background-color:var(--color-effect-skeleton-default);border-radius:var(--size-border-radius-sm, 4px)}.c-checkbox--skeleton .c-checkbox__label{cursor:default;pointer-events:none}.c-checkbox input[type=checkbox]{-webkit-appearance:none;appearance:none;width:18px;height:18px;border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-default, #929a99);background-color:var(--color-textfield-background-default);border-radius:var(--size-border-radius-sm, 4px);display:grid;place-content:center;cursor:pointer}.c-checkbox input[type=checkbox]:hover{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-hover, #7d8483)}.c-checkbox input[type=checkbox]:not(:disabled):not(.c-checkbox__input--skeleton):focus-visible{box-shadow:var(--focus-outset);outline:none}.c-checkbox input[type=checkbox].c-checkbox__input--error{border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox].c-checkbox__input--error:checked,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate,.c-checkbox input[type=checkbox].c-checkbox__input--error:checked:hover,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate:hover{background-color:var(--color-feedback-danger-default, #ba2f1e);border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox]:checked,.c-checkbox input[type=checkbox]:indeterminate{border-color:var(--color-action-primary-selected-background-default, #217870);background-color:var(--color-action-primary-selected-background-default, #217870)}.c-checkbox input[type=checkbox]:checked:hover,.c-checkbox input[type=checkbox]:indeterminate:hover{background-color:var(--color-action-primary-selected-background-hover, #19625b);border-color:var(--color-action-primary-selected-background-hover, #19625b)}.c-checkbox input[type=checkbox]:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:disabled+.c-checkbox__label{pointer-events:none;cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:disabled,.c-checkbox input[type=checkbox]:indeterminate:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0%,43% 62%)}.c-checkbox input[type=checkbox]:indeterminate:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(0% 38%,100% 38%,100% 62%,0 62%)}.c-checkbox input[type=checkbox]:checked:disabled:before,.c-checkbox input[type=checkbox]:indeterminate:disabled:before{box-shadow:inset 1em 1em #7d8483}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton{border-color:var(--color-effect-skeleton-soft);background-color:var(--color-textfield-background-disabled);cursor:not-allowed;pointer-events:none}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton:before{content:none!important}.c-checkbox ::ng-deep lib-input-label span{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: InputLabelComponent, selector: "lib-input-label", inputs: ["text", "required", "size", "disabled", "for", "innerHTML"] }] });
|
|
2961
2962
|
}
|
|
2962
2963
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: CheckboxComponent, decorators: [{
|
|
2963
2964
|
type: Component,
|
|
@@ -2967,7 +2968,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
2967
2968
|
useExisting: forwardRef(() => CheckboxComponent),
|
|
2968
2969
|
multi: true,
|
|
2969
2970
|
},
|
|
2970
|
-
], template: "<div [ngClass]=\"classes()\" class=\"c-checkbox\">\n <div class=\"c-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [id]=\"name()\"\n [ngClass]=\"inputClasses()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"isIndeterminate()\"\n [disabled]=\"isDisabled()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-checked]=\"ariaChecked()\"\n (change)=\"handleChange($event)\"\n (keydown)=\"handleKeyDown($event)\"\n />\n </div>\n @if(isSkeleton()) {\n <div class=\"c-checkbox__label__skeleton\">\n <span></span>\n </div>\n } @else { @if(label()) {\n <lib-input-label\n size=\"md\"\n [text]=\"label()\"\n [disabled]=\"disabled()\"\n [required]=\"true\"\n [for]=\"name()\"\n [innerHTML]=\"innerHTML()\"\n ></lib-input-label>\n } }\n</div>\n", styles: [".c-checkbox{display:flex;align-items:flex-start;gap:var(--space-component-gap-sm)}.c-checkbox__input-wrapper{height:var(--typography-label-md-default-line-height);display:flex;align-items:center}.c-checkbox__label{cursor:pointer}.c-checkbox__label__skeleton{width:64px;height:24px;display:flex;align-items:center}.c-checkbox__label__skeleton span{width:100%;height:8px;background-color:var(--color-effect-skeleton-default);border-radius:var(--size-border-radius-sm, 4px)}.c-checkbox--skeleton .c-checkbox__label{cursor:default;pointer-events:none}.c-checkbox input[type=checkbox]{-webkit-appearance:none;appearance:none;width:18px;height:18px;border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-default, #929a99);background-color:var(--color-textfield-background-default);border-radius:var(--size-border-radius-sm, 4px);display:grid;place-content:center;cursor:pointer}.c-checkbox input[type=checkbox]:hover{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-hover, #7d8483)}.c-checkbox input[type=checkbox]:not(:disabled):not(.c-checkbox__input--skeleton):focus-visible{box-shadow:var(--focus-outset);outline:none}.c-checkbox input[type=checkbox].c-checkbox__input--error{border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox].c-checkbox__input--error:checked,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate,.c-checkbox input[type=checkbox].c-checkbox__input--error:checked:hover,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate:hover{background-color:var(--color-feedback-danger-default, #ba2f1e);border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox]:checked,.c-checkbox input[type=checkbox]:indeterminate{border-color:var(--color-action-primary-selected-background-default, #217870);background-color:var(--color-action-primary-selected-background-default, #217870)}.c-checkbox input[type=checkbox]:checked:hover,.c-checkbox input[type=checkbox]:indeterminate:hover{background-color:var(--color-action-primary-selected-background-hover, #19625b);border-color:var(--color-action-primary-selected-background-hover, #19625b)}.c-checkbox input[type=checkbox]:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:disabled+.c-checkbox__label{pointer-events:none;cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:disabled,.c-checkbox input[type=checkbox]:indeterminate:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0%,43% 62%)}.c-checkbox input[type=checkbox]:indeterminate:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(0% 38%,100% 38%,100% 62%,0 62%)}.c-checkbox input[type=checkbox]:checked:disabled:before,.c-checkbox input[type=checkbox]:indeterminate:disabled:before{box-shadow:inset 1em 1em #7d8483}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton{border-color:var(--color-effect-skeleton-soft);background-color:var(--color-textfield-background-disabled);cursor:not-allowed;pointer-events:none}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton:before{content:none!important}.c-checkbox ::ng-deep lib-input-label span{cursor:pointer}\n"] }]
|
|
2971
|
+
], template: "<div [ngClass]=\"classes()\" class=\"c-checkbox\">\n <div class=\"c-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [id]=\"name()\"\n [ngClass]=\"inputClasses()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"isIndeterminate()\"\n [disabled]=\"isDisabled()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-checked]=\"ariaChecked()\"\n (change)=\"handleChange($event)\"\n (keydown)=\"handleKeyDown($event)\"\n />\n </div>\n @if(isSkeleton()) {\n <div class=\"c-checkbox__label__skeleton\">\n <span></span>\n </div>\n } @else { @if(label() || innerHTML()) {\n <lib-input-label\n size=\"md\"\n [text]=\"label()\"\n [disabled]=\"disabled()\"\n [required]=\"true\"\n [for]=\"name()\"\n [innerHTML]=\"innerHTML()\"\n ></lib-input-label>\n } }\n</div>\n", styles: [".c-checkbox{display:flex;align-items:flex-start;gap:var(--space-component-gap-sm)}.c-checkbox__input-wrapper{height:var(--typography-label-md-default-line-height);display:flex;align-items:center}.c-checkbox__label{cursor:pointer}.c-checkbox__label__skeleton{width:64px;height:24px;display:flex;align-items:center}.c-checkbox__label__skeleton span{width:100%;height:8px;background-color:var(--color-effect-skeleton-default);border-radius:var(--size-border-radius-sm, 4px)}.c-checkbox--skeleton .c-checkbox__label{cursor:default;pointer-events:none}.c-checkbox input[type=checkbox]{-webkit-appearance:none;appearance:none;width:18px;height:18px;border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-default, #929a99);background-color:var(--color-textfield-background-default);border-radius:var(--size-border-radius-sm, 4px);display:grid;place-content:center;cursor:pointer}.c-checkbox input[type=checkbox]:hover{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-hover, #7d8483)}.c-checkbox input[type=checkbox]:not(:disabled):not(.c-checkbox__input--skeleton):focus-visible{box-shadow:var(--focus-outset);outline:none}.c-checkbox input[type=checkbox].c-checkbox__input--error{border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox].c-checkbox__input--error:checked,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate,.c-checkbox input[type=checkbox].c-checkbox__input--error:checked:hover,.c-checkbox input[type=checkbox].c-checkbox__input--error:indeterminate:hover{background-color:var(--color-feedback-danger-default, #ba2f1e);border-color:var(--color-feedback-danger-default, #ba2f1e)}.c-checkbox input[type=checkbox]:checked,.c-checkbox input[type=checkbox]:indeterminate{border-color:var(--color-action-primary-selected-background-default, #217870);background-color:var(--color-action-primary-selected-background-default, #217870)}.c-checkbox input[type=checkbox]:checked:hover,.c-checkbox input[type=checkbox]:indeterminate:hover{background-color:var(--color-action-primary-selected-background-hover, #19625b);border-color:var(--color-action-primary-selected-background-hover, #19625b)}.c-checkbox input[type=checkbox]:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:disabled+.c-checkbox__label{pointer-events:none;cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:disabled,.c-checkbox input[type=checkbox]:indeterminate:disabled{border:var(--size-border-width-md, 2px) solid var(--color-textfield-border-disabled, #a6b0af);background:var(--color-textfield-background-disabled, rgba(0, 0, 0, .02));cursor:not-allowed}.c-checkbox input[type=checkbox]:checked:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0%,43% 62%)}.c-checkbox input[type=checkbox]:indeterminate:before{content:\"\";width:10px;height:10px;transition:.12s transform ease-in-out;box-shadow:inset 1em 1em #fff;clip-path:polygon(0% 38%,100% 38%,100% 62%,0 62%)}.c-checkbox input[type=checkbox]:checked:disabled:before,.c-checkbox input[type=checkbox]:indeterminate:disabled:before{box-shadow:inset 1em 1em #7d8483}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton{border-color:var(--color-effect-skeleton-soft);background-color:var(--color-textfield-background-disabled);cursor:not-allowed;pointer-events:none}.c-checkbox input[type=checkbox].c-checkbox__input--skeleton:before{content:none!important}.c-checkbox ::ng-deep lib-input-label span{cursor:pointer}\n"] }]
|
|
2971
2972
|
}], ctorParameters: () => [] });
|
|
2972
2973
|
|
|
2973
2974
|
class HelperTextComponent {
|
|
@@ -3145,21 +3146,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
3145
3146
|
}] });
|
|
3146
3147
|
|
|
3147
3148
|
class OverlayComponent {
|
|
3148
|
-
// Constants
|
|
3149
3149
|
static MOBILE_BREAKPOINT = 768;
|
|
3150
3150
|
static DROPDOWN_HEIGHT = 320;
|
|
3151
3151
|
static DROPDOWN_GAP = 2;
|
|
3152
3152
|
static VIEWPORT_MARGIN = 16;
|
|
3153
3153
|
static ANIMATION_DURATION = 20;
|
|
3154
3154
|
static DEFAULT_MENU_WIDTH = 200;
|
|
3155
|
-
// Inputs
|
|
3156
3155
|
position = input('right');
|
|
3157
3156
|
disabled = input(false);
|
|
3158
3157
|
width = input(`${OverlayComponent.DEFAULT_MENU_WIDTH}px`);
|
|
3159
|
-
// Outputs
|
|
3160
3158
|
opened = output();
|
|
3161
3159
|
closed = output();
|
|
3162
|
-
// Signals
|
|
3163
3160
|
_isOpen = signal(false);
|
|
3164
3161
|
_isClosing = signal(false);
|
|
3165
3162
|
_isMobile = signal(false);
|
|
@@ -3168,12 +3165,10 @@ class OverlayComponent {
|
|
|
3168
3165
|
left: 0,
|
|
3169
3166
|
width: OverlayComponent.DEFAULT_MENU_WIDTH,
|
|
3170
3167
|
});
|
|
3171
|
-
// Computed
|
|
3172
3168
|
isOpen = this._isOpen.asReadonly();
|
|
3173
3169
|
isClosing = this._isClosing.asReadonly();
|
|
3174
3170
|
getMenuClasses = computed(() => ['c-overlay__menu', `c-overlay__menu--${this.position()}`].join(' '));
|
|
3175
3171
|
getMenuStyles = computed(() => {
|
|
3176
|
-
// On mobile we don't apply position styles, it's handled with CSS
|
|
3177
3172
|
if (this._isMobile()) {
|
|
3178
3173
|
return {};
|
|
3179
3174
|
}
|
|
@@ -3198,17 +3193,32 @@ class OverlayComponent {
|
|
|
3198
3193
|
}
|
|
3199
3194
|
return classes.join(' ');
|
|
3200
3195
|
});
|
|
3201
|
-
// Element refs
|
|
3202
3196
|
elementRef = inject(ElementRef);
|
|
3203
3197
|
viewContainerRef = inject(ViewContainerRef);
|
|
3204
3198
|
applicationRef = inject(ApplicationRef);
|
|
3205
3199
|
platformId = inject(PLATFORM_ID);
|
|
3206
3200
|
destroyRef = inject(DestroyRef);
|
|
3201
|
+
focusTrapFactory = inject(FocusTrapFactory);
|
|
3202
|
+
router = inject(Router);
|
|
3203
|
+
// Portal and container management
|
|
3207
3204
|
triggerButtonRef;
|
|
3208
3205
|
portal;
|
|
3209
3206
|
portalOutlet;
|
|
3210
3207
|
portalContainer;
|
|
3208
|
+
boundPortalClickHandler;
|
|
3209
|
+
// Focus and accessibility management
|
|
3210
|
+
focusTrap;
|
|
3211
|
+
previouslyFocusedElement;
|
|
3212
|
+
triggerKeydownHandler;
|
|
3213
|
+
inertElements = [];
|
|
3214
|
+
escapeKeyHandler;
|
|
3215
|
+
// Scroll and navigation management
|
|
3211
3216
|
originalBodyOverflow;
|
|
3217
|
+
navigationSub;
|
|
3218
|
+
// Helper to get the correct document context (important for Storybook)
|
|
3219
|
+
getDocument() {
|
|
3220
|
+
return this.elementRef.nativeElement.ownerDocument || document;
|
|
3221
|
+
}
|
|
3212
3222
|
menuTemplate;
|
|
3213
3223
|
contentTemplate;
|
|
3214
3224
|
footerTemplate;
|
|
@@ -3223,20 +3233,32 @@ class OverlayComponent {
|
|
|
3223
3233
|
else if (!this.isOpen() && !this.isClosing())
|
|
3224
3234
|
this.closed.emit();
|
|
3225
3235
|
});
|
|
3226
|
-
// Cleanup when component is destroyed
|
|
3227
3236
|
this.destroyRef.onDestroy(() => {
|
|
3228
3237
|
if (this.isOpen() && this._isMobile()) {
|
|
3229
3238
|
this.unblockBodyScroll();
|
|
3230
3239
|
}
|
|
3240
|
+
this.destroyFocusTrap();
|
|
3241
|
+
this.cleanupTriggerListener();
|
|
3242
|
+
this.navigationSub?.unsubscribe();
|
|
3243
|
+
this.removeEscapeKeyListener();
|
|
3231
3244
|
});
|
|
3232
3245
|
}
|
|
3246
|
+
// ================== MOBILE DETECTION ==================
|
|
3233
3247
|
updateMobileDetection() {
|
|
3234
3248
|
this._isMobile.set(isPlatformBrowser(this.platformId)
|
|
3235
3249
|
? window.innerWidth <= OverlayComponent.MOBILE_BREAKPOINT
|
|
3236
3250
|
: false);
|
|
3237
3251
|
}
|
|
3252
|
+
// ================== TRIGGER MANAGEMENT ==================
|
|
3238
3253
|
setTriggerButton(element) {
|
|
3239
3254
|
this.triggerButtonRef = element;
|
|
3255
|
+
this.triggerKeydownHandler = (event) => {
|
|
3256
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
3257
|
+
event.preventDefault();
|
|
3258
|
+
this.toggleOverlay();
|
|
3259
|
+
}
|
|
3260
|
+
};
|
|
3261
|
+
element.addEventListener('keydown', this.triggerKeydownHandler);
|
|
3240
3262
|
}
|
|
3241
3263
|
toggleOverlay() {
|
|
3242
3264
|
if (this.disabled())
|
|
@@ -3252,75 +3274,160 @@ class OverlayComponent {
|
|
|
3252
3274
|
onEscapeKey() {
|
|
3253
3275
|
this.closeOverlay();
|
|
3254
3276
|
}
|
|
3277
|
+
// ================== OVERLAY LIFECYCLE ==================
|
|
3255
3278
|
openOverlay() {
|
|
3279
|
+
this.initializeOverlayState();
|
|
3280
|
+
this.prepareOverlayForOpening();
|
|
3281
|
+
this.createOverlayPortal();
|
|
3282
|
+
this.configureScrollBehavior();
|
|
3283
|
+
this.finalizeOverlayOpening();
|
|
3284
|
+
setTimeout(() => {
|
|
3285
|
+
this.trapFocus();
|
|
3286
|
+
this.makeOutsideElementsInert();
|
|
3287
|
+
this.setupEscapeKeyListener();
|
|
3288
|
+
}, 0);
|
|
3289
|
+
}
|
|
3290
|
+
initializeOverlayState() {
|
|
3256
3291
|
this._isClosing.set(false);
|
|
3257
3292
|
this.updateMobileDetection();
|
|
3258
|
-
|
|
3293
|
+
this.previouslyFocusedElement = this.triggerButtonRef ?? this.getDocument().activeElement;
|
|
3294
|
+
}
|
|
3295
|
+
prepareOverlayForOpening() {
|
|
3259
3296
|
if (!this._isMobile()) {
|
|
3260
3297
|
this.calculatePosition();
|
|
3261
3298
|
}
|
|
3262
|
-
|
|
3299
|
+
}
|
|
3300
|
+
createOverlayPortal() {
|
|
3263
3301
|
this.createPortal();
|
|
3264
|
-
|
|
3302
|
+
}
|
|
3303
|
+
configureScrollBehavior() {
|
|
3265
3304
|
if (this._isMobile()) {
|
|
3266
3305
|
this.blockBodyScroll();
|
|
3267
3306
|
}
|
|
3307
|
+
}
|
|
3308
|
+
finalizeOverlayOpening() {
|
|
3268
3309
|
this._isOpen.set(true);
|
|
3269
3310
|
this.addResizeListener();
|
|
3311
|
+
this.listenToNavigation();
|
|
3270
3312
|
}
|
|
3271
3313
|
closeOverlay() {
|
|
3314
|
+
this.initializeOverlayClosing();
|
|
3315
|
+
this.cleanupOverlayResources();
|
|
3316
|
+
this.restoreScrollBehavior();
|
|
3317
|
+
this.destroyOverlayComponents();
|
|
3318
|
+
// Restore focus AFTER destroying DOM to avoid interference
|
|
3319
|
+
requestAnimationFrame(() => {
|
|
3320
|
+
this.restoreFocusToTrigger();
|
|
3321
|
+
});
|
|
3322
|
+
this.scheduleOverlayFinalization();
|
|
3323
|
+
}
|
|
3324
|
+
initializeOverlayClosing() {
|
|
3272
3325
|
this._isClosing.set(true);
|
|
3326
|
+
}
|
|
3327
|
+
cleanupOverlayResources() {
|
|
3273
3328
|
this.removeResizeListener();
|
|
3274
|
-
|
|
3329
|
+
this.unsubscribeFromNavigation();
|
|
3330
|
+
}
|
|
3331
|
+
unsubscribeFromNavigation() {
|
|
3332
|
+
this.navigationSub?.unsubscribe();
|
|
3333
|
+
this.navigationSub = undefined;
|
|
3334
|
+
}
|
|
3335
|
+
restoreScrollBehavior() {
|
|
3275
3336
|
if (this._isMobile()) {
|
|
3276
3337
|
this.unblockBodyScroll();
|
|
3277
3338
|
}
|
|
3278
|
-
|
|
3339
|
+
}
|
|
3340
|
+
destroyOverlayComponents() {
|
|
3341
|
+
this.destroyFocusTrap();
|
|
3279
3342
|
this.destroyPortal();
|
|
3343
|
+
// Ensure elements are restored after destroying components
|
|
3344
|
+
this.restoreOutsideElements();
|
|
3345
|
+
}
|
|
3346
|
+
scheduleOverlayFinalization() {
|
|
3280
3347
|
setTimeout(() => {
|
|
3281
|
-
this.
|
|
3282
|
-
this._isClosing.set(false);
|
|
3348
|
+
this.finalizeOverlayClosing();
|
|
3283
3349
|
}, OverlayComponent.ANIMATION_DURATION);
|
|
3284
3350
|
}
|
|
3351
|
+
finalizeOverlayClosing() {
|
|
3352
|
+
this._isOpen.set(false);
|
|
3353
|
+
this._isClosing.set(false);
|
|
3354
|
+
}
|
|
3355
|
+
// ================== EVENT HANDLING ==================
|
|
3285
3356
|
onPortalClick = (event) => {
|
|
3286
3357
|
if (!this.isOpen() || this.isClosing())
|
|
3287
3358
|
return;
|
|
3288
3359
|
const target = event.target;
|
|
3289
|
-
// Check if click is on the trigger button
|
|
3290
3360
|
const onTrigger = this.triggerButtonRef?.contains(target);
|
|
3291
3361
|
if (onTrigger) {
|
|
3292
|
-
return;
|
|
3362
|
+
return;
|
|
3293
3363
|
}
|
|
3294
|
-
// Check if click is inside the menu
|
|
3295
3364
|
const menuEl = this.portalContainer?.querySelector('.c-overlay__menu');
|
|
3296
3365
|
const insideMenu = menuEl?.contains(target);
|
|
3297
3366
|
if (insideMenu) {
|
|
3298
|
-
return;
|
|
3367
|
+
return;
|
|
3299
3368
|
}
|
|
3300
|
-
// If we get here, click is outside both trigger and menu
|
|
3301
3369
|
this.closeOverlay();
|
|
3302
3370
|
};
|
|
3371
|
+
// ================== POSITIONING ==================
|
|
3303
3372
|
calculatePosition() {
|
|
3304
3373
|
if (!this.triggerButtonRef)
|
|
3305
3374
|
return;
|
|
3306
3375
|
const rect = this.triggerButtonRef.getBoundingClientRect();
|
|
3307
3376
|
const menuWidth = this.parseWidth(rect.width);
|
|
3308
3377
|
const menuHeight = OverlayComponent.DROPDOWN_HEIGHT;
|
|
3378
|
+
const viewportPosition = this.calculateViewportPosition(rect, menuWidth, menuHeight);
|
|
3379
|
+
const finalPosition = this.convertToFinalCoordinates(viewportPosition, menuWidth, menuHeight);
|
|
3380
|
+
this._menuPosition.set(finalPosition);
|
|
3381
|
+
}
|
|
3382
|
+
calculateViewportPosition(rect, menuWidth, menuHeight) {
|
|
3309
3383
|
const gap = OverlayComponent.DROPDOWN_GAP;
|
|
3384
|
+
const viewportTop = this.calculateVerticalPosition(rect, menuHeight, gap);
|
|
3385
|
+
const viewportLeft = this.calculateHorizontalPosition(rect, menuWidth);
|
|
3386
|
+
return { top: viewportTop, left: viewportLeft };
|
|
3387
|
+
}
|
|
3388
|
+
calculateVerticalPosition(rect, menuHeight, gap) {
|
|
3310
3389
|
let top = rect.bottom + gap;
|
|
3311
3390
|
if (window.innerHeight - rect.bottom < menuHeight &&
|
|
3312
3391
|
rect.top > rect.bottom) {
|
|
3313
3392
|
top = rect.top - menuHeight - gap;
|
|
3314
3393
|
}
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3394
|
+
return top;
|
|
3395
|
+
}
|
|
3396
|
+
calculateHorizontalPosition(rect, menuWidth) {
|
|
3397
|
+
const position = this.position();
|
|
3398
|
+
switch (position) {
|
|
3399
|
+
case 'right':
|
|
3400
|
+
return rect.right - menuWidth;
|
|
3401
|
+
case 'center': {
|
|
3402
|
+
const triggerCenter = rect.left + rect.width / 2;
|
|
3403
|
+
return triggerCenter;
|
|
3404
|
+
}
|
|
3405
|
+
case 'left':
|
|
3406
|
+
default:
|
|
3407
|
+
return rect.left;
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
convertToFinalCoordinates(viewportPosition, menuWidth, menuHeight) {
|
|
3411
|
+
const scrollTop = window.pageYOffset || this.getDocument().documentElement.scrollTop;
|
|
3412
|
+
const scrollLeft = window.pageXOffset || this.getDocument().documentElement.scrollLeft;
|
|
3413
|
+
let top;
|
|
3414
|
+
let left;
|
|
3415
|
+
if (this._isMobile()) {
|
|
3416
|
+
const clampedPosition = this.clampToViewport(viewportPosition, menuWidth, menuHeight);
|
|
3417
|
+
top = clampedPosition.top;
|
|
3418
|
+
left = clampedPosition.left;
|
|
3419
|
+
}
|
|
3420
|
+
else {
|
|
3421
|
+
const clampedPosition = this.clampToViewport(viewportPosition, menuWidth, menuHeight);
|
|
3422
|
+
top = clampedPosition.top + scrollTop;
|
|
3423
|
+
left = clampedPosition.left + scrollLeft;
|
|
3424
|
+
}
|
|
3425
|
+
return { top, left, width: menuWidth };
|
|
3426
|
+
}
|
|
3427
|
+
clampToViewport(position, menuWidth, menuHeight) {
|
|
3428
|
+
const clampedTop = Math.max(OverlayComponent.VIEWPORT_MARGIN, Math.min(position.top, window.innerHeight - menuHeight - OverlayComponent.VIEWPORT_MARGIN));
|
|
3429
|
+
const clampedLeft = Math.max(OverlayComponent.VIEWPORT_MARGIN, Math.min(position.left, window.innerWidth - menuWidth - OverlayComponent.VIEWPORT_MARGIN));
|
|
3430
|
+
return { top: clampedTop, left: clampedLeft };
|
|
3324
3431
|
}
|
|
3325
3432
|
parseWidth(triggerWidth) {
|
|
3326
3433
|
if (this.width() === 'stretch')
|
|
@@ -3328,6 +3435,7 @@ class OverlayComponent {
|
|
|
3328
3435
|
const w = parseFloat(this.width());
|
|
3329
3436
|
return isNaN(w) ? OverlayComponent.DEFAULT_MENU_WIDTH : w;
|
|
3330
3437
|
}
|
|
3438
|
+
// ================== RESIZE HANDLING ==================
|
|
3331
3439
|
addResizeListener() {
|
|
3332
3440
|
if (!isPlatformBrowser(this.platformId))
|
|
3333
3441
|
return;
|
|
@@ -3344,61 +3452,94 @@ class OverlayComponent {
|
|
|
3344
3452
|
const wasMobile = this._isMobile();
|
|
3345
3453
|
this.updateMobileDetection();
|
|
3346
3454
|
const isNowMobile = this._isMobile();
|
|
3347
|
-
// If mobile state changed, re-render the overlay
|
|
3348
3455
|
if (wasMobile !== isNowMobile) {
|
|
3349
|
-
// Destroy and recreate portal to apply correct styles
|
|
3350
3456
|
this.destroyPortal();
|
|
3351
3457
|
this.createPortal();
|
|
3352
|
-
// Recalculate position if now on desktop
|
|
3353
3458
|
if (!isNowMobile && this.triggerButtonRef) {
|
|
3354
3459
|
this.calculatePosition();
|
|
3355
3460
|
}
|
|
3356
3461
|
}
|
|
3357
3462
|
else if (!isNowMobile && this.triggerButtonRef) {
|
|
3358
|
-
// If still on desktop, just recalculate position
|
|
3359
3463
|
this.calculatePosition();
|
|
3360
3464
|
}
|
|
3361
3465
|
};
|
|
3466
|
+
// ================== PORTAL MANAGEMENT ==================
|
|
3362
3467
|
createPortal() {
|
|
3363
3468
|
if (!this.menuTemplate || !this.contentTemplate)
|
|
3364
3469
|
return;
|
|
3470
|
+
this.createPortalTemplate();
|
|
3471
|
+
this.createPortalContainer();
|
|
3472
|
+
this.setupPortalEventListeners();
|
|
3473
|
+
this.createPortalOutlet();
|
|
3474
|
+
this.attachPortalContent();
|
|
3475
|
+
// Focus trap will be set up in openOverlay()
|
|
3476
|
+
this.applyMenuPositioning();
|
|
3477
|
+
}
|
|
3478
|
+
createPortalTemplate() {
|
|
3365
3479
|
this.portal = new TemplatePortal(this.menuTemplate, this.viewContainerRef);
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
this.portalContainer
|
|
3480
|
+
}
|
|
3481
|
+
createPortalContainer() {
|
|
3482
|
+
this.portalContainer = this.getDocument().createElement('div');
|
|
3483
|
+
this.configurePortalContainerStyles();
|
|
3484
|
+
this.getDocument().body.appendChild(this.portalContainer);
|
|
3485
|
+
}
|
|
3486
|
+
configurePortalContainerStyles() {
|
|
3487
|
+
if (!this.portalContainer)
|
|
3488
|
+
return;
|
|
3489
|
+
this.portalContainer.style.position = this._isMobile() ? 'fixed' : 'absolute';
|
|
3369
3490
|
this.portalContainer.style.top = '0';
|
|
3370
3491
|
this.portalContainer.style.left = '0';
|
|
3371
3492
|
this.portalContainer.style.width = '100%';
|
|
3372
3493
|
this.portalContainer.style.height = '100%';
|
|
3373
3494
|
this.portalContainer.style.zIndex = '1000';
|
|
3374
|
-
this.portalContainer.style.pointerEvents = 'auto';
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
this.portalContainer
|
|
3378
|
-
|
|
3495
|
+
this.portalContainer.style.pointerEvents = 'auto';
|
|
3496
|
+
}
|
|
3497
|
+
setupPortalEventListeners() {
|
|
3498
|
+
if (!this.portalContainer)
|
|
3499
|
+
return;
|
|
3500
|
+
this.boundPortalClickHandler = this.onPortalClick.bind(this);
|
|
3501
|
+
this.portalContainer.addEventListener('click', this.boundPortalClickHandler);
|
|
3502
|
+
}
|
|
3503
|
+
createPortalOutlet() {
|
|
3504
|
+
if (!this.portalContainer)
|
|
3505
|
+
return;
|
|
3379
3506
|
this.portalOutlet = new DomPortalOutlet(this.portalContainer, null, this.applicationRef, this.viewContainerRef.injector);
|
|
3507
|
+
}
|
|
3508
|
+
attachPortalContent() {
|
|
3509
|
+
if (!this.portalOutlet || !this.portal)
|
|
3510
|
+
return;
|
|
3380
3511
|
this.portalOutlet.attach(this.portal);
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
// Mobile: clear desktop positioning styles
|
|
3396
|
-
menuEl.style.position = '';
|
|
3397
|
-
menuEl.style.top = '';
|
|
3398
|
-
menuEl.style.left = '';
|
|
3399
|
-
menuEl.style.width = '';
|
|
3400
|
-
}
|
|
3512
|
+
}
|
|
3513
|
+
applyMenuPositioning() {
|
|
3514
|
+
const menuEl = this.portalContainer?.querySelector('.c-overlay__menu');
|
|
3515
|
+
if (!menuEl)
|
|
3516
|
+
return;
|
|
3517
|
+
this.configureMenuElement(menuEl);
|
|
3518
|
+
this.applyPositioningStyles(menuEl);
|
|
3519
|
+
}
|
|
3520
|
+
configureMenuElement(menuEl) {
|
|
3521
|
+
menuEl.style.pointerEvents = 'auto';
|
|
3522
|
+
}
|
|
3523
|
+
applyPositioningStyles(menuEl) {
|
|
3524
|
+
if (this._isMobile()) {
|
|
3525
|
+
this.applyMobilePositioning(menuEl);
|
|
3401
3526
|
}
|
|
3527
|
+
else {
|
|
3528
|
+
this.applyDesktopPositioning(menuEl);
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
applyMobilePositioning(menuEl) {
|
|
3532
|
+
menuEl.style.position = '';
|
|
3533
|
+
menuEl.style.top = '';
|
|
3534
|
+
menuEl.style.left = '';
|
|
3535
|
+
menuEl.style.width = '';
|
|
3536
|
+
}
|
|
3537
|
+
applyDesktopPositioning(menuEl) {
|
|
3538
|
+
const pos = this._menuPosition();
|
|
3539
|
+
menuEl.style.position = 'absolute';
|
|
3540
|
+
menuEl.style.top = `${pos.top}px`;
|
|
3541
|
+
menuEl.style.left = `${pos.left}px`;
|
|
3542
|
+
menuEl.style.width = `${pos.width}px`;
|
|
3402
3543
|
}
|
|
3403
3544
|
destroyPortal() {
|
|
3404
3545
|
if (this.portalOutlet) {
|
|
@@ -3408,32 +3549,171 @@ class OverlayComponent {
|
|
|
3408
3549
|
this.portal = undefined;
|
|
3409
3550
|
}
|
|
3410
3551
|
if (this.portalContainer && this.portalContainer.parentNode) {
|
|
3411
|
-
|
|
3412
|
-
|
|
3552
|
+
if (this.boundPortalClickHandler) {
|
|
3553
|
+
this.portalContainer.removeEventListener('click', this.boundPortalClickHandler);
|
|
3554
|
+
this.boundPortalClickHandler = undefined;
|
|
3555
|
+
}
|
|
3413
3556
|
this.portalContainer.parentNode.removeChild(this.portalContainer);
|
|
3414
3557
|
}
|
|
3415
3558
|
this.portalContainer = undefined;
|
|
3416
3559
|
}
|
|
3560
|
+
// ================== SCROLL MANAGEMENT ==================
|
|
3417
3561
|
blockBodyScroll() {
|
|
3418
3562
|
if (!isPlatformBrowser(this.platformId))
|
|
3419
3563
|
return;
|
|
3420
|
-
|
|
3421
|
-
this.
|
|
3422
|
-
|
|
3423
|
-
|
|
3564
|
+
this.originalBodyOverflow = this.getDocument().body.style.overflow;
|
|
3565
|
+
this.getDocument().body.style.overflow = 'hidden';
|
|
3566
|
+
this.getDocument().body.style.position = 'fixed';
|
|
3567
|
+
this.getDocument().body.style.width = '100%';
|
|
3568
|
+
this.getDocument().body.style.top = `-${window.pageYOffset}px`;
|
|
3569
|
+
this.getDocument().documentElement.style.overflow = 'hidden';
|
|
3424
3570
|
}
|
|
3425
3571
|
unblockBodyScroll() {
|
|
3426
3572
|
if (!isPlatformBrowser(this.platformId))
|
|
3427
3573
|
return;
|
|
3428
|
-
|
|
3574
|
+
const scrollY = this.getDocument().body.style.top;
|
|
3429
3575
|
if (this.originalBodyOverflow !== undefined) {
|
|
3430
|
-
|
|
3576
|
+
this.getDocument().body.style.overflow = this.originalBodyOverflow;
|
|
3431
3577
|
}
|
|
3432
3578
|
else {
|
|
3433
|
-
|
|
3579
|
+
this.getDocument().body.style.overflow = '';
|
|
3580
|
+
}
|
|
3581
|
+
this.getDocument().body.style.position = '';
|
|
3582
|
+
this.getDocument().body.style.width = '';
|
|
3583
|
+
this.getDocument().body.style.top = '';
|
|
3584
|
+
this.getDocument().documentElement.style.overflow = '';
|
|
3585
|
+
if (scrollY) {
|
|
3586
|
+
window.scrollTo(0, parseInt(scrollY || '0') * -1);
|
|
3434
3587
|
}
|
|
3435
3588
|
this.originalBodyOverflow = undefined;
|
|
3436
3589
|
}
|
|
3590
|
+
// ================== FOCUS MANAGEMENT ==================
|
|
3591
|
+
trapFocus() {
|
|
3592
|
+
if (!this.portalContainer) {
|
|
3593
|
+
return;
|
|
3594
|
+
}
|
|
3595
|
+
// Search for menu element in entire document, not just within portalContainer
|
|
3596
|
+
const doc = this.getDocument();
|
|
3597
|
+
const menuEl = doc.querySelector('.c-overlay__menu');
|
|
3598
|
+
if (!menuEl) {
|
|
3599
|
+
setTimeout(() => this.trapFocus(), 10);
|
|
3600
|
+
return;
|
|
3601
|
+
}
|
|
3602
|
+
// CDK FocusTrap
|
|
3603
|
+
this.focusTrap = this.focusTrapFactory.create(menuEl);
|
|
3604
|
+
this.focusTrap.focusInitialElement();
|
|
3605
|
+
}
|
|
3606
|
+
// ================== ESCAPE KEY HANDLING ==================
|
|
3607
|
+
setupEscapeKeyListener() {
|
|
3608
|
+
if (!isPlatformBrowser(this.platformId))
|
|
3609
|
+
return;
|
|
3610
|
+
this.escapeKeyHandler = (event) => {
|
|
3611
|
+
if (event.key === 'Escape' && this.isOpen() && !this.isClosing()) {
|
|
3612
|
+
event.preventDefault();
|
|
3613
|
+
this.closeOverlay();
|
|
3614
|
+
}
|
|
3615
|
+
};
|
|
3616
|
+
this.getDocument().addEventListener('keydown', this.escapeKeyHandler);
|
|
3617
|
+
}
|
|
3618
|
+
removeEscapeKeyListener() {
|
|
3619
|
+
if (!isPlatformBrowser(this.platformId))
|
|
3620
|
+
return;
|
|
3621
|
+
if (this.escapeKeyHandler) {
|
|
3622
|
+
this.getDocument().removeEventListener('keydown', this.escapeKeyHandler);
|
|
3623
|
+
this.escapeKeyHandler = undefined;
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
// ================== FOCUS RESTORATION ==================
|
|
3627
|
+
restoreFocusToTrigger() {
|
|
3628
|
+
const doc = this.getDocument();
|
|
3629
|
+
// Prefer to return focus to trigger button
|
|
3630
|
+
if (this.triggerButtonRef && doc.contains(this.triggerButtonRef)) {
|
|
3631
|
+
const focusableElement = this.findFocusableButton(this.triggerButtonRef);
|
|
3632
|
+
if (focusableElement) {
|
|
3633
|
+
focusableElement.focus({ preventScroll: true });
|
|
3634
|
+
return;
|
|
3635
|
+
}
|
|
3636
|
+
}
|
|
3637
|
+
// Si no hay trigger, devolvemos el foco al elemento que estaba activo antes
|
|
3638
|
+
if (this.previouslyFocusedElement && doc.contains(this.previouslyFocusedElement)) {
|
|
3639
|
+
const focusableElement = this.findFocusableButton(this.previouslyFocusedElement);
|
|
3640
|
+
if (focusableElement) {
|
|
3641
|
+
focusableElement.focus({ preventScroll: true });
|
|
3642
|
+
return;
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
// Safety fallback
|
|
3646
|
+
doc.body.focus();
|
|
3647
|
+
}
|
|
3648
|
+
findFocusableButton(element) {
|
|
3649
|
+
// If element is already a focusable button, return it
|
|
3650
|
+
if (element.tagName === 'BUTTON' && !element.hasAttribute('disabled')) {
|
|
3651
|
+
return element;
|
|
3652
|
+
}
|
|
3653
|
+
// If it's a lib-button or custom component, search for internal button
|
|
3654
|
+
const button = element.querySelector('button:not([disabled])');
|
|
3655
|
+
if (button) {
|
|
3656
|
+
return button;
|
|
3657
|
+
}
|
|
3658
|
+
// Search for any focusable element inside
|
|
3659
|
+
const focusableSelectors = [
|
|
3660
|
+
'button:not([disabled])',
|
|
3661
|
+
'input:not([disabled])',
|
|
3662
|
+
'select:not([disabled])',
|
|
3663
|
+
'textarea:not([disabled])',
|
|
3664
|
+
'a[href]',
|
|
3665
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
3666
|
+
];
|
|
3667
|
+
const focusable = element.querySelector(focusableSelectors.join(', '));
|
|
3668
|
+
return focusable;
|
|
3669
|
+
}
|
|
3670
|
+
releaseFocusTrap() {
|
|
3671
|
+
if (this.focusTrap) {
|
|
3672
|
+
this.focusTrap.destroy();
|
|
3673
|
+
this.focusTrap = undefined;
|
|
3674
|
+
}
|
|
3675
|
+
this.removeEscapeKeyListener();
|
|
3676
|
+
}
|
|
3677
|
+
// ================== INERT OUTSIDE ELEMENTS ==================
|
|
3678
|
+
makeOutsideElementsInert() {
|
|
3679
|
+
if (!isPlatformBrowser(this.platformId))
|
|
3680
|
+
return;
|
|
3681
|
+
this.inertElements = [];
|
|
3682
|
+
const doc = this.getDocument();
|
|
3683
|
+
const bodyChildren = Array.from(doc.body.children);
|
|
3684
|
+
bodyChildren.forEach(el => {
|
|
3685
|
+
if (el !== this.portalContainer && !el.hasAttribute('aria-hidden')) {
|
|
3686
|
+
el.inert = true; // Hace que no sean focusables ni interactuables
|
|
3687
|
+
this.inertElements.push(el);
|
|
3688
|
+
}
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3691
|
+
restoreOutsideElements() {
|
|
3692
|
+
if (!isPlatformBrowser(this.platformId))
|
|
3693
|
+
return;
|
|
3694
|
+
this.inertElements.forEach(el => {
|
|
3695
|
+
el.inert = false;
|
|
3696
|
+
});
|
|
3697
|
+
this.inertElements = [];
|
|
3698
|
+
}
|
|
3699
|
+
destroyFocusTrap() {
|
|
3700
|
+
this.releaseFocusTrap();
|
|
3701
|
+
this.restoreOutsideElements();
|
|
3702
|
+
}
|
|
3703
|
+
cleanupTriggerListener() {
|
|
3704
|
+
if (this.triggerButtonRef && this.triggerKeydownHandler) {
|
|
3705
|
+
this.triggerButtonRef.removeEventListener('keydown', this.triggerKeydownHandler);
|
|
3706
|
+
this.triggerKeydownHandler = undefined;
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
listenToNavigation() {
|
|
3710
|
+
this.navigationSub?.unsubscribe(); // Clean up previous subscription
|
|
3711
|
+
this.navigationSub = this.router.events.subscribe(event => {
|
|
3712
|
+
if (event instanceof NavigationStart && this.isOpen()) {
|
|
3713
|
+
this.closeOverlay();
|
|
3714
|
+
}
|
|
3715
|
+
});
|
|
3716
|
+
}
|
|
3437
3717
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: OverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3438
3718
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: OverlayComponent, isStandalone: true, selector: "lib-overlay", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "contentTemplate", first: true, predicate: TemplateRef, descendants: true, static: true }, { propertyName: "footerTemplate", first: true, predicate: ["footer"], descendants: true, static: true }], viewQueries: [{ propertyName: "menuTemplate", first: true, predicate: ["menuTemplate"], descendants: true, static: true }], ngImport: i0, template: "\n\n\n<!-- Portal template for both desktop and mobile -->\n<ng-template #menuTemplate>\n <div class=\"c-overlay\" [ngClass]=\"getClasses()\">\n <!-- Backdrop for mobile -->\n @if (_isMobile() && (isOpen() || isClosing())) {\n <div\n class=\"c-overlay__backdrop\"\n [ngClass]=\"getBackdropClasses()\"\n (click)=\"onBackdropClick()\"\n (keydown.escape)=\"onEscapeKey()\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close overlay\"\n ></div>\n }\n\n <!-- Overlay Menu -->\n @if (isOpen() || isClosing()) {\n <div\n class=\"c-overlay__menu\"\n [ngClass]=\"getMenuClasses()\"\n [ngStyle]=\"getMenuStyles()\"\n #overlayMenu\n >\n <div class=\"c-overlay__content\">\n <!-- Main content projection -->\n <ng-container *ngTemplateOutlet=\"contentTemplate\"></ng-container>\n </div>\n \n <!-- Footer slot for mobile action buttons -->\n @if (_isMobile() && footerTemplate) {\n <div class=\"c-overlay__footer\">\n <ng-container *ngTemplateOutlet=\"footerTemplate\"></ng-container>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>", styles: [".c-overlay{position:relative}.c-overlay__backdrop{position:fixed;inset:0;z-index:999;background-color:var(--color-effect-overlay);opacity:0;transition:opacity .2s ease-in-out;display:none}.c-overlay__backdrop--open{opacity:1}.c-overlay__menu{position:absolute;margin-top:2px;z-index:1000;background-color:var(--color-core-background-surface-raised);border:var(--size-border-width-sm) solid var(--color-core-border-soft);border-radius:var(--size-textfield-border-radius);box-shadow:var(--elevation-raised);max-height:320px;min-width:200px;overflow:hidden;display:flex;flex-direction:column;opacity:0;transform:scale(.95);animation:overlay-enter .2s ease-out forwards;transform-origin:top center}.c-overlay__menu--fixed{position:fixed;min-width:0}.c-overlay__menu--right{left:0;right:auto}.c-overlay__menu--left{left:auto;right:0}.c-overlay__menu--center{left:50%;right:auto;transform:translate(-50%) scale(.95);animation:overlay-enter-center .2s ease-out forwards}.c-overlay__content{flex:1;overflow-y:auto}.c-overlay__footer{display:none}@keyframes overlay-enter{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes overlay-enter-center{0%{opacity:0;transform:translate(-50%) scale(.95)}to{opacity:1;transform:translate(-50%) scale(1)}}@keyframes overlay-exit{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:scale(.95)}}@media (max-width: 768px){.c-overlay__backdrop{display:block;z-index:999}.c-overlay__menu{position:fixed;bottom:0;left:0;right:0;width:100%;max-width:none;max-height:100vh;margin-top:0;border-radius:0;animation:none;z-index:1001;opacity:1;display:flex;flex-direction:column}.c-overlay__content{flex:1;overflow-y:auto;overflow-x:hidden;max-height:100vh;width:100%;min-width:0}.c-overlay__content>*{max-width:100%!important;width:100%!important;box-sizing:border-box!important;word-wrap:break-word!important;overflow-wrap:break-word!important;overflow-x:hidden!important}.c-overlay__content *{max-width:100%;box-sizing:border-box;word-wrap:break-word;overflow-wrap:break-word}.c-overlay--open .c-overlay__menu{transform:translateY(0)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: PortalModule }] });
|
|
3439
3719
|
}
|
|
@@ -5905,18 +6185,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
5905
6185
|
* - **default**: Shows custom header content
|
|
5906
6186
|
* - **navigation**: Shows back button with title in header
|
|
5907
6187
|
*/
|
|
5908
|
-
class
|
|
6188
|
+
class SidebarProgrammaticComponent {
|
|
5909
6189
|
visible = signal(false);
|
|
5910
6190
|
state = signal('default');
|
|
5911
6191
|
title = signal('');
|
|
5912
6192
|
hasSlotHeader = signal(false);
|
|
5913
|
-
|
|
6193
|
+
savedHeaderContent = signal([]);
|
|
5914
6194
|
setVisible(visible) {
|
|
5915
6195
|
this.visible.set(visible);
|
|
5916
6196
|
}
|
|
6197
|
+
updateTitle(title) {
|
|
6198
|
+
if (this.hasSlotHeader()) {
|
|
6199
|
+
this.saveHeaderContent();
|
|
6200
|
+
this.removeSlotHeader();
|
|
6201
|
+
}
|
|
6202
|
+
this.title.set(title);
|
|
6203
|
+
}
|
|
5917
6204
|
setConfig(config) {
|
|
5918
6205
|
if (config.title !== undefined) {
|
|
5919
|
-
this.
|
|
6206
|
+
this.updateTitle(config.title);
|
|
5920
6207
|
}
|
|
5921
6208
|
if (config.state !== undefined) {
|
|
5922
6209
|
this.state.set(config.state);
|
|
@@ -5929,7 +6216,15 @@ class SidebarComponent {
|
|
|
5929
6216
|
// This method is overridden by the service
|
|
5930
6217
|
}
|
|
5931
6218
|
onBackNavigation() {
|
|
5932
|
-
|
|
6219
|
+
this.state.set('default');
|
|
6220
|
+
if (this.savedHeaderContent()) {
|
|
6221
|
+
setTimeout(() => {
|
|
6222
|
+
this.restoreHeaderFooterContent();
|
|
6223
|
+
}, 0);
|
|
6224
|
+
}
|
|
6225
|
+
else {
|
|
6226
|
+
this.updateTitle(this.title());
|
|
6227
|
+
}
|
|
5933
6228
|
}
|
|
5934
6229
|
onCloseButtonClick() {
|
|
5935
6230
|
// This method is overridden by the service
|
|
@@ -5937,19 +6232,64 @@ class SidebarComponent {
|
|
|
5937
6232
|
onArrowKeyNavigation(direction) {
|
|
5938
6233
|
// This method is overridden by the content component
|
|
5939
6234
|
}
|
|
5940
|
-
|
|
5941
|
-
|
|
6235
|
+
restoreHeaderFooterContent() {
|
|
6236
|
+
const headerContainer = document.querySelector('.c-sidebar__header-default');
|
|
6237
|
+
if (headerContainer) {
|
|
6238
|
+
headerContainer.innerHTML = '';
|
|
6239
|
+
const savedElements = this.savedHeaderContent();
|
|
6240
|
+
savedElements.forEach((element) => {
|
|
6241
|
+
const clonedElement = element.cloneNode(true);
|
|
6242
|
+
headerContainer.appendChild(clonedElement);
|
|
6243
|
+
});
|
|
6244
|
+
this.removeDuplicateContent();
|
|
6245
|
+
this.hasSlotHeader.set(true);
|
|
6246
|
+
}
|
|
6247
|
+
}
|
|
6248
|
+
removeDuplicateContent() {
|
|
6249
|
+
const contentContainer = document.querySelector('.c-sidebar__body');
|
|
6250
|
+
if (contentContainer) {
|
|
6251
|
+
const slotHeaderContent = contentContainer.querySelector('[slot="header"]');
|
|
6252
|
+
if (slotHeaderContent) {
|
|
6253
|
+
slotHeaderContent.remove();
|
|
6254
|
+
}
|
|
6255
|
+
const slotFooterContent = contentContainer.querySelector('[slot="footer"]');
|
|
6256
|
+
if (slotFooterContent) {
|
|
6257
|
+
slotFooterContent.remove();
|
|
6258
|
+
}
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6261
|
+
saveHeaderContent() {
|
|
6262
|
+
const headerContainer = document.querySelector('.c-sidebar__header-default');
|
|
6263
|
+
if (headerContainer) {
|
|
6264
|
+
const elements = Array.from(headerContainer.children);
|
|
6265
|
+
this.savedHeaderContent.set(elements);
|
|
6266
|
+
}
|
|
6267
|
+
}
|
|
6268
|
+
removeSlotHeader() {
|
|
6269
|
+
const headerContainer = document.querySelector('.c-sidebar__header-default');
|
|
6270
|
+
if (headerContainer) {
|
|
6271
|
+
const slotHeaderContent = headerContainer.querySelector('[slot="header"]');
|
|
6272
|
+
if (slotHeaderContent) {
|
|
6273
|
+
slotHeaderContent.remove();
|
|
6274
|
+
}
|
|
6275
|
+
const customHeaderItems = headerContainer.querySelectorAll('[data-custom-header="true"]');
|
|
6276
|
+
customHeaderItems.forEach(item => item.remove());
|
|
6277
|
+
this.hasSlotHeader.set(false);
|
|
6278
|
+
}
|
|
6279
|
+
}
|
|
6280
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarProgrammaticComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6281
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: SidebarProgrammaticComponent, isStandalone: true, selector: "lib-sidebar-programmatic", ngImport: i0, template: "<div class=\"c-sidebar\" [ngClass]=\"'c-sidebar--' + state() + (visible() ? ' c-sidebar--visible' : ' c-sidebar--hide')\">\n <!-- Backdrop -->\n <div\n class=\"c-sidebar__backdrop\"\n [ngClass]=\"{'c-sidebar__backdrop--open': visible()}\"\n (click)=\"onBackdropClick()\"\n (keydown.escape)=\"onEscapeKey()\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close sidebar\"\n ></div>\n\n <!-- Sidebar Content -->\n <aside\n class=\"c-sidebar__content\"\n [ngClass]=\"'c-sidebar__content--' + state()\"\n (keydown.escape)=\"onEscapeKey()\"\n role=\"dialog\"\n tabindex=\"-1\"\n >\n <!-- Header -->\n <header class=\"c-sidebar__header\">\n <div class=\"c-sidebar__header-content\">\n <div class=\"c-sidebar__header-default\">\n @if (state() === 'default') {\n @if (hasSlotHeader()) {\n <ng-content select=\"[slot=header]\"></ng-content>\n } @else if (title()) {\n <div class=\"c-sidebar__header-title\">{{ title() }}</div>\n }\n }\n </div>\n \n @if (state() === 'navigation') {\n <div class=\"c-sidebar__header-navigation\">\n <lib-button-icon \n iconName=\"caretleft-regular\" \n variant=\"neutral\" \n size=\"sm\"\n ariaLabel=\"Back\"\n (clicked)=\"onBackNavigation()\">\n </lib-button-icon>\n <div class=\"c-sidebar__header-title\">{{ title() }}</div>\n </div>\n }\n </div>\n <lib-button-icon \n iconName=\"x-regular\" \n variant=\"neutral\" \n size=\"sm\"\n ariaLabel=\"Close\"\n (clicked)=\"onCloseButtonClick()\">\n </lib-button-icon>\n </header>\n \n <!-- Body Content -->\n <div class=\"c-sidebar__body\">\n <ng-content></ng-content>\n </div>\n \n <!-- Footer Content -->\n <footer class=\"c-sidebar__footer\" [ngClass]=\"{'c-sidebar__footer--hidden': state() === 'navigation'}\">\n <div class=\"c-sidebar__footer-content\">\n <ng-content select=\"[slot=footer]\"></ng-content>\n </div>\n </footer>\n </aside>\n</div>\n", styles: [".c-sidebar{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:1000}.c-sidebar__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:var(--color-effect-overlay);opacity:0;transition:opacity .2s ease-in-out;z-index:999}.c-sidebar__backdrop--open{opacity:1}.c-sidebar__content{display:flex;flex-direction:column;width:100%;height:100vh;background:var(--color-core-background-surface-floating);border-right:var(--size-border-width-sm) solid var(--color-core-border-soft);box-shadow:0 4px 8px 0 var(--color-effect-shadow-soft),0 0 4px 0 var(--color-effect-shadow-soft);position:fixed;top:0;left:0;z-index:1000;transform:translate(-100%);transition:transform .33s ease-out}@media (min-width: 768px){.c-sidebar__content{width:360px;max-width:360px}}.c-sidebar--visible .c-sidebar__content{transform:translate(0)}.c-sidebar--hide .c-sidebar__content{transform:translate(-100%)}.c-sidebar__header{padding:var(--space-component-padding-lg) var(--space-container-padding-md);border-bottom:var(--size-border-width-sm) solid var(--color-core-border-soft);background:var(--color-core-background-default);display:flex;align-items:center;justify-content:space-between;gap:var(--space-container-gap-sm)}.c-sidebar__header-content{height:2rem;display:flex;align-items:center;flex:1}.c-sidebar__header-title{flex:1;color:var(--color-core-content-default);font-family:var(--typography-label-lg-default-family, Satoshi);font-size:var(--typography-label-lg-default-size);font-style:normal;font-weight:var(--typography-label-lg-default-weight);line-height:var(--typography-label-lg-default-line-height);letter-spacing:var(--typography-label-lg-default-letter-spacing)}.c-sidebar__header-navigation{display:flex;align-items:center;gap:var(--space-container-gap-xs)}.c-sidebar__body{padding:var(--space-component-padding-sm);flex:1;overflow-y:auto}@media (min-width: 768px){.c-sidebar__body{padding:var(--space-component-padding-lg) var(--space-component-padding-md)}}.c-sidebar__footer{padding:var(--space-container-padding-sm);border-top:var(--size-border-width-sm) solid var(--color-core-border-soft);flex-shrink:0}.c-sidebar__footer--hidden{display:none}.c-sidebar__footer-content{display:flex;flex-direction:column;gap:var(--space-component-gap-xs)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ButtonIconComponent, selector: "lib-button-icon", inputs: ["ariaLabel", "variant", "size", "iconName", "disabled", "loading", "skeletonActive"], outputs: ["clicked"] }] });
|
|
5942
6282
|
}
|
|
5943
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type:
|
|
6283
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarProgrammaticComponent, decorators: [{
|
|
5944
6284
|
type: Component,
|
|
5945
|
-
args: [{ selector: 'lib-sidebar', imports: [CommonModule, ButtonIconComponent, NgClass], template: "<div class=\"c-sidebar\" [ngClass]=\"'c-sidebar--' + state() + (visible() ? ' c-sidebar--visible' : ' c-sidebar--hide')\">\n <!-- Backdrop -->\n <div\n class=\"c-sidebar__backdrop\"\n [ngClass]=\"{'c-sidebar__backdrop--open': visible()}\"\n (click)=\"onBackdropClick()\"\n (keydown.escape)=\"onEscapeKey()\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close sidebar\"\n ></div>\n\n <!-- Sidebar Content -->\n <aside\n class=\"c-sidebar__content\"\n [ngClass]=\"'c-sidebar__content--' + state()\"\n (keydown.escape)=\"onEscapeKey()\"\n
|
|
6285
|
+
args: [{ selector: 'lib-sidebar-programmatic', imports: [CommonModule, ButtonIconComponent, NgClass], template: "<div class=\"c-sidebar\" [ngClass]=\"'c-sidebar--' + state() + (visible() ? ' c-sidebar--visible' : ' c-sidebar--hide')\">\n <!-- Backdrop -->\n <div\n class=\"c-sidebar__backdrop\"\n [ngClass]=\"{'c-sidebar__backdrop--open': visible()}\"\n (click)=\"onBackdropClick()\"\n (keydown.escape)=\"onEscapeKey()\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close sidebar\"\n ></div>\n\n <!-- Sidebar Content -->\n <aside\n class=\"c-sidebar__content\"\n [ngClass]=\"'c-sidebar__content--' + state()\"\n (keydown.escape)=\"onEscapeKey()\"\n role=\"dialog\"\n tabindex=\"-1\"\n >\n <!-- Header -->\n <header class=\"c-sidebar__header\">\n <div class=\"c-sidebar__header-content\">\n <div class=\"c-sidebar__header-default\">\n @if (state() === 'default') {\n @if (hasSlotHeader()) {\n <ng-content select=\"[slot=header]\"></ng-content>\n } @else if (title()) {\n <div class=\"c-sidebar__header-title\">{{ title() }}</div>\n }\n }\n </div>\n \n @if (state() === 'navigation') {\n <div class=\"c-sidebar__header-navigation\">\n <lib-button-icon \n iconName=\"caretleft-regular\" \n variant=\"neutral\" \n size=\"sm\"\n ariaLabel=\"Back\"\n (clicked)=\"onBackNavigation()\">\n </lib-button-icon>\n <div class=\"c-sidebar__header-title\">{{ title() }}</div>\n </div>\n }\n </div>\n <lib-button-icon \n iconName=\"x-regular\" \n variant=\"neutral\" \n size=\"sm\"\n ariaLabel=\"Close\"\n (clicked)=\"onCloseButtonClick()\">\n </lib-button-icon>\n </header>\n \n <!-- Body Content -->\n <div class=\"c-sidebar__body\">\n <ng-content></ng-content>\n </div>\n \n <!-- Footer Content -->\n <footer class=\"c-sidebar__footer\" [ngClass]=\"{'c-sidebar__footer--hidden': state() === 'navigation'}\">\n <div class=\"c-sidebar__footer-content\">\n <ng-content select=\"[slot=footer]\"></ng-content>\n </div>\n </footer>\n </aside>\n</div>\n", styles: [".c-sidebar{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:1000}.c-sidebar__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:var(--color-effect-overlay);opacity:0;transition:opacity .2s ease-in-out;z-index:999}.c-sidebar__backdrop--open{opacity:1}.c-sidebar__content{display:flex;flex-direction:column;width:100%;height:100vh;background:var(--color-core-background-surface-floating);border-right:var(--size-border-width-sm) solid var(--color-core-border-soft);box-shadow:0 4px 8px 0 var(--color-effect-shadow-soft),0 0 4px 0 var(--color-effect-shadow-soft);position:fixed;top:0;left:0;z-index:1000;transform:translate(-100%);transition:transform .33s ease-out}@media (min-width: 768px){.c-sidebar__content{width:360px;max-width:360px}}.c-sidebar--visible .c-sidebar__content{transform:translate(0)}.c-sidebar--hide .c-sidebar__content{transform:translate(-100%)}.c-sidebar__header{padding:var(--space-component-padding-lg) var(--space-container-padding-md);border-bottom:var(--size-border-width-sm) solid var(--color-core-border-soft);background:var(--color-core-background-default);display:flex;align-items:center;justify-content:space-between;gap:var(--space-container-gap-sm)}.c-sidebar__header-content{height:2rem;display:flex;align-items:center;flex:1}.c-sidebar__header-title{flex:1;color:var(--color-core-content-default);font-family:var(--typography-label-lg-default-family, Satoshi);font-size:var(--typography-label-lg-default-size);font-style:normal;font-weight:var(--typography-label-lg-default-weight);line-height:var(--typography-label-lg-default-line-height);letter-spacing:var(--typography-label-lg-default-letter-spacing)}.c-sidebar__header-navigation{display:flex;align-items:center;gap:var(--space-container-gap-xs)}.c-sidebar__body{padding:var(--space-component-padding-sm);flex:1;overflow-y:auto}@media (min-width: 768px){.c-sidebar__body{padding:var(--space-component-padding-lg) var(--space-component-padding-md)}}.c-sidebar__footer{padding:var(--space-container-padding-sm);border-top:var(--size-border-width-sm) solid var(--color-core-border-soft);flex-shrink:0}.c-sidebar__footer--hidden{display:none}.c-sidebar__footer-content{display:flex;flex-direction:column;gap:var(--space-component-gap-xs)}\n"] }]
|
|
5946
6286
|
}] });
|
|
5947
6287
|
|
|
5948
6288
|
class SidebarService {
|
|
5949
6289
|
appRef = inject(ApplicationRef);
|
|
5950
6290
|
injector = inject(Injector);
|
|
5951
6291
|
open(component, config = {}) {
|
|
5952
|
-
const sidebarRef = createComponent(
|
|
6292
|
+
const sidebarRef = createComponent(SidebarProgrammaticComponent, {
|
|
5953
6293
|
environmentInjector: this.appRef.injector,
|
|
5954
6294
|
elementInjector: this.injector,
|
|
5955
6295
|
});
|
|
@@ -5975,35 +6315,7 @@ class SidebarService {
|
|
|
5975
6315
|
// Append all remaining content to main container
|
|
5976
6316
|
setTimeout(() => {
|
|
5977
6317
|
sidebarRef.instance.setVisible(true);
|
|
5978
|
-
|
|
5979
|
-
const contentContainer = sidebarRef.location.nativeElement.querySelector('.c-sidebar__body');
|
|
5980
|
-
const headerContainer = sidebarRef.location.nativeElement.querySelector('.c-sidebar__header-content');
|
|
5981
|
-
const footerContainer = sidebarRef.location.nativeElement.querySelector('.c-sidebar__footer-content');
|
|
5982
|
-
// Handle header content
|
|
5983
|
-
const headerContent = contentElement.querySelector('[slot="header"]');
|
|
5984
|
-
if (headerContent && headerContainer) {
|
|
5985
|
-
const headerItems = headerContent.children;
|
|
5986
|
-
Array.from(headerItems).forEach(item => {
|
|
5987
|
-
headerContainer.appendChild(item);
|
|
5988
|
-
});
|
|
5989
|
-
headerContent.remove();
|
|
5990
|
-
sidebarRef.instance.hasSlotHeader.set(true);
|
|
5991
|
-
}
|
|
5992
|
-
// Handle footer content
|
|
5993
|
-
const footerContent = contentElement.querySelector('[slot="footer"]');
|
|
5994
|
-
if (footerContent && footerContainer) {
|
|
5995
|
-
const footerItems = footerContent.children;
|
|
5996
|
-
Array.from(footerItems).forEach(item => {
|
|
5997
|
-
footerContainer.appendChild(item);
|
|
5998
|
-
});
|
|
5999
|
-
footerContent.remove();
|
|
6000
|
-
sidebarRef.instance.hasSlotFooter.set(true);
|
|
6001
|
-
}
|
|
6002
|
-
// Add remaining content to body
|
|
6003
|
-
const remainingContent = contentElement.children;
|
|
6004
|
-
Array.from(remainingContent).forEach(item => {
|
|
6005
|
-
contentContainer.appendChild(item);
|
|
6006
|
-
});
|
|
6318
|
+
this.moveContentToSidebar(contentRef, sidebarRef);
|
|
6007
6319
|
}, 50);
|
|
6008
6320
|
return {
|
|
6009
6321
|
close: (resultValue) => {
|
|
@@ -6012,6 +6324,9 @@ class SidebarService {
|
|
|
6012
6324
|
},
|
|
6013
6325
|
afterClosed: () => afterClosedPromise,
|
|
6014
6326
|
getContentComponent: () => contentRef.instance,
|
|
6327
|
+
updateTitle: (title) => {
|
|
6328
|
+
sidebarRef.instance.updateTitle(title);
|
|
6329
|
+
},
|
|
6015
6330
|
};
|
|
6016
6331
|
}
|
|
6017
6332
|
handleClose(sidebarRef, contentRef, resolvePromise, config, result) {
|
|
@@ -6028,6 +6343,47 @@ class SidebarService {
|
|
|
6028
6343
|
this.closeSidebar(sidebarRef, contentRef, resolvePromise, result);
|
|
6029
6344
|
}
|
|
6030
6345
|
}
|
|
6346
|
+
moveHeaderToSidebar(contentElement, sidebarRef) {
|
|
6347
|
+
const headerContainer = sidebarRef.location.nativeElement.querySelector('.c-sidebar__header-default');
|
|
6348
|
+
const headerContent = contentElement.querySelector('[slot="header"]');
|
|
6349
|
+
if (headerContent && headerContainer) {
|
|
6350
|
+
const headerItems = headerContent.children;
|
|
6351
|
+
Array.from(headerItems).forEach(item => {
|
|
6352
|
+
item.setAttribute('data-custom-header', 'true');
|
|
6353
|
+
headerContainer.appendChild(item);
|
|
6354
|
+
});
|
|
6355
|
+
headerContent.remove();
|
|
6356
|
+
sidebarRef.instance.hasSlotHeader.set(true);
|
|
6357
|
+
}
|
|
6358
|
+
}
|
|
6359
|
+
moveFooterToSidebar(contentElement, sidebarRef) {
|
|
6360
|
+
const footerContainer = sidebarRef.location.nativeElement.querySelector('.c-sidebar__footer-content');
|
|
6361
|
+
const footerContent = contentElement.querySelector('[slot="footer"]');
|
|
6362
|
+
if (footerContent && footerContainer) {
|
|
6363
|
+
const footerItems = footerContent.children;
|
|
6364
|
+
Array.from(footerItems).forEach(item => {
|
|
6365
|
+
footerContainer.appendChild(item);
|
|
6366
|
+
});
|
|
6367
|
+
footerContent.remove();
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6370
|
+
moveContentToSidebar(contentRef, sidebarRef) {
|
|
6371
|
+
const contentElement = contentRef.location.nativeElement;
|
|
6372
|
+
const contentContainer = sidebarRef.location.nativeElement.querySelector('.c-sidebar__body');
|
|
6373
|
+
// Handle header content
|
|
6374
|
+
this.moveHeaderToSidebar(contentElement, sidebarRef);
|
|
6375
|
+
// Handle footer content
|
|
6376
|
+
this.moveFooterToSidebar(contentElement, sidebarRef);
|
|
6377
|
+
// Add remaining content to body
|
|
6378
|
+
const remainingContent = contentElement.children;
|
|
6379
|
+
Array.from(remainingContent).forEach(item => {
|
|
6380
|
+
contentContainer.appendChild(item);
|
|
6381
|
+
});
|
|
6382
|
+
// If no content was moved, try to move the entire content element
|
|
6383
|
+
if (remainingContent.length === 0) {
|
|
6384
|
+
contentContainer.appendChild(contentElement);
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
6031
6387
|
closeSidebar(sidebarRef, contentRef, resolvePromise, result) {
|
|
6032
6388
|
sidebarRef.instance.setVisible(false);
|
|
6033
6389
|
setTimeout(() => {
|
|
@@ -6050,116 +6406,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
6050
6406
|
|
|
6051
6407
|
class BasicSidebarMenuComponent {
|
|
6052
6408
|
selectedItem;
|
|
6053
|
-
selectedChildId = '';
|
|
6054
6409
|
sidebar;
|
|
6055
|
-
currentIndex = 0;
|
|
6056
6410
|
menuItems = [];
|
|
6411
|
+
isInSettingsSubLevel = false;
|
|
6057
6412
|
initializeComponent() {
|
|
6058
6413
|
this.initializeMenuItems();
|
|
6059
|
-
this.selectedItem = this.menuItems[0];
|
|
6060
|
-
this.currentIndex = 0;
|
|
6061
|
-
this.initializeSidebarTitle();
|
|
6062
|
-
this.setupKeyboardNavigation();
|
|
6063
|
-
}
|
|
6064
|
-
initializeSidebarTitle() {
|
|
6065
|
-
if (this.sidebar && !this.sidebar.title() && this.selectedItem) {
|
|
6066
|
-
this.sidebar.title.set(this.selectedItem.label());
|
|
6067
|
-
}
|
|
6068
6414
|
}
|
|
6069
6415
|
onItemClick(menuItem) {
|
|
6070
6416
|
const label = menuItem.label();
|
|
6071
6417
|
this.selectedItem = menuItem;
|
|
6072
|
-
this.
|
|
6073
|
-
|
|
6074
|
-
// Only set title if we don't have slot header content
|
|
6075
|
-
if (this.sidebar && !this.sidebar.hasSlotHeader()) {
|
|
6076
|
-
this.sidebar.title.set(label);
|
|
6418
|
+
if (this.hasSubNavigation(menuItem)) {
|
|
6419
|
+
this.navigateToSubLevel(menuItem);
|
|
6077
6420
|
}
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6421
|
+
else {
|
|
6422
|
+
if (this.sidebar && !this.sidebar.hasSlotHeader()) {
|
|
6423
|
+
this.sidebar.updateTitle(label);
|
|
6424
|
+
}
|
|
6425
|
+
this.sidebar?.state.set('default');
|
|
6081
6426
|
}
|
|
6082
|
-
console.log('Clicked item:', {
|
|
6083
|
-
label: label,
|
|
6084
|
-
element: menuItem,
|
|
6085
|
-
index: this.currentIndex
|
|
6086
|
-
});
|
|
6087
6427
|
}
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
this.selectedChildId = `${parent.label().toLowerCase()}-${childLabel.toLowerCase()}`;
|
|
6092
|
-
// Only set title and navigation state if we don't have slot header content
|
|
6093
|
-
if (this.sidebar && !this.sidebar.hasSlotHeader()) {
|
|
6094
|
-
this.sidebar?.title.set(childLabel);
|
|
6095
|
-
this.sidebar?.state.set('navigation');
|
|
6096
|
-
this.sidebar.onBackNavigation = () => this.onBackNavigation();
|
|
6097
|
-
}
|
|
6098
|
-
console.log('Clicked child item:', {
|
|
6099
|
-
label: childLabel,
|
|
6100
|
-
parent: parent.label(),
|
|
6101
|
-
selectedItem: this.selectedItem,
|
|
6102
|
-
selectedChildId: this.selectedChildId
|
|
6103
|
-
});
|
|
6428
|
+
hasSubNavigation(menuItem) {
|
|
6429
|
+
// Override this method in child components to define which items have sub-navigation
|
|
6430
|
+
return false;
|
|
6104
6431
|
}
|
|
6105
|
-
|
|
6106
|
-
this.
|
|
6107
|
-
this.
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
if (this.sidebar && !this.sidebar.hasSlotHeader()) {
|
|
6111
|
-
this.sidebar.title.set(this.menuItems[0].label());
|
|
6432
|
+
navigateToSubLevel(menuItem) {
|
|
6433
|
+
this.isInSettingsSubLevel = true;
|
|
6434
|
+
if (this.sidebar) {
|
|
6435
|
+
this.sidebar.updateTitle(menuItem.label());
|
|
6436
|
+
this.sidebar.state.set('navigation');
|
|
6112
6437
|
}
|
|
6113
|
-
|
|
6114
|
-
|
|
6438
|
+
}
|
|
6439
|
+
navigateToMainLevel() {
|
|
6440
|
+
this.isInSettingsSubLevel = false;
|
|
6115
6441
|
}
|
|
6116
6442
|
onFooterItemClick(menuItem) {
|
|
6117
6443
|
const label = menuItem.label();
|
|
6118
6444
|
this.selectedItem = menuItem;
|
|
6119
|
-
this.selectedChildId = '';
|
|
6120
|
-
this.sidebar?.title.set(label);
|
|
6121
|
-
this.sidebar?.state.set('default');
|
|
6122
6445
|
if (this.sidebar) {
|
|
6123
|
-
this.sidebar.
|
|
6124
|
-
|
|
6125
|
-
console.log('Footer item clicked:', {
|
|
6126
|
-
label: label,
|
|
6127
|
-
element: menuItem
|
|
6128
|
-
});
|
|
6129
|
-
}
|
|
6130
|
-
setupKeyboardNavigation() {
|
|
6131
|
-
if (this.sidebar) {
|
|
6132
|
-
this.sidebar.onArrowKeyNavigation = (direction) => {
|
|
6133
|
-
this.navigateMenu(direction);
|
|
6134
|
-
};
|
|
6135
|
-
}
|
|
6136
|
-
}
|
|
6137
|
-
navigateMenu(direction) {
|
|
6138
|
-
if (!this.menuItems.length) {
|
|
6139
|
-
return;
|
|
6140
|
-
}
|
|
6141
|
-
if (direction === 'down') {
|
|
6142
|
-
this.currentIndex = (this.currentIndex + 1) % this.menuItems.length;
|
|
6143
|
-
}
|
|
6144
|
-
else {
|
|
6145
|
-
this.currentIndex = this.currentIndex === 0 ? this.menuItems.length - 1 : this.currentIndex - 1;
|
|
6146
|
-
}
|
|
6147
|
-
const newItem = this.menuItems[this.currentIndex];
|
|
6148
|
-
this.selectedItem = newItem;
|
|
6149
|
-
this.selectedChildId = '';
|
|
6150
|
-
// Only set title if we don't have slot header content
|
|
6151
|
-
if (this.sidebar && !this.sidebar.hasSlotHeader()) {
|
|
6152
|
-
this.sidebar.title.set(newItem.label());
|
|
6153
|
-
}
|
|
6154
|
-
this.sidebar?.state.set('default');
|
|
6155
|
-
if (this.sidebar) {
|
|
6156
|
-
this.sidebar.onBackNavigation = () => this.onBackNavigation();
|
|
6446
|
+
this.sidebar.title.set(label);
|
|
6447
|
+
this.sidebar.state.set('default');
|
|
6157
6448
|
}
|
|
6158
|
-
console.log('Keyboard navigation:', {
|
|
6159
|
-
direction,
|
|
6160
|
-
newIndex: this.currentIndex,
|
|
6161
|
-
label: newItem.label()
|
|
6162
|
-
});
|
|
6163
6449
|
}
|
|
6164
6450
|
}
|
|
6165
6451
|
class SidebarWithFooterComponent extends BasicSidebarMenuComponent {
|
|
@@ -6167,29 +6453,24 @@ class SidebarWithFooterComponent extends BasicSidebarMenuComponent {
|
|
|
6167
6453
|
settingsItem;
|
|
6168
6454
|
profileItem;
|
|
6169
6455
|
helpItem;
|
|
6456
|
+
// Sub-level items
|
|
6457
|
+
generalSettingsItem;
|
|
6458
|
+
privacySettingsItem;
|
|
6459
|
+
notificationsSettingsItem;
|
|
6460
|
+
securitySettingsItem;
|
|
6461
|
+
selectedSubItem;
|
|
6170
6462
|
ngAfterViewInit() {
|
|
6171
6463
|
this.initializeComponent();
|
|
6172
6464
|
}
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
label: 'Reports',
|
|
6183
|
-
selected: false,
|
|
6184
|
-
onClick: () => this.onChildClick('Reports', this.dashboardItem)
|
|
6185
|
-
},
|
|
6186
|
-
{
|
|
6187
|
-
id: 'dashboard-overview',
|
|
6188
|
-
label: 'Overview',
|
|
6189
|
-
selected: false,
|
|
6190
|
-
onClick: () => this.onChildClick('Overview', this.dashboardItem)
|
|
6191
|
-
}
|
|
6192
|
-
];
|
|
6465
|
+
hasSubNavigation(menuItem) {
|
|
6466
|
+
return menuItem === this.settingsItem;
|
|
6467
|
+
}
|
|
6468
|
+
onSubItemClick(subItem) {
|
|
6469
|
+
this.selectedSubItem = subItem;
|
|
6470
|
+
if (this.sidebar && !this.sidebar.hasSlotHeader()) {
|
|
6471
|
+
this.sidebar.updateTitle(subItem.label());
|
|
6472
|
+
}
|
|
6473
|
+
}
|
|
6193
6474
|
initializeMenuItems() {
|
|
6194
6475
|
this.menuItems = [
|
|
6195
6476
|
this.dashboardItem,
|
|
@@ -6199,13 +6480,24 @@ class SidebarWithFooterComponent extends BasicSidebarMenuComponent {
|
|
|
6199
6480
|
];
|
|
6200
6481
|
}
|
|
6201
6482
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarWithFooterComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6202
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
6483
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: SidebarWithFooterComponent, isStandalone: true, selector: "lib-sidebar-with-footer", viewQueries: [{ propertyName: "dashboardItem", first: true, predicate: ["dashboardItem"], descendants: true }, { propertyName: "settingsItem", first: true, predicate: ["settingsItem"], descendants: true }, { propertyName: "profileItem", first: true, predicate: ["profileItem"], descendants: true }, { propertyName: "helpItem", first: true, predicate: ["helpItem"], descendants: true }, { propertyName: "generalSettingsItem", first: true, predicate: ["generalSettingsItem"], descendants: true }, { propertyName: "privacySettingsItem", first: true, predicate: ["privacySettingsItem"], descendants: true }, { propertyName: "notificationsSettingsItem", first: true, predicate: ["notificationsSettingsItem"], descendants: true }, { propertyName: "securitySettingsItem", first: true, predicate: ["securitySettingsItem"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
6484
|
+
@if (sidebar?.state() === 'default') {
|
|
6485
|
+
<div slot="header">
|
|
6486
|
+
<div style="display: flex; align-items: center; gap: 12px; padding: 16px;">
|
|
6487
|
+
<div style="width: 32px; height: 32px; background: #17a2b8; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">
|
|
6488
|
+
L
|
|
6489
|
+
</div>
|
|
6490
|
+
<div>
|
|
6491
|
+
<h3 style="margin: 0; font-size: 16px; font-weight: 600; color: var(--color-core-content-default);">My App</h3>
|
|
6492
|
+
<p style="margin: 0; font-size: 12px; color: var(--color-core-content-secondary);">Welcome back!</p>
|
|
6493
|
+
</div>
|
|
6494
|
+
</div>
|
|
6495
|
+
</div>
|
|
6203
6496
|
<lib-menu-item
|
|
6204
6497
|
#dashboardItem
|
|
6205
6498
|
label="Dashboard"
|
|
6206
6499
|
icon="home-regular"
|
|
6207
6500
|
[selected]="selectedItem === dashboardItem"
|
|
6208
|
-
[children]="dashboardChildren"
|
|
6209
6501
|
(clicked)="onItemClick(dashboardItem)">
|
|
6210
6502
|
</lib-menu-item>
|
|
6211
6503
|
<lib-menu-item
|
|
@@ -6241,109 +6533,46 @@ class SidebarWithFooterComponent extends BasicSidebarMenuComponent {
|
|
|
6241
6533
|
(clicked)="onFooterItemClick(logoutItem)">
|
|
6242
6534
|
</lib-menu-item>
|
|
6243
6535
|
</div>
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
type: Component,
|
|
6248
|
-
args: [{
|
|
6249
|
-
selector: 'lib-sidebar-with-footer',
|
|
6250
|
-
template: `
|
|
6536
|
+
}
|
|
6537
|
+
<!-- Settings Sub-Level -->
|
|
6538
|
+
@if (sidebar?.state() === 'navigation' && isInSettingsSubLevel) {
|
|
6251
6539
|
<lib-menu-item
|
|
6252
|
-
#
|
|
6253
|
-
label="
|
|
6254
|
-
icon="
|
|
6255
|
-
[selected]="
|
|
6256
|
-
|
|
6257
|
-
(clicked)="onItemClick(dashboardItem)">
|
|
6540
|
+
#generalSettingsItem
|
|
6541
|
+
label="General"
|
|
6542
|
+
icon="settings-regular"
|
|
6543
|
+
[selected]="selectedSubItem === generalSettingsItem"
|
|
6544
|
+
(clicked)="onSubItemClick(generalSettingsItem)">
|
|
6258
6545
|
</lib-menu-item>
|
|
6259
6546
|
<lib-menu-item
|
|
6260
|
-
#
|
|
6261
|
-
label="
|
|
6262
|
-
icon="
|
|
6263
|
-
[selected]="
|
|
6264
|
-
(clicked)="
|
|
6547
|
+
#privacySettingsItem
|
|
6548
|
+
label="Privacy"
|
|
6549
|
+
icon="shield-regular"
|
|
6550
|
+
[selected]="selectedSubItem === privacySettingsItem"
|
|
6551
|
+
(clicked)="onSubItemClick(privacySettingsItem)">
|
|
6265
6552
|
</lib-menu-item>
|
|
6266
6553
|
<lib-menu-item
|
|
6267
|
-
#
|
|
6268
|
-
label="
|
|
6269
|
-
icon="
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
(clicked)="onItemClick(profileItem)">
|
|
6554
|
+
#notificationsSettingsItem
|
|
6555
|
+
label="Notifications"
|
|
6556
|
+
icon="bell-regular"
|
|
6557
|
+
[selected]="selectedSubItem === notificationsSettingsItem"
|
|
6558
|
+
(clicked)="onSubItemClick(notificationsSettingsItem)">
|
|
6273
6559
|
</lib-menu-item>
|
|
6274
6560
|
<lib-menu-item
|
|
6275
|
-
#
|
|
6276
|
-
label="
|
|
6277
|
-
icon="
|
|
6278
|
-
[selected]="
|
|
6279
|
-
(clicked)="
|
|
6561
|
+
#securitySettingsItem
|
|
6562
|
+
label="Security"
|
|
6563
|
+
icon="lock-regular"
|
|
6564
|
+
[selected]="selectedSubItem === securitySettingsItem"
|
|
6565
|
+
(clicked)="onSubItemClick(securitySettingsItem)">
|
|
6280
6566
|
</lib-menu-item>
|
|
6281
|
-
|
|
6282
|
-
<div slot="footer">
|
|
6283
|
-
<lib-menu-item
|
|
6284
|
-
#logoutItem
|
|
6285
|
-
label="Logout"
|
|
6286
|
-
icon="signout-regular"
|
|
6287
|
-
[showArrowIcon]="false"
|
|
6288
|
-
[selected]="selectedItem === logoutItem"
|
|
6289
|
-
(clicked)="onFooterItemClick(logoutItem)">
|
|
6290
|
-
</lib-menu-item>
|
|
6291
|
-
</div>
|
|
6292
|
-
`,
|
|
6293
|
-
imports: [CommonModule, MenuItemComponent, MenuChildItemComponent],
|
|
6294
|
-
standalone: true,
|
|
6295
|
-
}]
|
|
6296
|
-
}], propDecorators: { dashboardItem: [{
|
|
6297
|
-
type: ViewChild,
|
|
6298
|
-
args: ['dashboardItem']
|
|
6299
|
-
}], settingsItem: [{
|
|
6300
|
-
type: ViewChild,
|
|
6301
|
-
args: ['settingsItem']
|
|
6302
|
-
}], profileItem: [{
|
|
6303
|
-
type: ViewChild,
|
|
6304
|
-
args: ['profileItem']
|
|
6305
|
-
}], helpItem: [{
|
|
6306
|
-
type: ViewChild,
|
|
6307
|
-
args: ['helpItem']
|
|
6308
|
-
}] } });
|
|
6309
|
-
class SidebarWithHeaderComponent extends BasicSidebarMenuComponent {
|
|
6310
|
-
dashboardItem;
|
|
6311
|
-
settingsItem;
|
|
6312
|
-
profileItem;
|
|
6313
|
-
helpItem;
|
|
6314
|
-
ngAfterViewInit() {
|
|
6315
|
-
this.initializeComponent();
|
|
6316
6567
|
}
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
id: 'dashboard-reports',
|
|
6326
|
-
label: 'Reports',
|
|
6327
|
-
selected: false,
|
|
6328
|
-
onClick: () => this.onChildClick('Reports', this.dashboardItem)
|
|
6329
|
-
},
|
|
6330
|
-
{
|
|
6331
|
-
id: 'dashboard-overview',
|
|
6332
|
-
label: 'Overview',
|
|
6333
|
-
selected: false,
|
|
6334
|
-
onClick: () => this.onChildClick('Overview', this.dashboardItem)
|
|
6335
|
-
}
|
|
6336
|
-
];
|
|
6337
|
-
initializeMenuItems() {
|
|
6338
|
-
this.menuItems = [
|
|
6339
|
-
this.dashboardItem,
|
|
6340
|
-
this.settingsItem,
|
|
6341
|
-
this.profileItem,
|
|
6342
|
-
this.helpItem
|
|
6343
|
-
];
|
|
6344
|
-
}
|
|
6345
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarWithHeaderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6346
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: SidebarWithHeaderComponent, isStandalone: true, selector: "lib-sidebar-with-header", viewQueries: [{ propertyName: "dashboardItem", first: true, predicate: ["dashboardItem"], descendants: true }, { propertyName: "settingsItem", first: true, predicate: ["settingsItem"], descendants: true }, { propertyName: "profileItem", first: true, predicate: ["profileItem"], descendants: true }, { propertyName: "helpItem", first: true, predicate: ["helpItem"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
6568
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: MenuItemComponent, selector: "lib-menu-item", inputs: ["label", "icon", "disabled", "selected", "showArrowIcon", "tagLabel", "children"], outputs: ["clicked"] }] });
|
|
6569
|
+
}
|
|
6570
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarWithFooterComponent, decorators: [{
|
|
6571
|
+
type: Component,
|
|
6572
|
+
args: [{
|
|
6573
|
+
selector: 'lib-sidebar-with-footer',
|
|
6574
|
+
template: `
|
|
6575
|
+
@if (sidebar?.state() === 'default') {
|
|
6347
6576
|
<div slot="header">
|
|
6348
6577
|
<div style="display: flex; align-items: center; gap: 12px; padding: 16px;">
|
|
6349
6578
|
<div style="width: 32px; height: 32px; background: #17a2b8; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">
|
|
@@ -6355,13 +6584,11 @@ class SidebarWithHeaderComponent extends BasicSidebarMenuComponent {
|
|
|
6355
6584
|
</div>
|
|
6356
6585
|
</div>
|
|
6357
6586
|
</div>
|
|
6358
|
-
|
|
6359
6587
|
<lib-menu-item
|
|
6360
6588
|
#dashboardItem
|
|
6361
6589
|
label="Dashboard"
|
|
6362
6590
|
icon="home-regular"
|
|
6363
6591
|
[selected]="selectedItem === dashboardItem"
|
|
6364
|
-
[children]="dashboardChildren"
|
|
6365
6592
|
(clicked)="onItemClick(dashboardItem)">
|
|
6366
6593
|
</lib-menu-item>
|
|
6367
6594
|
<lib-menu-item
|
|
@@ -6386,57 +6613,51 @@ class SidebarWithHeaderComponent extends BasicSidebarMenuComponent {
|
|
|
6386
6613
|
[selected]="selectedItem === helpItem"
|
|
6387
6614
|
(clicked)="onItemClick(helpItem)">
|
|
6388
6615
|
</lib-menu-item>
|
|
6389
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: MenuItemComponent, selector: "lib-menu-item", inputs: ["label", "icon", "disabled", "selected", "showArrowIcon", "tagLabel", "children"], outputs: ["clicked"] }] });
|
|
6390
|
-
}
|
|
6391
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarWithHeaderComponent, decorators: [{
|
|
6392
|
-
type: Component,
|
|
6393
|
-
args: [{
|
|
6394
|
-
selector: 'lib-sidebar-with-header',
|
|
6395
|
-
template: `
|
|
6396
|
-
<div slot="header">
|
|
6397
|
-
<div style="display: flex; align-items: center; gap: 12px; padding: 16px;">
|
|
6398
|
-
<div style="width: 32px; height: 32px; background: #17a2b8; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">
|
|
6399
|
-
L
|
|
6400
|
-
</div>
|
|
6401
|
-
<div>
|
|
6402
|
-
<h3 style="margin: 0; font-size: 16px; font-weight: 600; color: var(--color-core-content-default);">My App</h3>
|
|
6403
|
-
<p style="margin: 0; font-size: 12px; color: var(--color-core-content-secondary);">Welcome back!</p>
|
|
6404
|
-
</div>
|
|
6405
|
-
</div>
|
|
6406
|
-
</div>
|
|
6407
6616
|
|
|
6617
|
+
<div slot="footer">
|
|
6618
|
+
<lib-menu-item
|
|
6619
|
+
#logoutItem
|
|
6620
|
+
label="Logout"
|
|
6621
|
+
icon="signout-regular"
|
|
6622
|
+
[showArrowIcon]="false"
|
|
6623
|
+
[selected]="selectedItem === logoutItem"
|
|
6624
|
+
(clicked)="onFooterItemClick(logoutItem)">
|
|
6625
|
+
</lib-menu-item>
|
|
6626
|
+
</div>
|
|
6627
|
+
}
|
|
6628
|
+
<!-- Settings Sub-Level -->
|
|
6629
|
+
@if (sidebar?.state() === 'navigation' && isInSettingsSubLevel) {
|
|
6408
6630
|
<lib-menu-item
|
|
6409
|
-
#
|
|
6410
|
-
label="
|
|
6411
|
-
icon="
|
|
6412
|
-
[selected]="
|
|
6413
|
-
|
|
6414
|
-
(clicked)="onItemClick(dashboardItem)">
|
|
6631
|
+
#generalSettingsItem
|
|
6632
|
+
label="General"
|
|
6633
|
+
icon="settings-regular"
|
|
6634
|
+
[selected]="selectedSubItem === generalSettingsItem"
|
|
6635
|
+
(clicked)="onSubItemClick(generalSettingsItem)">
|
|
6415
6636
|
</lib-menu-item>
|
|
6416
6637
|
<lib-menu-item
|
|
6417
|
-
#
|
|
6418
|
-
label="
|
|
6419
|
-
icon="
|
|
6420
|
-
[selected]="
|
|
6421
|
-
(clicked)="
|
|
6638
|
+
#privacySettingsItem
|
|
6639
|
+
label="Privacy"
|
|
6640
|
+
icon="shield-regular"
|
|
6641
|
+
[selected]="selectedSubItem === privacySettingsItem"
|
|
6642
|
+
(clicked)="onSubItemClick(privacySettingsItem)">
|
|
6422
6643
|
</lib-menu-item>
|
|
6423
6644
|
<lib-menu-item
|
|
6424
|
-
#
|
|
6425
|
-
label="
|
|
6426
|
-
icon="
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
(clicked)="onItemClick(profileItem)">
|
|
6645
|
+
#notificationsSettingsItem
|
|
6646
|
+
label="Notifications"
|
|
6647
|
+
icon="bell-regular"
|
|
6648
|
+
[selected]="selectedSubItem === notificationsSettingsItem"
|
|
6649
|
+
(clicked)="onSubItemClick(notificationsSettingsItem)">
|
|
6430
6650
|
</lib-menu-item>
|
|
6431
6651
|
<lib-menu-item
|
|
6432
|
-
#
|
|
6433
|
-
label="
|
|
6434
|
-
icon="
|
|
6435
|
-
[selected]="
|
|
6436
|
-
(clicked)="
|
|
6652
|
+
#securitySettingsItem
|
|
6653
|
+
label="Security"
|
|
6654
|
+
icon="lock-regular"
|
|
6655
|
+
[selected]="selectedSubItem === securitySettingsItem"
|
|
6656
|
+
(clicked)="onSubItemClick(securitySettingsItem)">
|
|
6437
6657
|
</lib-menu-item>
|
|
6658
|
+
}
|
|
6438
6659
|
`,
|
|
6439
|
-
imports: [CommonModule, MenuItemComponent
|
|
6660
|
+
imports: [CommonModule, MenuItemComponent],
|
|
6440
6661
|
standalone: true,
|
|
6441
6662
|
}]
|
|
6442
6663
|
}], propDecorators: { dashboardItem: [{
|
|
@@ -6451,8 +6672,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
6451
6672
|
}], helpItem: [{
|
|
6452
6673
|
type: ViewChild,
|
|
6453
6674
|
args: ['helpItem']
|
|
6675
|
+
}], generalSettingsItem: [{
|
|
6676
|
+
type: ViewChild,
|
|
6677
|
+
args: ['generalSettingsItem']
|
|
6678
|
+
}], privacySettingsItem: [{
|
|
6679
|
+
type: ViewChild,
|
|
6680
|
+
args: ['privacySettingsItem']
|
|
6681
|
+
}], notificationsSettingsItem: [{
|
|
6682
|
+
type: ViewChild,
|
|
6683
|
+
args: ['notificationsSettingsItem']
|
|
6684
|
+
}], securitySettingsItem: [{
|
|
6685
|
+
type: ViewChild,
|
|
6686
|
+
args: ['securitySettingsItem']
|
|
6454
6687
|
}] } });
|
|
6455
|
-
class
|
|
6688
|
+
class SidebarProgrammaticExamplesComponent {
|
|
6456
6689
|
sidebarService = inject(SidebarService);
|
|
6457
6690
|
openSidebarWithFooter() {
|
|
6458
6691
|
const sidebarRef = this.sidebarService.open(SidebarWithFooterComponent, {
|
|
@@ -6462,24 +6695,12 @@ class SidebarExamplesComponent {
|
|
|
6462
6695
|
});
|
|
6463
6696
|
sidebarRef.afterClosed().then((result) => {
|
|
6464
6697
|
if (result) {
|
|
6465
|
-
console.log('
|
|
6698
|
+
console.log('Sidebar closed with result:', result);
|
|
6466
6699
|
}
|
|
6467
6700
|
});
|
|
6468
6701
|
}
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
onClose: (closeSidebar) => {
|
|
6472
|
-
closeSidebar({ message: 'Sidebar closed successfully' });
|
|
6473
|
-
}
|
|
6474
|
-
});
|
|
6475
|
-
sidebarRef.afterClosed().then((result) => {
|
|
6476
|
-
if (result) {
|
|
6477
|
-
console.log('✅ Sidebar result:', result);
|
|
6478
|
-
}
|
|
6479
|
-
});
|
|
6480
|
-
}
|
|
6481
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarExamplesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6482
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: SidebarExamplesComponent, isStandalone: true, selector: "lib-sidebar-examples", ngImport: i0, template: `
|
|
6702
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarProgrammaticExamplesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6703
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: SidebarProgrammaticExamplesComponent, isStandalone: true, selector: "lib-sidebar-examples", ngImport: i0, template: `
|
|
6483
6704
|
<div
|
|
6484
6705
|
style="height: 90vh; padding: 24px; font-family: var(--typography-body-md-family), sans-serif;
|
|
6485
6706
|
font-weight: var(--typography-body-md-weight);
|
|
@@ -6490,8 +6711,8 @@ class SidebarExamplesComponent {
|
|
|
6490
6711
|
>
|
|
6491
6712
|
<h2>Sidebar Service Examples</h2>
|
|
6492
6713
|
<p>
|
|
6493
|
-
This demonstrates how to use the Sidebar Service
|
|
6494
|
-
|
|
6714
|
+
This demonstrates how to use the Sidebar Service with two-level navigation.
|
|
6715
|
+
Click on "Settings" to see the sub-navigation level.
|
|
6495
6716
|
</p>
|
|
6496
6717
|
|
|
6497
6718
|
<div style="margin: 24px 0;">
|
|
@@ -6510,127 +6731,17 @@ class SidebarExamplesComponent {
|
|
|
6510
6731
|
font-size: 14px;
|
|
6511
6732
|
font-weight: 500;
|
|
6512
6733
|
">
|
|
6513
|
-
Open Sidebar with
|
|
6514
|
-
</button>
|
|
6515
|
-
<button
|
|
6516
|
-
(click)="openSidebarWithHeader()"
|
|
6517
|
-
style="
|
|
6518
|
-
background: #17a2b8;
|
|
6519
|
-
color: white;
|
|
6520
|
-
border: none;
|
|
6521
|
-
padding: 12px 24px;
|
|
6522
|
-
border-radius: 6px;
|
|
6523
|
-
cursor: pointer;
|
|
6524
|
-
font-size: 14px;
|
|
6525
|
-
font-weight: 500;
|
|
6526
|
-
">
|
|
6527
|
-
Open Sidebar with custom Header
|
|
6734
|
+
Open Sidebar with Two-Level Navigation
|
|
6528
6735
|
</button>
|
|
6529
6736
|
</div>
|
|
6530
6737
|
</div>
|
|
6531
|
-
|
|
6532
|
-
<div
|
|
6533
|
-
style="margin-top: 24px; padding: 20px; background: #e3f2fd; border-radius: 8px; border: 1px solid #2196f3;"
|
|
6534
|
-
>
|
|
6535
|
-
<h3>Configuration Options Available:</h3>
|
|
6536
|
-
<ul style="margin: 0; padding-left: 20px;">
|
|
6537
|
-
<li><strong>title</strong>: string - Sidebar header title (if not provided, uses slot="header")</li>
|
|
6538
|
-
<li><strong>state</strong>: 'default' | 'navigation' - Sidebar state (default: 'default')</li>
|
|
6539
|
-
<li><strong>collapsible</strong>: boolean - Whether sidebar can be opened/closed (default: true)</li>
|
|
6540
|
-
<li><strong>onClose</strong>: function - Close event handler with result parameter</li>
|
|
6541
|
-
</ul>
|
|
6542
|
-
</div>
|
|
6543
|
-
|
|
6544
|
-
<div
|
|
6545
|
-
style="margin-top: 24px; padding: 20px; background: #f8f9fa; border-radius: 8px; border: 1px solid #6c757d;"
|
|
6546
|
-
>
|
|
6547
|
-
<h3>Header Content Options:</h3>
|
|
6548
|
-
<ul style="margin: 0; padding-left: 20px;">
|
|
6549
|
-
<li><strong>With title</strong>: Pass <code>title: "My Title"</code> in config</li>
|
|
6550
|
-
<li><strong>Custom HTML</strong>: Use slot="header" for any custom header content</li>
|
|
6551
|
-
</ul>
|
|
6552
|
-
|
|
6553
|
-
<pre style="background: #e9ecef; padding: 12px; border-radius: 4px; font-size: 12px; overflow-x: auto; margin-top: 8px;">
|
|
6554
|
-
// In your component template:
|
|
6555
|
-
<div slot="header">
|
|
6556
|
-
<a class="logo" [routerLink]="state.language()" tabindex="0">
|
|
6557
|
-
<img
|
|
6558
|
-
class="logo-full"
|
|
6559
|
-
ngSrc="{{ '{' }}{{ 'img/branding/logo_full.svg' }}{{ '}' }}"
|
|
6560
|
-
alt="logo"
|
|
6561
|
-
width="130"
|
|
6562
|
-
height="32" />
|
|
6563
|
-
</a>
|
|
6564
|
-
</div>
|
|
6565
|
-
|
|
6566
|
-
<lib-menu-item
|
|
6567
|
-
label="Dashboard"
|
|
6568
|
-
icon="home-regular"
|
|
6569
|
-
[selected]="selectedItem === dashboardItem"
|
|
6570
|
-
[children]="dashboardChildren"
|
|
6571
|
-
(clicked)="onItemClick(dashboardItem)">
|
|
6572
|
-
</lib-menu-item>
|
|
6573
|
-
<lib-menu-item
|
|
6574
|
-
label="Settings"
|
|
6575
|
-
icon="settings-regular"
|
|
6576
|
-
[selected]="selectedItem === settingsItem"
|
|
6577
|
-
[children]="settingsChildren"
|
|
6578
|
-
(clicked)="onItemClick(settingsItem)">
|
|
6579
|
-
</lib-menu-item>
|
|
6580
|
-
</pre>
|
|
6581
|
-
</div>
|
|
6582
|
-
|
|
6583
|
-
<div
|
|
6584
|
-
style="margin-top: 24px; padding: 20px; background: #f3e5f5; border-radius: 8px; border: 1px solid #9c27b0;"
|
|
6585
|
-
>
|
|
6586
|
-
<h3>Footer Content:</h3>
|
|
6587
|
-
<p style="margin: 0 0 12px 0;">Use <code>[slot="footer"]</code> to add footer content:</p>
|
|
6588
|
-
<pre style="background: #e9ecef; padding: 12px; border-radius: 4px; font-size: 12px; overflow-x: auto; margin-top: 8px;">
|
|
6589
|
-
// In your component template:
|
|
6590
|
-
<lib-menu-item label="Dashboard" icon="home-regular"></lib-menu-item>
|
|
6591
|
-
<lib-menu-item label="Settings" icon="settings-regular"></lib-menu-item>
|
|
6592
|
-
|
|
6593
|
-
<!-- Footer content -->
|
|
6594
|
-
<div slot="footer">
|
|
6595
|
-
<lib-menu-item
|
|
6596
|
-
label="Logout"
|
|
6597
|
-
icon="signout-regular"
|
|
6598
|
-
[showArrowIcon]="false">
|
|
6599
|
-
</lib-menu-item>
|
|
6600
|
-
</div>
|
|
6601
|
-
</pre>
|
|
6602
|
-
</div>
|
|
6603
|
-
|
|
6604
|
-
<div
|
|
6605
|
-
style="margin-top: 24px; padding: 20px; background: #e8f5e8; border-radius: 8px; border: 1px solid #4caf50;"
|
|
6606
|
-
>
|
|
6607
|
-
<h3>Keyboard Navigation:</h3>
|
|
6608
|
-
<ul style="margin: 0; padding-left: 20px;">
|
|
6609
|
-
<li><strong>Arrow Down (↓)</strong>: Navigate to next item or first child</li>
|
|
6610
|
-
<li><strong>Arrow Up (↑)</strong>: Navigate to previous item or parent</li>
|
|
6611
|
-
<li><strong>Escape</strong>: Close sidebar</li>
|
|
6612
|
-
<li><strong>Click outside</strong>: Close sidebar</li>
|
|
6613
|
-
</ul>
|
|
6614
|
-
</div>
|
|
6615
|
-
|
|
6616
|
-
<div
|
|
6617
|
-
style="margin-top: 24px; padding: 20px; background: #d1ecf1; border-radius: 8px; border: 1px solid #17a2b8;"
|
|
6618
|
-
>
|
|
6619
|
-
<h3>Check Console for Results:</h3>
|
|
6620
|
-
<p>
|
|
6621
|
-
Open your browser's developer console to see the callback results and
|
|
6622
|
-
sidebar interactions.
|
|
6623
|
-
</p>
|
|
6624
|
-
</div>
|
|
6738
|
+
|
|
6625
6739
|
</div>
|
|
6626
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
6740
|
+
`, isInline: true, styles: [".sidebar-content{display:flex;flex-direction:column;height:100%;padding:24px;font-family:var(--typography-body-md-family)}.sidebar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--color-core-border-default)}.sidebar-header h2{margin:0;font-size:var(--typography-heading-md-size);font-weight:var(--typography-heading-md-weight);color:var(--color-core-content-default)}.sidebar-body{flex:1;display:flex;flex-direction:column;gap:24px}.user-info{display:flex;align-items:center;gap:16px}.avatar{width:48px;height:48px;border-radius:50%;background:var(--color-core-background-secondary);display:flex;align-items:center;justify-content:center}.avatar-placeholder{font-weight:600;font-size:18px;color:var(--color-core-content-default)}.user-details h3{margin:0 0 4px;font-size:var(--typography-body-lg-size);font-weight:var(--typography-body-lg-weight);color:var(--color-core-content-default)}.user-details p{margin:0;font-size:var(--typography-body-sm-size);color:var(--color-core-content-secondary)}.role{font-weight:500;color:var(--color-core-content-default)!important}.actions-section h4,.stats-section h4{margin:0 0 12px;font-size:var(--typography-body-md-size);font-weight:600;color:var(--color-core-content-default)}.action-buttons{display:flex;flex-direction:column;gap:8px}.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.stat-item{text-align:center;padding:12px;background:var(--color-core-background-secondary);border-radius:8px}.stat-value{display:block;font-size:var(--typography-heading-sm-size);font-weight:var(--typography-heading-sm-weight);color:var(--color-core-content-default)}.stat-label{display:block;font-size:var(--typography-body-xs-size);color:var(--color-core-content-secondary);margin-top:4px}.sidebar-footer{padding-top:16px;border-top:1px solid var(--color-core-border-default)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
6627
6741
|
}
|
|
6628
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type:
|
|
6742
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarProgrammaticExamplesComponent, decorators: [{
|
|
6629
6743
|
type: Component,
|
|
6630
|
-
args: [{
|
|
6631
|
-
selector: 'lib-sidebar-examples',
|
|
6632
|
-
imports: [CommonModule],
|
|
6633
|
-
template: `
|
|
6744
|
+
args: [{ selector: 'lib-sidebar-examples', imports: [CommonModule], template: `
|
|
6634
6745
|
<div
|
|
6635
6746
|
style="height: 90vh; padding: 24px; font-family: var(--typography-body-md-family), sans-serif;
|
|
6636
6747
|
font-weight: var(--typography-body-md-weight);
|
|
@@ -6641,8 +6752,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
6641
6752
|
>
|
|
6642
6753
|
<h2>Sidebar Service Examples</h2>
|
|
6643
6754
|
<p>
|
|
6644
|
-
This demonstrates how to use the Sidebar Service
|
|
6645
|
-
|
|
6755
|
+
This demonstrates how to use the Sidebar Service with two-level navigation.
|
|
6756
|
+
Click on "Settings" to see the sub-navigation level.
|
|
6646
6757
|
</p>
|
|
6647
6758
|
|
|
6648
6759
|
<div style="margin: 24px 0;">
|
|
@@ -6661,121 +6772,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
6661
6772
|
font-size: 14px;
|
|
6662
6773
|
font-weight: 500;
|
|
6663
6774
|
">
|
|
6664
|
-
Open Sidebar with
|
|
6665
|
-
</button>
|
|
6666
|
-
<button
|
|
6667
|
-
(click)="openSidebarWithHeader()"
|
|
6668
|
-
style="
|
|
6669
|
-
background: #17a2b8;
|
|
6670
|
-
color: white;
|
|
6671
|
-
border: none;
|
|
6672
|
-
padding: 12px 24px;
|
|
6673
|
-
border-radius: 6px;
|
|
6674
|
-
cursor: pointer;
|
|
6675
|
-
font-size: 14px;
|
|
6676
|
-
font-weight: 500;
|
|
6677
|
-
">
|
|
6678
|
-
Open Sidebar with custom Header
|
|
6775
|
+
Open Sidebar with Two-Level Navigation
|
|
6679
6776
|
</button>
|
|
6680
6777
|
</div>
|
|
6681
6778
|
</div>
|
|
6682
|
-
|
|
6683
|
-
<div
|
|
6684
|
-
style="margin-top: 24px; padding: 20px; background: #e3f2fd; border-radius: 8px; border: 1px solid #2196f3;"
|
|
6685
|
-
>
|
|
6686
|
-
<h3>Configuration Options Available:</h3>
|
|
6687
|
-
<ul style="margin: 0; padding-left: 20px;">
|
|
6688
|
-
<li><strong>title</strong>: string - Sidebar header title (if not provided, uses slot="header")</li>
|
|
6689
|
-
<li><strong>state</strong>: 'default' | 'navigation' - Sidebar state (default: 'default')</li>
|
|
6690
|
-
<li><strong>collapsible</strong>: boolean - Whether sidebar can be opened/closed (default: true)</li>
|
|
6691
|
-
<li><strong>onClose</strong>: function - Close event handler with result parameter</li>
|
|
6692
|
-
</ul>
|
|
6693
|
-
</div>
|
|
6694
|
-
|
|
6695
|
-
<div
|
|
6696
|
-
style="margin-top: 24px; padding: 20px; background: #f8f9fa; border-radius: 8px; border: 1px solid #6c757d;"
|
|
6697
|
-
>
|
|
6698
|
-
<h3>Header Content Options:</h3>
|
|
6699
|
-
<ul style="margin: 0; padding-left: 20px;">
|
|
6700
|
-
<li><strong>With title</strong>: Pass <code>title: "My Title"</code> in config</li>
|
|
6701
|
-
<li><strong>Custom HTML</strong>: Use slot="header" for any custom header content</li>
|
|
6702
|
-
</ul>
|
|
6703
|
-
|
|
6704
|
-
<pre style="background: #e9ecef; padding: 12px; border-radius: 4px; font-size: 12px; overflow-x: auto; margin-top: 8px;">
|
|
6705
|
-
// In your component template:
|
|
6706
|
-
<div slot="header">
|
|
6707
|
-
<a class="logo" [routerLink]="state.language()" tabindex="0">
|
|
6708
|
-
<img
|
|
6709
|
-
class="logo-full"
|
|
6710
|
-
ngSrc="{{ '{' }}{{ 'img/branding/logo_full.svg' }}{{ '}' }}"
|
|
6711
|
-
alt="logo"
|
|
6712
|
-
width="130"
|
|
6713
|
-
height="32" />
|
|
6714
|
-
</a>
|
|
6715
|
-
</div>
|
|
6716
|
-
|
|
6717
|
-
<lib-menu-item
|
|
6718
|
-
label="Dashboard"
|
|
6719
|
-
icon="home-regular"
|
|
6720
|
-
[selected]="selectedItem === dashboardItem"
|
|
6721
|
-
[children]="dashboardChildren"
|
|
6722
|
-
(clicked)="onItemClick(dashboardItem)">
|
|
6723
|
-
</lib-menu-item>
|
|
6724
|
-
<lib-menu-item
|
|
6725
|
-
label="Settings"
|
|
6726
|
-
icon="settings-regular"
|
|
6727
|
-
[selected]="selectedItem === settingsItem"
|
|
6728
|
-
[children]="settingsChildren"
|
|
6729
|
-
(clicked)="onItemClick(settingsItem)">
|
|
6730
|
-
</lib-menu-item>
|
|
6731
|
-
</pre>
|
|
6732
|
-
</div>
|
|
6733
|
-
|
|
6734
|
-
<div
|
|
6735
|
-
style="margin-top: 24px; padding: 20px; background: #f3e5f5; border-radius: 8px; border: 1px solid #9c27b0;"
|
|
6736
|
-
>
|
|
6737
|
-
<h3>Footer Content:</h3>
|
|
6738
|
-
<p style="margin: 0 0 12px 0;">Use <code>[slot="footer"]</code> to add footer content:</p>
|
|
6739
|
-
<pre style="background: #e9ecef; padding: 12px; border-radius: 4px; font-size: 12px; overflow-x: auto; margin-top: 8px;">
|
|
6740
|
-
// In your component template:
|
|
6741
|
-
<lib-menu-item label="Dashboard" icon="home-regular"></lib-menu-item>
|
|
6742
|
-
<lib-menu-item label="Settings" icon="settings-regular"></lib-menu-item>
|
|
6743
|
-
|
|
6744
|
-
<!-- Footer content -->
|
|
6745
|
-
<div slot="footer">
|
|
6746
|
-
<lib-menu-item
|
|
6747
|
-
label="Logout"
|
|
6748
|
-
icon="signout-regular"
|
|
6749
|
-
[showArrowIcon]="false">
|
|
6750
|
-
</lib-menu-item>
|
|
6751
|
-
</div>
|
|
6752
|
-
</pre>
|
|
6753
|
-
</div>
|
|
6754
|
-
|
|
6755
|
-
<div
|
|
6756
|
-
style="margin-top: 24px; padding: 20px; background: #e8f5e8; border-radius: 8px; border: 1px solid #4caf50;"
|
|
6757
|
-
>
|
|
6758
|
-
<h3>Keyboard Navigation:</h3>
|
|
6759
|
-
<ul style="margin: 0; padding-left: 20px;">
|
|
6760
|
-
<li><strong>Arrow Down (↓)</strong>: Navigate to next item or first child</li>
|
|
6761
|
-
<li><strong>Arrow Up (↑)</strong>: Navigate to previous item or parent</li>
|
|
6762
|
-
<li><strong>Escape</strong>: Close sidebar</li>
|
|
6763
|
-
<li><strong>Click outside</strong>: Close sidebar</li>
|
|
6764
|
-
</ul>
|
|
6765
|
-
</div>
|
|
6766
|
-
|
|
6767
|
-
<div
|
|
6768
|
-
style="margin-top: 24px; padding: 20px; background: #d1ecf1; border-radius: 8px; border: 1px solid #17a2b8;"
|
|
6769
|
-
>
|
|
6770
|
-
<h3>Check Console for Results:</h3>
|
|
6771
|
-
<p>
|
|
6772
|
-
Open your browser's developer console to see the callback results and
|
|
6773
|
-
sidebar interactions.
|
|
6774
|
-
</p>
|
|
6775
|
-
</div>
|
|
6779
|
+
|
|
6776
6780
|
</div>
|
|
6777
|
-
`,
|
|
6778
|
-
|
|
6781
|
+
`, standalone: true, styles: [".sidebar-content{display:flex;flex-direction:column;height:100%;padding:24px;font-family:var(--typography-body-md-family)}.sidebar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--color-core-border-default)}.sidebar-header h2{margin:0;font-size:var(--typography-heading-md-size);font-weight:var(--typography-heading-md-weight);color:var(--color-core-content-default)}.sidebar-body{flex:1;display:flex;flex-direction:column;gap:24px}.user-info{display:flex;align-items:center;gap:16px}.avatar{width:48px;height:48px;border-radius:50%;background:var(--color-core-background-secondary);display:flex;align-items:center;justify-content:center}.avatar-placeholder{font-weight:600;font-size:18px;color:var(--color-core-content-default)}.user-details h3{margin:0 0 4px;font-size:var(--typography-body-lg-size);font-weight:var(--typography-body-lg-weight);color:var(--color-core-content-default)}.user-details p{margin:0;font-size:var(--typography-body-sm-size);color:var(--color-core-content-secondary)}.role{font-weight:500;color:var(--color-core-content-default)!important}.actions-section h4,.stats-section h4{margin:0 0 12px;font-size:var(--typography-body-md-size);font-weight:600;color:var(--color-core-content-default)}.action-buttons{display:flex;flex-direction:column;gap:8px}.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.stat-item{text-align:center;padding:12px;background:var(--color-core-background-secondary);border-radius:8px}.stat-value{display:block;font-size:var(--typography-heading-sm-size);font-weight:var(--typography-heading-sm-weight);color:var(--color-core-content-default)}.stat-label{display:block;font-size:var(--typography-body-xs-size);color:var(--color-core-content-secondary);margin-top:4px}.sidebar-footer{padding-top:16px;border-top:1px solid var(--color-core-border-default)}\n"] }]
|
|
6782
|
+
}] });
|
|
6783
|
+
|
|
6784
|
+
/**
|
|
6785
|
+
* A flexible sidebar container that can be populated with any component content.
|
|
6786
|
+
* The sidebar acts as an empty container that gets filled with dynamic content.
|
|
6787
|
+
*
|
|
6788
|
+
* @inputs
|
|
6789
|
+
* - **visible**: Controls sidebar visibility (boolean)
|
|
6790
|
+
*
|
|
6791
|
+
* @outputs
|
|
6792
|
+
* - **closed**: Emitted when sidebar is closed
|
|
6793
|
+
*/
|
|
6794
|
+
class SidebarComponent {
|
|
6795
|
+
visible = input(false);
|
|
6796
|
+
closed = output();
|
|
6797
|
+
close() {
|
|
6798
|
+
this.closed.emit();
|
|
6799
|
+
}
|
|
6800
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6801
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: SidebarComponent, isStandalone: true, selector: "lib-sidebar", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: "<div class=\"c-sidebar\" [ngClass]=\"visible() ? 'c-sidebar--visible' : 'c-sidebar--hide'\">\n <!-- Backdrop -->\n <div\n class=\"c-sidebar__backdrop\"\n [ngClass]=\"{'c-sidebar__backdrop--open': visible()}\"\n (click)=\"close()\"\n (keydown.escape)=\"close()\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close sidebar\"\n ></div>\n\n <!-- Sidebar Content -->\n <aside\n class=\"c-sidebar__content\"\n (keydown.escape)=\"close()\"\n role=\"dialog\"\n tabindex=\"-1\"\n >\n <!-- Content Container -->\n <div class=\"c-sidebar__body\">\n <ng-content></ng-content>\n </div>\n </aside>\n</div>\n", styles: [".c-sidebar{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:1000}.c-sidebar--hide{pointer-events:none;transition:visibility 0s .33s;visibility:hidden}.c-sidebar--hide .c-sidebar__backdrop{opacity:0}.c-sidebar__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:var(--color-effect-overlay);opacity:0;transition:opacity .33s ease-in-out;z-index:999}.c-sidebar__backdrop--open{opacity:1}.c-sidebar__content{display:flex;flex-direction:column;width:100%;height:100vh;background:var(--color-core-background-surface-floating);border-right:var(--size-border-width-sm) solid var(--color-core-border-soft);box-shadow:0 4px 8px 0 var(--color-effect-shadow-soft),0 0 4px 0 var(--color-effect-shadow-soft);position:fixed;top:0;left:0;z-index:1000;transform:translate(-100%);transition:transform .33s ease-out}@media (min-width: 768px){.c-sidebar__content{width:360px;max-width:360px}}.c-sidebar--visible .c-sidebar__content{transform:translate(0)}.c-sidebar--hide .c-sidebar__content{transform:translate(-100%)}.c-sidebar__body{padding:var(--space-component-padding-sm);flex:1;overflow-y:auto}@media (min-width: 768px){.c-sidebar__body{padding:var(--space-component-padding-lg) var(--space-component-padding-md)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
6802
|
+
}
|
|
6803
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SidebarComponent, decorators: [{
|
|
6804
|
+
type: Component,
|
|
6805
|
+
args: [{ selector: 'lib-sidebar', imports: [CommonModule, NgClass], template: "<div class=\"c-sidebar\" [ngClass]=\"visible() ? 'c-sidebar--visible' : 'c-sidebar--hide'\">\n <!-- Backdrop -->\n <div\n class=\"c-sidebar__backdrop\"\n [ngClass]=\"{'c-sidebar__backdrop--open': visible()}\"\n (click)=\"close()\"\n (keydown.escape)=\"close()\"\n tabindex=\"0\"\n role=\"button\"\n aria-label=\"Close sidebar\"\n ></div>\n\n <!-- Sidebar Content -->\n <aside\n class=\"c-sidebar__content\"\n (keydown.escape)=\"close()\"\n role=\"dialog\"\n tabindex=\"-1\"\n >\n <!-- Content Container -->\n <div class=\"c-sidebar__body\">\n <ng-content></ng-content>\n </div>\n </aside>\n</div>\n", styles: [".c-sidebar{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:1000}.c-sidebar--hide{pointer-events:none;transition:visibility 0s .33s;visibility:hidden}.c-sidebar--hide .c-sidebar__backdrop{opacity:0}.c-sidebar__backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:var(--color-effect-overlay);opacity:0;transition:opacity .33s ease-in-out;z-index:999}.c-sidebar__backdrop--open{opacity:1}.c-sidebar__content{display:flex;flex-direction:column;width:100%;height:100vh;background:var(--color-core-background-surface-floating);border-right:var(--size-border-width-sm) solid var(--color-core-border-soft);box-shadow:0 4px 8px 0 var(--color-effect-shadow-soft),0 0 4px 0 var(--color-effect-shadow-soft);position:fixed;top:0;left:0;z-index:1000;transform:translate(-100%);transition:transform .33s ease-out}@media (min-width: 768px){.c-sidebar__content{width:360px;max-width:360px}}.c-sidebar--visible .c-sidebar__content{transform:translate(0)}.c-sidebar--hide .c-sidebar__content{transform:translate(-100%)}.c-sidebar__body{padding:var(--space-component-padding-sm);flex:1;overflow-y:auto}@media (min-width: 768px){.c-sidebar__body{padding:var(--space-component-padding-lg) var(--space-component-padding-md)}}\n"] }]
|
|
6779
6806
|
}] });
|
|
6780
6807
|
|
|
6781
6808
|
class SocialLoginComponent {
|
|
@@ -7393,5 +7420,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
|
|
|
7393
7420
|
* Generated bundle index. Do not edit.
|
|
7394
7421
|
*/
|
|
7395
7422
|
|
|
7396
|
-
export { AccordionComponent, AlertComponent, ArrowsComponent, AvatarComponent, BadgeComponent, BasicSidebarMenuComponent, BreadcrumbComponent, ButtonComponent, ButtonIconComponent, ButtonSetComponent, CheckboxComponent, CheckboxGroupComponent, ChipsComponent, DesignTokensComponent, DropdownActionComponent, DropdownActionTriggerDirective, DropdownSelectComponent, DropdownSelectTriggerDirective, HelperTextComponent, IconComponent, InputDateComponent, InputLabelComponent, InputNumberComponent, InputPaymentComponent, InputSearchComponent, InputUploadComponent, LinkActionComponent, LinkComponent, MenuChildItemComponent, MenuItemComponent, ModalComponent, ModalService, OverlayComponent, OverlayTriggerDirective, PaginationComponent, PasswordInputComponent, RadioComponent, RadioGroupComponent, SegmentedControlComponent, SelectComponent, SidebarComponent,
|
|
7423
|
+
export { AccordionComponent, AlertComponent, ArrowsComponent, AvatarComponent, BadgeComponent, BasicSidebarMenuComponent, BreadcrumbComponent, ButtonComponent, ButtonIconComponent, ButtonSetComponent, CheckboxComponent, CheckboxGroupComponent, ChipsComponent, DesignTokensComponent, DropdownActionComponent, DropdownActionTriggerDirective, DropdownSelectComponent, DropdownSelectTriggerDirective, HelperTextComponent, IconComponent, InputDateComponent, InputLabelComponent, InputNumberComponent, InputPaymentComponent, InputSearchComponent, InputUploadComponent, LinkActionComponent, LinkComponent, MenuChildItemComponent, MenuItemComponent, ModalComponent, ModalService, OverlayComponent, OverlayTriggerDirective, PaginationComponent, PasswordInputComponent, RadioComponent, RadioGroupComponent, SegmentedControlComponent, SelectComponent, SidebarComponent, SidebarProgrammaticComponent, SidebarProgrammaticExamplesComponent, SidebarService, SidebarWithFooterComponent, SocialLoginComponent, SpinnerComponent, SwitchComponent, TabsComponent, TagComponent, TextInputComponent, TextareaComponent, ThumbnailComponent, TileComponent, ToastComponent, TooltipComponent, TooltipDirective, TooltipPosition };
|
|
7397
7424
|
//# sourceMappingURL=crowdfarming-oliva-ds.mjs.map
|