@life-cockpit/angular-ui-kit 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -6083,6 +6083,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
6083
6083
|
type: Input
|
|
6084
6084
|
}] } });
|
|
6085
6085
|
|
|
6086
|
+
/**
|
|
6087
|
+
* Badge component for displaying status, notifications, or counts.
|
|
6088
|
+
*
|
|
6089
|
+
* Features:
|
|
6090
|
+
* - Semantic color variants (primary, secondary, success, warning, error, info, neutral)
|
|
6091
|
+
* - Multiple size options (xs, sm, md, lg)
|
|
6092
|
+
* - Pill-shaped rounded mode
|
|
6093
|
+
* - Content projection for labels or count values
|
|
6094
|
+
*
|
|
6095
|
+
* @example
|
|
6096
|
+
* ```html
|
|
6097
|
+
* <lc-badge variant="primary" size="md">New</lc-badge>
|
|
6098
|
+
* <lc-badge variant="error" size="sm" [rounded]="true">5</lc-badge>
|
|
6099
|
+
* ```
|
|
6100
|
+
*/
|
|
6101
|
+
class BadgeComponent {
|
|
6102
|
+
/** Visual variant of the badge */
|
|
6103
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
6104
|
+
/** Size of the badge */
|
|
6105
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
6106
|
+
/** Whether the badge has fully rounded corners (pill shape) */
|
|
6107
|
+
rounded = input(false, ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
|
|
6108
|
+
/**
|
|
6109
|
+
* Computed CSS classes for the badge
|
|
6110
|
+
*/
|
|
6111
|
+
badgeClasses = computed(() => {
|
|
6112
|
+
const classes = ['lc-badge'];
|
|
6113
|
+
classes.push(`lc-badge--${this.variant()}`);
|
|
6114
|
+
classes.push(`lc-badge--${this.size()}`);
|
|
6115
|
+
if (this.rounded()) {
|
|
6116
|
+
classes.push('lc-badge--rounded');
|
|
6117
|
+
}
|
|
6118
|
+
return classes.join(' ');
|
|
6119
|
+
}, ...(ngDevMode ? [{ debugName: "badgeClasses" }] : /* istanbul ignore next */ []));
|
|
6120
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: BadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6121
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.10", type: BadgeComponent, isStandalone: true, selector: "lc-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span [class]=\"badgeClasses()\">\n <ng-content></ng-content>\n</span>\n", styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge--default{background-color:var(--color-neutral-200, #e5e7eb);color:var(--color-neutral-800, #1f2937)}[data-theme=dark] .lc-badge--default,:root[data-theme=dark] .lc-badge--default{background-color:var(--color-neutral-700, #374151);color:var(--color-neutral-100, #f3f4f6)}.lc-badge--primary{background-color:var(--color-primary-100, #dbeafe);color:var(--color-primary-800, #1e3a5f)}[data-theme=dark] .lc-badge--primary,:root[data-theme=dark] .lc-badge--primary{background-color:var(--color-primary-900, #1e3a5f);color:var(--color-primary-200, #bfdbfe)}.lc-badge--success{background-color:var(--color-success-light, #dcfce7);color:var(--color-success-dark, #166534)}[data-theme=dark] .lc-badge--success,:root[data-theme=dark] .lc-badge--success{background-color:#22c55e33;color:#86efac}.lc-badge--warning{background-color:var(--color-warning-light, #fef3c7);color:var(--color-warning-dark, #92400e)}[data-theme=dark] .lc-badge--warning,:root[data-theme=dark] .lc-badge--warning{background-color:#fbbf2433;color:#fde047}.lc-badge--error{background-color:var(--color-error-light, #fee2e2);color:var(--color-error-dark, #991b1b)}[data-theme=dark] .lc-badge--error,:root[data-theme=dark] .lc-badge--error{background-color:#ef444433;color:#fca5a5}.lc-badge--info{background-color:var(--color-info-light, #dbeafe);color:var(--color-info-dark, #1e40af)}[data-theme=dark] .lc-badge--info,:root[data-theme=dark] .lc-badge--info{background-color:#3b82f633;color:#93c5fd}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6122
|
+
}
|
|
6123
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: BadgeComponent, decorators: [{
|
|
6124
|
+
type: Component,
|
|
6125
|
+
args: [{ selector: 'lc-badge', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span [class]=\"badgeClasses()\">\n <ng-content></ng-content>\n</span>\n", styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge--default{background-color:var(--color-neutral-200, #e5e7eb);color:var(--color-neutral-800, #1f2937)}[data-theme=dark] .lc-badge--default,:root[data-theme=dark] .lc-badge--default{background-color:var(--color-neutral-700, #374151);color:var(--color-neutral-100, #f3f4f6)}.lc-badge--primary{background-color:var(--color-primary-100, #dbeafe);color:var(--color-primary-800, #1e3a5f)}[data-theme=dark] .lc-badge--primary,:root[data-theme=dark] .lc-badge--primary{background-color:var(--color-primary-900, #1e3a5f);color:var(--color-primary-200, #bfdbfe)}.lc-badge--success{background-color:var(--color-success-light, #dcfce7);color:var(--color-success-dark, #166534)}[data-theme=dark] .lc-badge--success,:root[data-theme=dark] .lc-badge--success{background-color:#22c55e33;color:#86efac}.lc-badge--warning{background-color:var(--color-warning-light, #fef3c7);color:var(--color-warning-dark, #92400e)}[data-theme=dark] .lc-badge--warning,:root[data-theme=dark] .lc-badge--warning{background-color:#fbbf2433;color:#fde047}.lc-badge--error{background-color:var(--color-error-light, #fee2e2);color:var(--color-error-dark, #991b1b)}[data-theme=dark] .lc-badge--error,:root[data-theme=dark] .lc-badge--error{background-color:#ef444433;color:#fca5a5}.lc-badge--info{background-color:var(--color-info-light, #dbeafe);color:var(--color-info-dark, #1e40af)}[data-theme=dark] .lc-badge--info,:root[data-theme=dark] .lc-badge--info{background-color:#3b82f633;color:#93c5fd}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"] }]
|
|
6126
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }] } });
|
|
6127
|
+
|
|
6086
6128
|
/**
|
|
6087
6129
|
* Sidenav component for application navigation sidebar.
|
|
6088
6130
|
*
|
|
@@ -6200,6 +6242,10 @@ class SidenavComponent {
|
|
|
6200
6242
|
* Event emitted when a navigation item is clicked
|
|
6201
6243
|
*/
|
|
6202
6244
|
itemClicked = new EventEmitter();
|
|
6245
|
+
/**
|
|
6246
|
+
* Event emitted when an item's action button is clicked
|
|
6247
|
+
*/
|
|
6248
|
+
itemAction = new EventEmitter();
|
|
6203
6249
|
/**
|
|
6204
6250
|
* Computed CSS classes for the sidenav
|
|
6205
6251
|
*/
|
|
@@ -6242,6 +6288,13 @@ class SidenavComponent {
|
|
|
6242
6288
|
handleItemClick(item) {
|
|
6243
6289
|
this.itemClicked.emit(item);
|
|
6244
6290
|
}
|
|
6291
|
+
/**
|
|
6292
|
+
* Handle action button click on a navigation item
|
|
6293
|
+
*/
|
|
6294
|
+
handleItemAction(event, item) {
|
|
6295
|
+
event.stopPropagation();
|
|
6296
|
+
this.itemAction.emit(item);
|
|
6297
|
+
}
|
|
6245
6298
|
/**
|
|
6246
6299
|
* Check if an item is active
|
|
6247
6300
|
*/
|
|
@@ -6284,15 +6337,15 @@ class SidenavComponent {
|
|
|
6284
6337
|
}
|
|
6285
6338
|
}
|
|
6286
6339
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: SidenavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6287
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: SidenavComponent, isStandalone: true, selector: "lc-sidenav", inputs: { isOpenInput: "isOpenInput", modeInput: "modeInput", positionInput: "positionInput", widthInput: "widthInput", ariaLabelInput: "ariaLabelInput", hasOverlayInput: "hasOverlayInput", itemsInput: "itemsInput", activeRouteInput: "activeRouteInput", collapsedInput: "collapsedInput", themeInput: ["theme", "themeInput"] }, outputs: { closed: "closed", itemClicked: "itemClicked" }, host: { listeners: { "document:keydown": "handleKeydown($event)" }, properties: { "class.lc-sidenav-container": "true", "class.lc-sidenav-container--docked": "mode() === 'docked'", "class.lc-sidenav-container--open": "isOpen()" } }, ngImport: i0, template: "<!-- Drawer mode: render with overlay and conditional visibility -->\n@if (mode() === 'drawer') {\n @if (isOpen()) {\n <!-- Overlay backdrop -->\n @if (hasOverlay()) {\n <div\n class=\"lc-sidenav__overlay\"\n (click)=\"handleClose()\"\n aria-hidden=\"true\">\n </div>\n }\n\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n }\n}\n\n<!-- Docked mode: always render, visibility controlled by CSS -->\n@if (mode() === 'docked') {\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n}\n\n<!-- Shared sidenav panel template -->\n<ng-template #sidenavPanel>\n <aside\n [class]=\"sidenavClasses()\"\n [ngStyle]=\"sidenavStyles()\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel()\">\n\n <!-- Close button (drawer mode only) -->\n @if (mode() === 'drawer') {\n <button\n type=\"button\"\n class=\"lc-sidenav__close\"\n (click)=\"handleClose()\"\n aria-label=\"Close navigation\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Navigation items (if provided) -->\n @if (items().length > 0) {\n <nav class=\"lc-sidenav__nav\" [class.lc-sidenav__nav--docked]=\"mode() === 'docked'\">\n @for (item of sortedItems(); track item.id) {\n <!-- Section headline -->\n @if (item.isSection) {\n <div class=\"lc-sidenav__section\">\n <h2 class=\"lc-sidenav__section-title\">{{ item.label }}</h2>\n @if (item.children?.length) {\n <ul class=\"lc-sidenav__section-items\">\n @for (child of item.children; track child.id) {\n <li>\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: child.route === '/' }\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\">\n @if (child.icon) {\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n </a>\n </li>\n }\n </ul>\n }\n </div>\n } @else if (item.children?.length) {\n <!-- Parent item with children (collapsible group) -->\n <button\n type=\"button\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--parent\"\n [class.lc-sidenav__nav-item--expanded]=\"isExpanded(item)\"\n [class.lc-sidenav__nav-item--active]=\"hasActiveChild(item)\"\n (click)=\"toggleExpanded(item)\"\n [attr.aria-expanded]=\"isExpanded(item)\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n <lc-icon name=\"chevron-down\" size=\"xs\" [decorative]=\"true\" class=\"lc-sidenav__nav-chevron\" />\n </button>\n @if (isExpanded(item)) {\n <div class=\"lc-sidenav__nav-children\">\n @for (child of item.children; track child.id) {\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\">\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n </a>\n }\n </div>\n }\n } @else {\n <!-- Simple item without children -->\n <a\n [routerLink]=\"item.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === '/' }\"\n class=\"lc-sidenav__nav-item\"\n (click)=\"handleItemClick(item)\"\n [attr.aria-current]=\"isItemActive(item) ? 'page' : null\"\n [title]=\"collapsed() ? item.label : ''\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n </a>\n }\n }\n </nav>\n }\n\n <!-- Content projection (for custom content) -->\n <div class=\"lc-sidenav__content\" [class.lc-sidenav__content--docked]=\"mode() === 'docked'\">\n <ng-content></ng-content>\n </div>\n </aside>\n</ng-template>\n", styles: [".lc-sidenav-container{position:relative;z-index:1000}.lc-sidenav-container--docked{position:static;z-index:auto;height:100%}.lc-sidenav__overlay{position:fixed;inset:0;background-color:#00000080;opacity:0;animation:fadeIn .3s ease-out forwards;z-index:1000;cursor:pointer}@media(prefers-reduced-motion:reduce){.lc-sidenav__overlay{animation:none;opacity:1}}.lc-sidenav{--lc-sidenav-bg: var(--color-background, #ffffff);--lc-sidenav-fg: #374151;--lc-sidenav-fg-active: #111827;--lc-sidenav-border: var(--color-border, #e5e7eb);--lc-sidenav-hover-bg: #f3f4f6;--lc-sidenav-section-fg: #6b7280;position:fixed;top:0;bottom:0;background-color:var(--lc-sidenav-bg);box-shadow:var(--elevation-3, 0 10px 15px -3px rgba(0, 0, 0, .1));z-index:1001;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}.lc-sidenav--left{left:0}.lc-sidenav--right{right:0}.lc-sidenav--drawer.lc-sidenav--left{animation:slideInLeft .3s ease-out}.lc-sidenav--drawer.lc-sidenav--right{animation:slideInRight .3s ease-out}@media(prefers-reduced-motion:reduce){.lc-sidenav--drawer{animation:none!important}}.lc-sidenav--docked{position:static;z-index:auto;height:100%;box-shadow:none;border-right:1px solid var(--lc-sidenav-border, #e5e7eb);transform:translate(0);transition:width .3s ease,transform .3s ease}.lc-sidenav--docked:not(.lc-sidenav--open){width:0!important;overflow:hidden;border-right:none}.lc-sidenav--collapsed{width:56px!important;overflow:visible}.lc-sidenav--collapsed .lc-sidenav__nav-label,.lc-sidenav--collapsed .lc-sidenav__nav-chevron,.lc-sidenav--collapsed .lc-sidenav__section-title{display:none}.lc-sidenav--collapsed .lc-sidenav__nav{padding:.5rem;gap:.125rem}.lc-sidenav--collapsed .lc-sidenav__nav-item{justify-content:center;padding:.625rem;gap:0;border-radius:var(--radius-md, .375rem);position:relative}.lc-sidenav--collapsed .lc-sidenav__nav-item:hover:after{content:attr(title);position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:8px;padding:4px 10px;background-color:var(--color-neutral-900, #111827);color:#fff;font-size:.75rem;white-space:nowrap;border-radius:4px;z-index:1002;pointer-events:none}.lc-sidenav--collapsed .lc-sidenav__nav-icon{width:22px;height:22px}.lc-sidenav--collapsed .lc-sidenav__nav-children{display:none}.lc-sidenav--collapsed .lc-sidenav__section{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--color-divider, #e5e7eb)}.lc-sidenav--collapsed .lc-sidenav__content{display:none}.lc-sidenav__close{position:absolute;top:1rem;right:1rem;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary);cursor:pointer;transition:background-color .2s ease,color .2s ease;z-index:1}.lc-sidenav__close:hover{background-color:var(--color-surface);color:var(--color-text-primary)}.lc-sidenav__close:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px}.lc-sidenav__close:active{background-color:var(--color-border)}.lc-sidenav__close svg{width:1.25rem;height:1.25rem}.lc-sidenav__nav{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding:4rem 1rem 1rem}.lc-sidenav__nav--docked{padding-top:1rem;gap:0}.lc-sidenav__section:not(:first-child){margin-top:var(--spacing-4, 1rem);padding-top:var(--spacing-3, .75rem)}.lc-sidenav__section-title{padding:0 var(--spacing-3, .75rem);margin-bottom:var(--spacing-2, .5rem);font-size:var(--font-size-xs, .75rem);font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--lc-sidenav-section-fg)}.lc-sidenav__section-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-1, .25rem)}.lc-sidenav__nav-item{display:flex;align-items:center;gap:var(--spacing-3, .75rem);padding:var(--spacing-2, .5rem) var(--spacing-3, .75rem);text-decoration:none;color:var(--lc-sidenav-fg);border-radius:var(--radius-md, .375rem);transition:background-color .2s ease,color .2s ease;font-size:var(--font-size-sm, .875rem);font-weight:500;cursor:pointer}.lc-sidenav__nav-item:hover{background-color:var(--lc-sidenav-hover-bg);color:var(--lc-sidenav-fg-active)}.lc-sidenav__nav-item:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-sidenav__nav-item--active{background-color:var(--color-primary-50, rgba(59, 130, 246, .1));color:var(--color-primary-700, #1d4ed8);font-weight:600}.lc-sidenav__nav-item--active .lc-sidenav__nav-icon{color:var(--color-primary-600, #2563eb)}.lc-sidenav__nav-icon{width:20px;height:20px;flex-shrink:0;color:currentColor}.lc-sidenav__nav-chevron{width:16px;height:16px;flex-shrink:0;margin-left:auto;transition:transform .2s ease}.lc-sidenav__nav-item--expanded .lc-sidenav__nav-chevron{transform:rotate(180deg)}.lc-sidenav__nav-item--parent{width:100%;border:none;background:none;font-family:inherit;text-align:left}.lc-sidenav__nav-children{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding-left:var(--spacing-4, 1rem)}.lc-sidenav__nav-item--child{font-size:var(--font-size-sm, .875rem)}.lc-sidenav__nav-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lc-sidenav__content{flex:1;padding:4rem 1rem 1rem;overflow-y:auto;-webkit-overflow-scrolling:touch}.lc-sidenav__content--docked{padding-top:1rem}.lc-sidenav__content::-webkit-scrollbar{width:.5rem}.lc-sidenav__content::-webkit-scrollbar-track{background:var(--color-surface);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb:hover{background:var(--color-text-secondary)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:640px){.lc-sidenav--drawer{width:100%!important;max-width:320px}}@media(max-width:480px){.lc-sidenav--drawer{max-width:280px}}.lc-sidenav__content:focus{outline:none}.lc-sidenav__content a:focus-visible,.lc-sidenav__content button:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px;border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav--dark{--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}:host-context([data-theme=dark]) .lc-sidenav:not(.lc-sidenav--light){--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}@media print{.lc-sidenav-container,.lc-sidenav__overlay,.lc-sidenav{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: IconComponent, selector: "lc-icon", inputs: ["name", "variant", "size", "color", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6340
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: SidenavComponent, isStandalone: true, selector: "lc-sidenav", inputs: { isOpenInput: "isOpenInput", modeInput: "modeInput", positionInput: "positionInput", widthInput: "widthInput", ariaLabelInput: "ariaLabelInput", hasOverlayInput: "hasOverlayInput", itemsInput: "itemsInput", activeRouteInput: "activeRouteInput", collapsedInput: "collapsedInput", themeInput: ["theme", "themeInput"] }, outputs: { closed: "closed", itemClicked: "itemClicked", itemAction: "itemAction" }, host: { listeners: { "document:keydown": "handleKeydown($event)" }, properties: { "class.lc-sidenav-container": "true", "class.lc-sidenav-container--docked": "mode() === 'docked'", "class.lc-sidenav-container--open": "isOpen()" } }, ngImport: i0, template: "<!-- Drawer mode: render with overlay and conditional visibility -->\n@if (mode() === 'drawer') {\n @if (isOpen()) {\n <!-- Overlay backdrop -->\n @if (hasOverlay()) {\n <div\n class=\"lc-sidenav__overlay\"\n (click)=\"handleClose()\"\n aria-hidden=\"true\">\n </div>\n }\n\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n }\n}\n\n<!-- Docked mode: always render, visibility controlled by CSS -->\n@if (mode() === 'docked') {\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n}\n\n<!-- Shared sidenav panel template -->\n<ng-template #sidenavPanel>\n <aside\n [class]=\"sidenavClasses()\"\n [ngStyle]=\"sidenavStyles()\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel()\">\n\n <!-- Close button (drawer mode only) -->\n @if (mode() === 'drawer') {\n <button\n type=\"button\"\n class=\"lc-sidenav__close\"\n (click)=\"handleClose()\"\n aria-label=\"Close navigation\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Navigation items (if provided) -->\n @if (items().length > 0) {\n <nav class=\"lc-sidenav__nav\" [class.lc-sidenav__nav--docked]=\"mode() === 'docked'\">\n @for (item of sortedItems(); track item.id) {\n <!-- Section headline -->\n @if (item.isSection) {\n <div class=\"lc-sidenav__section\">\n <div class=\"lc-sidenav__section-header\">\n <h2 class=\"lc-sidenav__section-title\">{{ item.label }}</h2>\n @if (item.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"item.action.ariaLabel || item.label + ' action'\"\n (click)=\"handleItemAction($event, item)\">\n <lc-icon [name]=\"item.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n @if (item.children?.length) {\n <ul class=\"lc-sidenav__section-items\">\n @for (child of item.children; track child.id) {\n <li>\n @if (child.children?.length) {\n <!-- Section child with nested children (collapsible) -->\n <div class=\"lc-sidenav__nav-item-row\">\n <button\n type=\"button\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--parent\"\n [class.lc-sidenav__nav-item--expanded]=\"isExpanded(child)\"\n [class.lc-sidenav__nav-item--active]=\"hasActiveChild(child)\"\n (click)=\"toggleExpanded(child)\"\n [attr.aria-expanded]=\"isExpanded(child)\"\n [title]=\"collapsed() ? child.label : ''\">\n @if (child.icon) {\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n @if (child.badge) {\n <lc-badge [variant]=\"child.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ child.badge.value }}</lc-badge>\n }\n <lc-icon name=\"chevron-down\" size=\"xs\" [decorative]=\"true\" class=\"lc-sidenav__nav-chevron\" />\n </button>\n @if (child.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"child.action.ariaLabel || child.label + ' action'\"\n (click)=\"handleItemAction($event, child)\">\n <lc-icon [name]=\"child.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n @if (isExpanded(child)) {\n <div class=\"lc-sidenav__nav-children\">\n @for (grandchild of child.children; track grandchild.id) {\n <a\n [routerLink]=\"grandchild.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(grandchild)\"\n [attr.aria-current]=\"isItemActive(grandchild) ? 'page' : null\">\n @if (grandchild.icon) {\n <lc-icon [name]=\"grandchild.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ grandchild.label }}</span>\n @if (grandchild.badge) {\n <lc-badge [variant]=\"grandchild.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ grandchild.badge.value }}</lc-badge>\n }\n </a>\n }\n </div>\n }\n } @else {\n <!-- Section child (simple link) -->\n <div class=\"lc-sidenav__nav-item-row\">\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: child.route === '/' }\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\"\n [title]=\"collapsed() ? child.label : ''\">\n @if (child.icon) {\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n @if (child.badge) {\n <lc-badge [variant]=\"child.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ child.badge.value }}</lc-badge>\n }\n </a>\n @if (child.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"child.action.ariaLabel || child.label + ' action'\"\n (click)=\"handleItemAction($event, child)\">\n <lc-icon [name]=\"child.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n }\n </li>\n }\n </ul>\n }\n </div>\n } @else if (item.children?.length) {\n <!-- Parent item with children (collapsible group) -->\n <div class=\"lc-sidenav__nav-item-row\">\n <button\n type=\"button\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--parent\"\n [class.lc-sidenav__nav-item--expanded]=\"isExpanded(item)\"\n [class.lc-sidenav__nav-item--active]=\"hasActiveChild(item)\"\n (click)=\"toggleExpanded(item)\"\n [attr.aria-expanded]=\"isExpanded(item)\"\n [title]=\"collapsed() ? item.label : ''\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n @if (item.badge) {\n <lc-badge [variant]=\"item.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ item.badge.value }}</lc-badge>\n }\n <lc-icon name=\"chevron-down\" size=\"xs\" [decorative]=\"true\" class=\"lc-sidenav__nav-chevron\" />\n </button>\n @if (item.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"item.action.ariaLabel || item.label + ' action'\"\n (click)=\"handleItemAction($event, item)\">\n <lc-icon [name]=\"item.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n @if (isExpanded(item)) {\n <div class=\"lc-sidenav__nav-children\">\n @for (child of item.children; track child.id) {\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\">\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n @if (child.badge) {\n <lc-badge [variant]=\"child.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ child.badge.value }}</lc-badge>\n }\n </a>\n }\n </div>\n }\n } @else {\n <!-- Simple item without children -->\n <div class=\"lc-sidenav__nav-item-row\">\n <a\n [routerLink]=\"item.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === '/' }\"\n class=\"lc-sidenav__nav-item\"\n (click)=\"handleItemClick(item)\"\n [attr.aria-current]=\"isItemActive(item) ? 'page' : null\"\n [title]=\"collapsed() ? item.label : ''\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n @if (item.badge) {\n <lc-badge [variant]=\"item.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ item.badge.value }}</lc-badge>\n }\n </a>\n @if (item.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"item.action.ariaLabel || item.label + ' action'\"\n (click)=\"handleItemAction($event, item)\">\n <lc-icon [name]=\"item.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n }\n }\n </nav>\n }\n\n <!-- Content projection (for custom content) -->\n <div class=\"lc-sidenav__content\" [class.lc-sidenav__content--docked]=\"mode() === 'docked'\">\n <ng-content></ng-content>\n </div>\n </aside>\n</ng-template>\n", styles: [".lc-sidenav-container{position:relative;z-index:1000}.lc-sidenav-container--docked{position:static;z-index:auto;height:100%}.lc-sidenav__overlay{position:fixed;inset:0;background-color:#00000080;opacity:0;animation:fadeIn .3s ease-out forwards;z-index:1000;cursor:pointer}@media(prefers-reduced-motion:reduce){.lc-sidenav__overlay{animation:none;opacity:1}}.lc-sidenav{--lc-sidenav-bg: var(--color-background, #ffffff);--lc-sidenav-fg: #374151;--lc-sidenav-fg-active: #111827;--lc-sidenav-border: var(--color-border, #e5e7eb);--lc-sidenav-hover-bg: #f3f4f6;--lc-sidenav-section-fg: #6b7280;position:fixed;top:0;bottom:0;background-color:var(--lc-sidenav-bg);box-shadow:var(--elevation-3, 0 10px 15px -3px rgba(0, 0, 0, .1));z-index:1001;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}.lc-sidenav--left{left:0}.lc-sidenav--right{right:0}.lc-sidenav--drawer.lc-sidenav--left{animation:slideInLeft .3s ease-out}.lc-sidenav--drawer.lc-sidenav--right{animation:slideInRight .3s ease-out}@media(prefers-reduced-motion:reduce){.lc-sidenav--drawer{animation:none!important}}.lc-sidenav--docked{position:static;z-index:auto;height:100%;box-shadow:none;border-right:1px solid var(--lc-sidenav-border, #e5e7eb);transform:translate(0);transition:width .3s ease,transform .3s ease}.lc-sidenav--docked:not(.lc-sidenav--open){width:0!important;overflow:hidden;border-right:none}.lc-sidenav--collapsed{width:56px!important;overflow:visible}.lc-sidenav--collapsed .lc-sidenav__nav-label,.lc-sidenav--collapsed .lc-sidenav__nav-chevron,.lc-sidenav--collapsed .lc-sidenav__section-title,.lc-sidenav--collapsed .lc-sidenav__action-btn,.lc-sidenav--collapsed .lc-sidenav__section-header{display:none}.lc-sidenav--collapsed .lc-sidenav__nav{padding:.5rem;gap:.125rem}.lc-sidenav--collapsed .lc-sidenav__nav-item-row .lc-sidenav__action-btn{display:none}.lc-sidenav--collapsed .lc-sidenav__nav-item{justify-content:center;padding:.625rem;gap:0;border-radius:var(--radius-md, .375rem);position:relative}.lc-sidenav--collapsed .lc-sidenav__nav-item:hover:after{content:attr(title);position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:8px;padding:4px 10px;background-color:var(--color-neutral-900, #111827);color:#fff;font-size:.75rem;white-space:nowrap;border-radius:4px;z-index:1002;pointer-events:none}.lc-sidenav--collapsed .lc-sidenav__nav-icon{width:22px;height:22px}.lc-sidenav--collapsed .lc-sidenav__nav-badge{position:absolute;top:2px;right:2px;margin-left:0;font-size:.625rem;min-width:0;padding:0 3px;line-height:1.2}.lc-sidenav--collapsed .lc-sidenav__nav-children{display:none}.lc-sidenav--collapsed .lc-sidenav__section-items{display:flex;flex-direction:column;gap:.125rem}.lc-sidenav--collapsed .lc-sidenav__section{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--color-divider, #e5e7eb)}.lc-sidenav--collapsed .lc-sidenav__content{display:none}.lc-sidenav__close{position:absolute;top:1rem;right:1rem;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary);cursor:pointer;transition:background-color .2s ease,color .2s ease;z-index:1}.lc-sidenav__close:hover{background-color:var(--color-surface);color:var(--color-text-primary)}.lc-sidenav__close:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px}.lc-sidenav__close:active{background-color:var(--color-border)}.lc-sidenav__close svg{width:1.25rem;height:1.25rem}.lc-sidenav__nav{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding:4rem 1rem 1rem}.lc-sidenav__nav--docked{padding-top:1rem;gap:0}.lc-sidenav__section:not(:first-child){margin-top:var(--spacing-4, 1rem);padding-top:var(--spacing-3, .75rem)}.lc-sidenav__section-header{display:flex;align-items:center;justify-content:space-between;padding-right:var(--spacing-2, .5rem)}.lc-sidenav__section-title{padding:0 var(--spacing-3, .75rem);margin-bottom:var(--spacing-2, .5rem);font-size:var(--font-size-xs, .75rem);font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--lc-sidenav-section-fg)}.lc-sidenav__section-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-1, .25rem)}.lc-sidenav__nav-item{display:flex;align-items:center;gap:var(--spacing-3, .75rem);padding:var(--spacing-2, .5rem) var(--spacing-3, .75rem);text-decoration:none;color:var(--lc-sidenav-fg);border-radius:var(--radius-md, .375rem);transition:background-color .2s ease,color .2s ease;font-size:var(--font-size-sm, .875rem);font-weight:500;cursor:pointer}.lc-sidenav__nav-item:hover{background-color:var(--lc-sidenav-hover-bg);color:var(--lc-sidenav-fg-active)}.lc-sidenav__nav-item:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-sidenav__nav-item--active{background-color:var(--color-primary-50, rgba(59, 130, 246, .1));color:var(--color-primary-700, #1d4ed8);font-weight:600}.lc-sidenav__nav-item--active .lc-sidenav__nav-icon{color:var(--color-primary-600, #2563eb)}.lc-sidenav__nav-icon{width:20px;height:20px;flex-shrink:0;color:currentColor}.lc-sidenav__nav-chevron{width:16px;height:16px;flex-shrink:0;margin-left:auto;transition:transform .2s ease}.lc-sidenav__nav-badge{flex-shrink:0;margin-left:auto}.lc-sidenav__nav-item--expanded .lc-sidenav__nav-chevron{transform:rotate(180deg)}.lc-sidenav__nav-item--parent{width:100%;border:none;background:none;font-family:inherit;text-align:left}.lc-sidenav__nav-children{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding-left:var(--spacing-4, 1rem)}.lc-sidenav__nav-item--child{font-size:var(--font-size-sm, .875rem)}.lc-sidenav__nav-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lc-sidenav__nav-item-row{display:flex;align-items:center}.lc-sidenav__nav-item-row .lc-sidenav__nav-item{flex:1;min-width:0}.lc-sidenav__nav-item-row .lc-sidenav__action-btn{opacity:0;transition:opacity .15s ease}.lc-sidenav__nav-item-row:hover .lc-sidenav__action-btn{opacity:1}.lc-sidenav__action-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:var(--radius-sm, .25rem);color:var(--lc-sidenav-section-fg);cursor:pointer;transition:background-color .15s ease,color .15s ease}.lc-sidenav__action-btn:hover{background-color:var(--lc-sidenav-hover-bg);color:var(--lc-sidenav-fg-active)}.lc-sidenav__action-btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;opacity:1}.lc-sidenav__content{flex:1;padding:4rem 1rem 1rem;overflow-y:auto;-webkit-overflow-scrolling:touch}.lc-sidenav__content--docked{padding-top:1rem}.lc-sidenav__content::-webkit-scrollbar{width:.5rem}.lc-sidenav__content::-webkit-scrollbar-track{background:var(--color-surface);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb:hover{background:var(--color-text-secondary)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:640px){.lc-sidenav--drawer{width:100%!important;max-width:320px}}@media(max-width:480px){.lc-sidenav--drawer{max-width:280px}}.lc-sidenav__content:focus{outline:none}.lc-sidenav__content a:focus-visible,.lc-sidenav__content button:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px;border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav--dark{--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}:host-context([data-theme=dark]) .lc-sidenav:not(.lc-sidenav--light){--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}@media print{.lc-sidenav-container,.lc-sidenav__overlay,.lc-sidenav{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: IconComponent, selector: "lc-icon", inputs: ["name", "variant", "size", "color", "ariaLabel", "decorative"] }, { kind: "component", type: BadgeComponent, selector: "lc-badge", inputs: ["variant", "size", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6288
6341
|
}
|
|
6289
6342
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: SidenavComponent, decorators: [{
|
|
6290
6343
|
type: Component,
|
|
6291
|
-
args: [{ selector: 'lc-sidenav', standalone: true, imports: [CommonModule, RouterModule, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
6344
|
+
args: [{ selector: 'lc-sidenav', standalone: true, imports: [CommonModule, RouterModule, IconComponent, BadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
6292
6345
|
'[class.lc-sidenav-container]': 'true',
|
|
6293
6346
|
'[class.lc-sidenav-container--docked]': "mode() === 'docked'",
|
|
6294
6347
|
'[class.lc-sidenav-container--open]': 'isOpen()',
|
|
6295
|
-
}, template: "<!-- Drawer mode: render with overlay and conditional visibility -->\n@if (mode() === 'drawer') {\n @if (isOpen()) {\n <!-- Overlay backdrop -->\n @if (hasOverlay()) {\n <div\n class=\"lc-sidenav__overlay\"\n (click)=\"handleClose()\"\n aria-hidden=\"true\">\n </div>\n }\n\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n }\n}\n\n<!-- Docked mode: always render, visibility controlled by CSS -->\n@if (mode() === 'docked') {\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n}\n\n<!-- Shared sidenav panel template -->\n<ng-template #sidenavPanel>\n <aside\n [class]=\"sidenavClasses()\"\n [ngStyle]=\"sidenavStyles()\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel()\">\n\n <!-- Close button (drawer mode only) -->\n @if (mode() === 'drawer') {\n <button\n type=\"button\"\n class=\"lc-sidenav__close\"\n (click)=\"handleClose()\"\n aria-label=\"Close navigation\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Navigation items (if provided) -->\n @if (items().length > 0) {\n <nav class=\"lc-sidenav__nav\" [class.lc-sidenav__nav--docked]=\"mode() === 'docked'\">\n @for (item of sortedItems(); track item.id) {\n <!-- Section headline -->\n @if (item.isSection) {\n <div class=\"lc-sidenav__section\">\n <h2 class=\"lc-sidenav__section-title\">{{ item.label }}</h2>\n @if (item.children?.length) {\n <ul class=\"lc-sidenav__section-items\">\n @for (child of item.children; track child.id) {\n <li>\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: child.route === '/' }\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\">\n @if (child.icon) {\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n </a>\n </li>\n }\n </ul>\n }\n </div>\n } @else if (item.children?.length) {\n <!-- Parent item with children (collapsible group) -->\n <button\n type=\"button\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--parent\"\n [class.lc-sidenav__nav-item--expanded]=\"isExpanded(item)\"\n [class.lc-sidenav__nav-item--active]=\"hasActiveChild(item)\"\n (click)=\"toggleExpanded(item)\"\n [attr.aria-expanded]=\"isExpanded(item)\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n <lc-icon name=\"chevron-down\" size=\"xs\" [decorative]=\"true\" class=\"lc-sidenav__nav-chevron\" />\n </button>\n @if (isExpanded(item)) {\n <div class=\"lc-sidenav__nav-children\">\n @for (child of item.children; track child.id) {\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\">\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n </a>\n }\n </div>\n }\n } @else {\n <!-- Simple item without children -->\n <a\n [routerLink]=\"item.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === '/' }\"\n class=\"lc-sidenav__nav-item\"\n (click)=\"handleItemClick(item)\"\n [attr.aria-current]=\"isItemActive(item) ? 'page' : null\"\n [title]=\"collapsed() ? item.label : ''\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n </a>\n }\n }\n </nav>\n }\n\n <!-- Content projection (for custom content) -->\n <div class=\"lc-sidenav__content\" [class.lc-sidenav__content--docked]=\"mode() === 'docked'\">\n <ng-content></ng-content>\n </div>\n </aside>\n</ng-template>\n", styles: [".lc-sidenav-container{position:relative;z-index:1000}.lc-sidenav-container--docked{position:static;z-index:auto;height:100%}.lc-sidenav__overlay{position:fixed;inset:0;background-color:#00000080;opacity:0;animation:fadeIn .3s ease-out forwards;z-index:1000;cursor:pointer}@media(prefers-reduced-motion:reduce){.lc-sidenav__overlay{animation:none;opacity:1}}.lc-sidenav{--lc-sidenav-bg: var(--color-background, #ffffff);--lc-sidenav-fg: #374151;--lc-sidenav-fg-active: #111827;--lc-sidenav-border: var(--color-border, #e5e7eb);--lc-sidenav-hover-bg: #f3f4f6;--lc-sidenav-section-fg: #6b7280;position:fixed;top:0;bottom:0;background-color:var(--lc-sidenav-bg);box-shadow:var(--elevation-3, 0 10px 15px -3px rgba(0, 0, 0, .1));z-index:1001;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}.lc-sidenav--left{left:0}.lc-sidenav--right{right:0}.lc-sidenav--drawer.lc-sidenav--left{animation:slideInLeft .3s ease-out}.lc-sidenav--drawer.lc-sidenav--right{animation:slideInRight .3s ease-out}@media(prefers-reduced-motion:reduce){.lc-sidenav--drawer{animation:none!important}}.lc-sidenav--docked{position:static;z-index:auto;height:100%;box-shadow:none;border-right:1px solid var(--lc-sidenav-border, #e5e7eb);transform:translate(0);transition:width .3s ease,transform .3s ease}.lc-sidenav--docked:not(.lc-sidenav--open){width:0!important;overflow:hidden;border-right:none}.lc-sidenav--collapsed{width:56px!important;overflow:visible}.lc-sidenav--collapsed .lc-sidenav__nav-label,.lc-sidenav--collapsed .lc-sidenav__nav-chevron,.lc-sidenav--collapsed .lc-sidenav__section-title{display:none}.lc-sidenav--collapsed .lc-sidenav__nav{padding:.5rem;gap:.125rem}.lc-sidenav--collapsed .lc-sidenav__nav-item{justify-content:center;padding:.625rem;gap:0;border-radius:var(--radius-md, .375rem);position:relative}.lc-sidenav--collapsed .lc-sidenav__nav-item:hover:after{content:attr(title);position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:8px;padding:4px 10px;background-color:var(--color-neutral-900, #111827);color:#fff;font-size:.75rem;white-space:nowrap;border-radius:4px;z-index:1002;pointer-events:none}.lc-sidenav--collapsed .lc-sidenav__nav-icon{width:22px;height:22px}.lc-sidenav--collapsed .lc-sidenav__nav-children{display:none}.lc-sidenav--collapsed .lc-sidenav__section{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--color-divider, #e5e7eb)}.lc-sidenav--collapsed .lc-sidenav__content{display:none}.lc-sidenav__close{position:absolute;top:1rem;right:1rem;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary);cursor:pointer;transition:background-color .2s ease,color .2s ease;z-index:1}.lc-sidenav__close:hover{background-color:var(--color-surface);color:var(--color-text-primary)}.lc-sidenav__close:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px}.lc-sidenav__close:active{background-color:var(--color-border)}.lc-sidenav__close svg{width:1.25rem;height:1.25rem}.lc-sidenav__nav{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding:4rem 1rem 1rem}.lc-sidenav__nav--docked{padding-top:1rem;gap:0}.lc-sidenav__section:not(:first-child){margin-top:var(--spacing-4, 1rem);padding-top:var(--spacing-3, .75rem)}.lc-sidenav__section-title{padding:0 var(--spacing-3, .75rem);margin-bottom:var(--spacing-2, .5rem);font-size:var(--font-size-xs, .75rem);font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--lc-sidenav-section-fg)}.lc-sidenav__section-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-1, .25rem)}.lc-sidenav__nav-item{display:flex;align-items:center;gap:var(--spacing-3, .75rem);padding:var(--spacing-2, .5rem) var(--spacing-3, .75rem);text-decoration:none;color:var(--lc-sidenav-fg);border-radius:var(--radius-md, .375rem);transition:background-color .2s ease,color .2s ease;font-size:var(--font-size-sm, .875rem);font-weight:500;cursor:pointer}.lc-sidenav__nav-item:hover{background-color:var(--lc-sidenav-hover-bg);color:var(--lc-sidenav-fg-active)}.lc-sidenav__nav-item:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-sidenav__nav-item--active{background-color:var(--color-primary-50, rgba(59, 130, 246, .1));color:var(--color-primary-700, #1d4ed8);font-weight:600}.lc-sidenav__nav-item--active .lc-sidenav__nav-icon{color:var(--color-primary-600, #2563eb)}.lc-sidenav__nav-icon{width:20px;height:20px;flex-shrink:0;color:currentColor}.lc-sidenav__nav-chevron{width:16px;height:16px;flex-shrink:0;margin-left:auto;transition:transform .2s ease}.lc-sidenav__nav-item--expanded .lc-sidenav__nav-chevron{transform:rotate(180deg)}.lc-sidenav__nav-item--parent{width:100%;border:none;background:none;font-family:inherit;text-align:left}.lc-sidenav__nav-children{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding-left:var(--spacing-4, 1rem)}.lc-sidenav__nav-item--child{font-size:var(--font-size-sm, .875rem)}.lc-sidenav__nav-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lc-sidenav__content{flex:1;padding:4rem 1rem 1rem;overflow-y:auto;-webkit-overflow-scrolling:touch}.lc-sidenav__content--docked{padding-top:1rem}.lc-sidenav__content::-webkit-scrollbar{width:.5rem}.lc-sidenav__content::-webkit-scrollbar-track{background:var(--color-surface);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb:hover{background:var(--color-text-secondary)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:640px){.lc-sidenav--drawer{width:100%!important;max-width:320px}}@media(max-width:480px){.lc-sidenav--drawer{max-width:280px}}.lc-sidenav__content:focus{outline:none}.lc-sidenav__content a:focus-visible,.lc-sidenav__content button:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px;border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav--dark{--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}:host-context([data-theme=dark]) .lc-sidenav:not(.lc-sidenav--light){--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}@media print{.lc-sidenav-container,.lc-sidenav__overlay,.lc-sidenav{display:none}}\n"] }]
|
|
6348
|
+
}, template: "<!-- Drawer mode: render with overlay and conditional visibility -->\n@if (mode() === 'drawer') {\n @if (isOpen()) {\n <!-- Overlay backdrop -->\n @if (hasOverlay()) {\n <div\n class=\"lc-sidenav__overlay\"\n (click)=\"handleClose()\"\n aria-hidden=\"true\">\n </div>\n }\n\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n }\n}\n\n<!-- Docked mode: always render, visibility controlled by CSS -->\n@if (mode() === 'docked') {\n <ng-container *ngTemplateOutlet=\"sidenavPanel\" />\n}\n\n<!-- Shared sidenav panel template -->\n<ng-template #sidenavPanel>\n <aside\n [class]=\"sidenavClasses()\"\n [ngStyle]=\"sidenavStyles()\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel()\">\n\n <!-- Close button (drawer mode only) -->\n @if (mode() === 'drawer') {\n <button\n type=\"button\"\n class=\"lc-sidenav__close\"\n (click)=\"handleClose()\"\n aria-label=\"Close navigation\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n\n <!-- Navigation items (if provided) -->\n @if (items().length > 0) {\n <nav class=\"lc-sidenav__nav\" [class.lc-sidenav__nav--docked]=\"mode() === 'docked'\">\n @for (item of sortedItems(); track item.id) {\n <!-- Section headline -->\n @if (item.isSection) {\n <div class=\"lc-sidenav__section\">\n <div class=\"lc-sidenav__section-header\">\n <h2 class=\"lc-sidenav__section-title\">{{ item.label }}</h2>\n @if (item.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"item.action.ariaLabel || item.label + ' action'\"\n (click)=\"handleItemAction($event, item)\">\n <lc-icon [name]=\"item.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n @if (item.children?.length) {\n <ul class=\"lc-sidenav__section-items\">\n @for (child of item.children; track child.id) {\n <li>\n @if (child.children?.length) {\n <!-- Section child with nested children (collapsible) -->\n <div class=\"lc-sidenav__nav-item-row\">\n <button\n type=\"button\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--parent\"\n [class.lc-sidenav__nav-item--expanded]=\"isExpanded(child)\"\n [class.lc-sidenav__nav-item--active]=\"hasActiveChild(child)\"\n (click)=\"toggleExpanded(child)\"\n [attr.aria-expanded]=\"isExpanded(child)\"\n [title]=\"collapsed() ? child.label : ''\">\n @if (child.icon) {\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n @if (child.badge) {\n <lc-badge [variant]=\"child.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ child.badge.value }}</lc-badge>\n }\n <lc-icon name=\"chevron-down\" size=\"xs\" [decorative]=\"true\" class=\"lc-sidenav__nav-chevron\" />\n </button>\n @if (child.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"child.action.ariaLabel || child.label + ' action'\"\n (click)=\"handleItemAction($event, child)\">\n <lc-icon [name]=\"child.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n @if (isExpanded(child)) {\n <div class=\"lc-sidenav__nav-children\">\n @for (grandchild of child.children; track grandchild.id) {\n <a\n [routerLink]=\"grandchild.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(grandchild)\"\n [attr.aria-current]=\"isItemActive(grandchild) ? 'page' : null\">\n @if (grandchild.icon) {\n <lc-icon [name]=\"grandchild.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ grandchild.label }}</span>\n @if (grandchild.badge) {\n <lc-badge [variant]=\"grandchild.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ grandchild.badge.value }}</lc-badge>\n }\n </a>\n }\n </div>\n }\n } @else {\n <!-- Section child (simple link) -->\n <div class=\"lc-sidenav__nav-item-row\">\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: child.route === '/' }\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\"\n [title]=\"collapsed() ? child.label : ''\">\n @if (child.icon) {\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n }\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n @if (child.badge) {\n <lc-badge [variant]=\"child.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ child.badge.value }}</lc-badge>\n }\n </a>\n @if (child.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"child.action.ariaLabel || child.label + ' action'\"\n (click)=\"handleItemAction($event, child)\">\n <lc-icon [name]=\"child.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n }\n </li>\n }\n </ul>\n }\n </div>\n } @else if (item.children?.length) {\n <!-- Parent item with children (collapsible group) -->\n <div class=\"lc-sidenav__nav-item-row\">\n <button\n type=\"button\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--parent\"\n [class.lc-sidenav__nav-item--expanded]=\"isExpanded(item)\"\n [class.lc-sidenav__nav-item--active]=\"hasActiveChild(item)\"\n (click)=\"toggleExpanded(item)\"\n [attr.aria-expanded]=\"isExpanded(item)\"\n [title]=\"collapsed() ? item.label : ''\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n @if (item.badge) {\n <lc-badge [variant]=\"item.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ item.badge.value }}</lc-badge>\n }\n <lc-icon name=\"chevron-down\" size=\"xs\" [decorative]=\"true\" class=\"lc-sidenav__nav-chevron\" />\n </button>\n @if (item.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"item.action.ariaLabel || item.label + ' action'\"\n (click)=\"handleItemAction($event, item)\">\n <lc-icon [name]=\"item.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n @if (isExpanded(item)) {\n <div class=\"lc-sidenav__nav-children\">\n @for (child of item.children; track child.id) {\n <a\n [routerLink]=\"child.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n class=\"lc-sidenav__nav-item lc-sidenav__nav-item--child\"\n (click)=\"handleItemClick(child)\"\n [attr.aria-current]=\"isItemActive(child) ? 'page' : null\">\n <lc-icon [name]=\"child.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ child.label }}</span>\n @if (child.badge) {\n <lc-badge [variant]=\"child.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ child.badge.value }}</lc-badge>\n }\n </a>\n }\n </div>\n }\n } @else {\n <!-- Simple item without children -->\n <div class=\"lc-sidenav__nav-item-row\">\n <a\n [routerLink]=\"item.route\"\n routerLinkActive=\"lc-sidenav__nav-item--active\"\n [routerLinkActiveOptions]=\"{ exact: item.route === '/' }\"\n class=\"lc-sidenav__nav-item\"\n (click)=\"handleItemClick(item)\"\n [attr.aria-current]=\"isItemActive(item) ? 'page' : null\"\n [title]=\"collapsed() ? item.label : ''\">\n <lc-icon [name]=\"item.icon\" size=\"sm\" [decorative]=\"true\" class=\"lc-sidenav__nav-icon\" />\n <span class=\"lc-sidenav__nav-label\">{{ item.label }}</span>\n @if (item.badge) {\n <lc-badge [variant]=\"item.badge.variant || 'default'\" size=\"xs\" [rounded]=\"true\" class=\"lc-sidenav__nav-badge\">{{ item.badge.value }}</lc-badge>\n }\n </a>\n @if (item.action) {\n <button\n type=\"button\"\n class=\"lc-sidenav__action-btn\"\n [attr.aria-label]=\"item.action.ariaLabel || item.label + ' action'\"\n (click)=\"handleItemAction($event, item)\">\n <lc-icon [name]=\"item.action.icon\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </div>\n }\n }\n </nav>\n }\n\n <!-- Content projection (for custom content) -->\n <div class=\"lc-sidenav__content\" [class.lc-sidenav__content--docked]=\"mode() === 'docked'\">\n <ng-content></ng-content>\n </div>\n </aside>\n</ng-template>\n", styles: [".lc-sidenav-container{position:relative;z-index:1000}.lc-sidenav-container--docked{position:static;z-index:auto;height:100%}.lc-sidenav__overlay{position:fixed;inset:0;background-color:#00000080;opacity:0;animation:fadeIn .3s ease-out forwards;z-index:1000;cursor:pointer}@media(prefers-reduced-motion:reduce){.lc-sidenav__overlay{animation:none;opacity:1}}.lc-sidenav{--lc-sidenav-bg: var(--color-background, #ffffff);--lc-sidenav-fg: #374151;--lc-sidenav-fg-active: #111827;--lc-sidenav-border: var(--color-border, #e5e7eb);--lc-sidenav-hover-bg: #f3f4f6;--lc-sidenav-section-fg: #6b7280;position:fixed;top:0;bottom:0;background-color:var(--lc-sidenav-bg);box-shadow:var(--elevation-3, 0 10px 15px -3px rgba(0, 0, 0, .1));z-index:1001;display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden}.lc-sidenav--left{left:0}.lc-sidenav--right{right:0}.lc-sidenav--drawer.lc-sidenav--left{animation:slideInLeft .3s ease-out}.lc-sidenav--drawer.lc-sidenav--right{animation:slideInRight .3s ease-out}@media(prefers-reduced-motion:reduce){.lc-sidenav--drawer{animation:none!important}}.lc-sidenav--docked{position:static;z-index:auto;height:100%;box-shadow:none;border-right:1px solid var(--lc-sidenav-border, #e5e7eb);transform:translate(0);transition:width .3s ease,transform .3s ease}.lc-sidenav--docked:not(.lc-sidenav--open){width:0!important;overflow:hidden;border-right:none}.lc-sidenav--collapsed{width:56px!important;overflow:visible}.lc-sidenav--collapsed .lc-sidenav__nav-label,.lc-sidenav--collapsed .lc-sidenav__nav-chevron,.lc-sidenav--collapsed .lc-sidenav__section-title,.lc-sidenav--collapsed .lc-sidenav__action-btn,.lc-sidenav--collapsed .lc-sidenav__section-header{display:none}.lc-sidenav--collapsed .lc-sidenav__nav{padding:.5rem;gap:.125rem}.lc-sidenav--collapsed .lc-sidenav__nav-item-row .lc-sidenav__action-btn{display:none}.lc-sidenav--collapsed .lc-sidenav__nav-item{justify-content:center;padding:.625rem;gap:0;border-radius:var(--radius-md, .375rem);position:relative}.lc-sidenav--collapsed .lc-sidenav__nav-item:hover:after{content:attr(title);position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:8px;padding:4px 10px;background-color:var(--color-neutral-900, #111827);color:#fff;font-size:.75rem;white-space:nowrap;border-radius:4px;z-index:1002;pointer-events:none}.lc-sidenav--collapsed .lc-sidenav__nav-icon{width:22px;height:22px}.lc-sidenav--collapsed .lc-sidenav__nav-badge{position:absolute;top:2px;right:2px;margin-left:0;font-size:.625rem;min-width:0;padding:0 3px;line-height:1.2}.lc-sidenav--collapsed .lc-sidenav__nav-children{display:none}.lc-sidenav--collapsed .lc-sidenav__section-items{display:flex;flex-direction:column;gap:.125rem}.lc-sidenav--collapsed .lc-sidenav__section{margin-top:.5rem;padding-top:.5rem;border-top:1px solid var(--color-divider, #e5e7eb)}.lc-sidenav--collapsed .lc-sidenav__content{display:none}.lc-sidenav__close{position:absolute;top:1rem;right:1rem;width:2.5rem;height:2.5rem;display:flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--border-radius-md, .375rem);color:var(--color-text-secondary);cursor:pointer;transition:background-color .2s ease,color .2s ease;z-index:1}.lc-sidenav__close:hover{background-color:var(--color-surface);color:var(--color-text-primary)}.lc-sidenav__close:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px}.lc-sidenav__close:active{background-color:var(--color-border)}.lc-sidenav__close svg{width:1.25rem;height:1.25rem}.lc-sidenav__nav{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding:4rem 1rem 1rem}.lc-sidenav__nav--docked{padding-top:1rem;gap:0}.lc-sidenav__section:not(:first-child){margin-top:var(--spacing-4, 1rem);padding-top:var(--spacing-3, .75rem)}.lc-sidenav__section-header{display:flex;align-items:center;justify-content:space-between;padding-right:var(--spacing-2, .5rem)}.lc-sidenav__section-title{padding:0 var(--spacing-3, .75rem);margin-bottom:var(--spacing-2, .5rem);font-size:var(--font-size-xs, .75rem);font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--lc-sidenav-section-fg)}.lc-sidenav__section-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--spacing-1, .25rem)}.lc-sidenav__nav-item{display:flex;align-items:center;gap:var(--spacing-3, .75rem);padding:var(--spacing-2, .5rem) var(--spacing-3, .75rem);text-decoration:none;color:var(--lc-sidenav-fg);border-radius:var(--radius-md, .375rem);transition:background-color .2s ease,color .2s ease;font-size:var(--font-size-sm, .875rem);font-weight:500;cursor:pointer}.lc-sidenav__nav-item:hover{background-color:var(--lc-sidenav-hover-bg);color:var(--lc-sidenav-fg-active)}.lc-sidenav__nav-item:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px}.lc-sidenav__nav-item--active{background-color:var(--color-primary-50, rgba(59, 130, 246, .1));color:var(--color-primary-700, #1d4ed8);font-weight:600}.lc-sidenav__nav-item--active .lc-sidenav__nav-icon{color:var(--color-primary-600, #2563eb)}.lc-sidenav__nav-icon{width:20px;height:20px;flex-shrink:0;color:currentColor}.lc-sidenav__nav-chevron{width:16px;height:16px;flex-shrink:0;margin-left:auto;transition:transform .2s ease}.lc-sidenav__nav-badge{flex-shrink:0;margin-left:auto}.lc-sidenav__nav-item--expanded .lc-sidenav__nav-chevron{transform:rotate(180deg)}.lc-sidenav__nav-item--parent{width:100%;border:none;background:none;font-family:inherit;text-align:left}.lc-sidenav__nav-children{display:flex;flex-direction:column;gap:var(--spacing-1, .25rem);padding-left:var(--spacing-4, 1rem)}.lc-sidenav__nav-item--child{font-size:var(--font-size-sm, .875rem)}.lc-sidenav__nav-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lc-sidenav__nav-item-row{display:flex;align-items:center}.lc-sidenav__nav-item-row .lc-sidenav__nav-item{flex:1;min-width:0}.lc-sidenav__nav-item-row .lc-sidenav__action-btn{opacity:0;transition:opacity .15s ease}.lc-sidenav__nav-item-row:hover .lc-sidenav__action-btn{opacity:1}.lc-sidenav__action-btn{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:var(--radius-sm, .25rem);color:var(--lc-sidenav-section-fg);cursor:pointer;transition:background-color .15s ease,color .15s ease}.lc-sidenav__action-btn:hover{background-color:var(--lc-sidenav-hover-bg);color:var(--lc-sidenav-fg-active)}.lc-sidenav__action-btn:focus-visible{outline:2px solid var(--color-primary-500);outline-offset:2px;opacity:1}.lc-sidenav__content{flex:1;padding:4rem 1rem 1rem;overflow-y:auto;-webkit-overflow-scrolling:touch}.lc-sidenav__content--docked{padding-top:1rem}.lc-sidenav__content::-webkit-scrollbar{width:.5rem}.lc-sidenav__content::-webkit-scrollbar-track{background:var(--color-surface);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav__content::-webkit-scrollbar-thumb:hover{background:var(--color-text-secondary)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideInLeft{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}@media(max-width:640px){.lc-sidenav--drawer{width:100%!important;max-width:320px}}@media(max-width:480px){.lc-sidenav--drawer{max-width:280px}}.lc-sidenav__content:focus{outline:none}.lc-sidenav__content a:focus-visible,.lc-sidenav__content button:focus-visible{outline:2px solid var(--color-primary-500, rgb(59, 130, 246));outline-offset:2px;border-radius:var(--border-radius-sm, .25rem)}.lc-sidenav--dark{--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}:host-context([data-theme=dark]) .lc-sidenav:not(.lc-sidenav--light){--lc-sidenav-bg: #18181b;--lc-sidenav-fg: #d4d4d8;--lc-sidenav-fg-active: #f5f5f5;--lc-sidenav-border: #3f3f46;--lc-sidenav-hover-bg: #27272a;--lc-sidenav-section-fg: #a1a1aa}@media print{.lc-sidenav-container,.lc-sidenav__overlay,.lc-sidenav{display:none}}\n"] }]
|
|
6296
6349
|
}], propDecorators: { isOpenInput: [{
|
|
6297
6350
|
type: Input
|
|
6298
6351
|
}], modeInput: [{
|
|
@@ -6318,6 +6371,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
6318
6371
|
type: Output
|
|
6319
6372
|
}], itemClicked: [{
|
|
6320
6373
|
type: Output
|
|
6374
|
+
}], itemAction: [{
|
|
6375
|
+
type: Output
|
|
6321
6376
|
}], handleKeydown: [{
|
|
6322
6377
|
type: HostListener,
|
|
6323
6378
|
args: ['document:keydown', ['$event']]
|
|
@@ -6615,48 +6670,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
6615
6670
|
type: Input
|
|
6616
6671
|
}] } });
|
|
6617
6672
|
|
|
6618
|
-
/**
|
|
6619
|
-
* Badge component for displaying status, notifications, or counts.
|
|
6620
|
-
*
|
|
6621
|
-
* Features:
|
|
6622
|
-
* - Semantic color variants (primary, secondary, success, warning, error, info, neutral)
|
|
6623
|
-
* - Multiple size options (xs, sm, md, lg)
|
|
6624
|
-
* - Pill-shaped rounded mode
|
|
6625
|
-
* - Content projection for labels or count values
|
|
6626
|
-
*
|
|
6627
|
-
* @example
|
|
6628
|
-
* ```html
|
|
6629
|
-
* <lc-badge variant="primary" size="md">New</lc-badge>
|
|
6630
|
-
* <lc-badge variant="error" size="sm" [rounded]="true">5</lc-badge>
|
|
6631
|
-
* ```
|
|
6632
|
-
*/
|
|
6633
|
-
class BadgeComponent {
|
|
6634
|
-
/** Visual variant of the badge */
|
|
6635
|
-
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
6636
|
-
/** Size of the badge */
|
|
6637
|
-
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
6638
|
-
/** Whether the badge has fully rounded corners (pill shape) */
|
|
6639
|
-
rounded = input(false, ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
|
|
6640
|
-
/**
|
|
6641
|
-
* Computed CSS classes for the badge
|
|
6642
|
-
*/
|
|
6643
|
-
badgeClasses = computed(() => {
|
|
6644
|
-
const classes = ['lc-badge'];
|
|
6645
|
-
classes.push(`lc-badge--${this.variant()}`);
|
|
6646
|
-
classes.push(`lc-badge--${this.size()}`);
|
|
6647
|
-
if (this.rounded()) {
|
|
6648
|
-
classes.push('lc-badge--rounded');
|
|
6649
|
-
}
|
|
6650
|
-
return classes.join(' ');
|
|
6651
|
-
}, ...(ngDevMode ? [{ debugName: "badgeClasses" }] : /* istanbul ignore next */ []));
|
|
6652
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: BadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6653
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.10", type: BadgeComponent, isStandalone: true, selector: "lc-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span [class]=\"badgeClasses()\">\n <ng-content></ng-content>\n</span>\n", styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge--default{background-color:var(--color-neutral-200, #e5e7eb);color:var(--color-neutral-800, #1f2937)}[data-theme=dark] .lc-badge--default,:root[data-theme=dark] .lc-badge--default{background-color:var(--color-neutral-700, #374151);color:var(--color-neutral-100, #f3f4f6)}.lc-badge--primary{background-color:var(--color-primary-100, #dbeafe);color:var(--color-primary-800, #1e3a5f)}[data-theme=dark] .lc-badge--primary,:root[data-theme=dark] .lc-badge--primary{background-color:var(--color-primary-900, #1e3a5f);color:var(--color-primary-200, #bfdbfe)}.lc-badge--success{background-color:var(--color-success-light, #dcfce7);color:var(--color-success-dark, #166534)}[data-theme=dark] .lc-badge--success,:root[data-theme=dark] .lc-badge--success{background-color:#22c55e33;color:#86efac}.lc-badge--warning{background-color:var(--color-warning-light, #fef3c7);color:var(--color-warning-dark, #92400e)}[data-theme=dark] .lc-badge--warning,:root[data-theme=dark] .lc-badge--warning{background-color:#fbbf2433;color:#fde047}.lc-badge--error{background-color:var(--color-error-light, #fee2e2);color:var(--color-error-dark, #991b1b)}[data-theme=dark] .lc-badge--error,:root[data-theme=dark] .lc-badge--error{background-color:#ef444433;color:#fca5a5}.lc-badge--info{background-color:var(--color-info-light, #dbeafe);color:var(--color-info-dark, #1e40af)}[data-theme=dark] .lc-badge--info,:root[data-theme=dark] .lc-badge--info{background-color:#3b82f633;color:#93c5fd}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
6654
|
-
}
|
|
6655
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: BadgeComponent, decorators: [{
|
|
6656
|
-
type: Component,
|
|
6657
|
-
args: [{ selector: 'lc-badge', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span [class]=\"badgeClasses()\">\n <ng-content></ng-content>\n</span>\n", styles: [".lc-badge{display:inline-flex;align-items:center;justify-content:center;font-weight:var(--typography-font-weight-medium, 500);line-height:1;border-radius:var(--border-radius-sm, .25rem);white-space:nowrap;transition:background-color .15s ease,color .15s ease}.lc-badge--xs{padding:.125rem .375rem;font-size:var(--typography-font-size-xs, .75rem);min-width:1.25rem;height:1.25rem}.lc-badge--sm{padding:.25rem .5rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.5rem;height:1.5rem}.lc-badge--md{padding:.375rem .625rem;font-size:var(--typography-font-size-sm, .875rem);min-width:1.75rem;height:1.75rem}.lc-badge--lg{padding:.5rem .75rem;font-size:var(--typography-font-size-base, 1rem);min-width:2rem;height:2rem}.lc-badge--default{background-color:var(--color-neutral-200, #e5e7eb);color:var(--color-neutral-800, #1f2937)}[data-theme=dark] .lc-badge--default,:root[data-theme=dark] .lc-badge--default{background-color:var(--color-neutral-700, #374151);color:var(--color-neutral-100, #f3f4f6)}.lc-badge--primary{background-color:var(--color-primary-100, #dbeafe);color:var(--color-primary-800, #1e3a5f)}[data-theme=dark] .lc-badge--primary,:root[data-theme=dark] .lc-badge--primary{background-color:var(--color-primary-900, #1e3a5f);color:var(--color-primary-200, #bfdbfe)}.lc-badge--success{background-color:var(--color-success-light, #dcfce7);color:var(--color-success-dark, #166534)}[data-theme=dark] .lc-badge--success,:root[data-theme=dark] .lc-badge--success{background-color:#22c55e33;color:#86efac}.lc-badge--warning{background-color:var(--color-warning-light, #fef3c7);color:var(--color-warning-dark, #92400e)}[data-theme=dark] .lc-badge--warning,:root[data-theme=dark] .lc-badge--warning{background-color:#fbbf2433;color:#fde047}.lc-badge--error{background-color:var(--color-error-light, #fee2e2);color:var(--color-error-dark, #991b1b)}[data-theme=dark] .lc-badge--error,:root[data-theme=dark] .lc-badge--error{background-color:#ef444433;color:#fca5a5}.lc-badge--info{background-color:var(--color-info-light, #dbeafe);color:var(--color-info-dark, #1e40af)}[data-theme=dark] .lc-badge--info,:root[data-theme=dark] .lc-badge--info{background-color:#3b82f633;color:#93c5fd}.lc-badge--rounded{border-radius:var(--border-radius-full, 9999px)}@media(max-width:640px){.lc-badge--lg{padding:.5rem .875rem}}@media print{.lc-badge{border:1px solid currentColor}}\n"] }]
|
|
6658
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }] } });
|
|
6659
|
-
|
|
6660
6673
|
/**
|
|
6661
6674
|
* Toggle group component for single-option selection from a set.
|
|
6662
6675
|
*
|