@lumston/ds-angular 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, computed, ChangeDetectionStrategy, Component, HostListener, ViewChild, Input, TemplateRef, Directive, output, signal, effect, forwardRef, Renderer2, DestroyRef,
|
|
2
|
+
import { inject, input, computed, ChangeDetectionStrategy, Component, HostListener, ViewChild, Input, TemplateRef, Directive, ElementRef, output, signal, effect, forwardRef, Renderer2, DestroyRef, model, viewChild, ViewEncapsulation, untracked, Injectable, contentChild } from '@angular/core';
|
|
3
3
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule, NgTemplateOutlet, DOCUMENT } from '@angular/common';
|
|
@@ -228,7 +228,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
228
228
|
|
|
229
229
|
class ButtonComponent {
|
|
230
230
|
constructor() {
|
|
231
|
+
this._elementRef = inject((ElementRef));
|
|
231
232
|
this.sanitizer = inject(DomSanitizer);
|
|
233
|
+
/** Host element of this component. Pass directly as `anchorEl` to overlay components like `ls-menu`. */
|
|
234
|
+
this.nativeElement = this._elementRef.nativeElement;
|
|
232
235
|
this.variant = input('contained', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
233
236
|
this.color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
234
237
|
this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
@@ -2524,6 +2527,505 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
2524
2527
|
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:contents}.alert{display:flex;align-items:flex-start;gap:12px;padding:12px 16px;border-radius:var(--ls-border-radius-md, 6px);font-family:var(--ls-font-family, \"Nunito\", sans-serif);font-size:14px;line-height:1.5;position:relative;width:100%;box-sizing:border-box}.alert-icon{flex-shrink:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center}.alert-icon svg{width:100%;height:100%}.alert-content{flex:1;min-width:0}.alert-title{font-weight:600;margin-bottom:4px}.alert-message{padding-top:2px;font-weight:400}.alert-close{flex-shrink:0;background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;color:inherit;opacity:.7;transition:opacity var(--ls-transition-duration, .3s);display:flex;align-items:center;justify-content:center}.alert-close:hover{opacity:1}.alert-default-success{background-color:var(--ls-color-success-light);border-left:4px solid var(--ls-color-success);color:var(--ls-color-success)}.alert-default-error{background-color:var(--ls-color-danger-light);border-left:4px solid var(--ls-color-danger);color:var(--ls-color-danger)}.alert-default-warning{background-color:var(--ls-color-warning-light);border-left:4px solid var(--ls-color-warning);color:var(--ls-color-warning)}.alert-default-info{background-color:var(--ls-color-info-light);border-left:4px solid var(--ls-color-info);color:var(--ls-color-info)}.alert-default-primary{background-color:var(--ls-color-primary-light);border-left:4px solid var(--ls-color-primary);color:var(--ls-color-primary)}.alert-default-secondary{background-color:var(--ls-color-secondary-light);border-left:4px solid var(--ls-color-secondary);color:var(--ls-color-secondary)}.alert-filled-success{background-color:var(--ls-color-success);color:#fff}.alert-filled-error{background-color:var(--ls-color-danger);color:#fff}.alert-filled-warning{background-color:var(--ls-color-warning);color:#fff}.alert-filled-info{background-color:var(--ls-color-info);color:#fff}.alert-filled-primary{background-color:var(--ls-color-primary);color:#fff}.alert-filled-secondary{background-color:var(--ls-color-secondary);color:#fff}.alert-outlined-success{background-color:transparent;border:1px solid var(--ls-color-success);color:var(--ls-color-success)}.alert-outlined-error{background-color:transparent;border:1px solid var(--ls-color-danger);color:var(--ls-color-danger)}.alert-outlined-warning{background-color:transparent;border:1px solid var(--ls-color-warning);color:var(--ls-color-warning)}.alert-outlined-info{background-color:transparent;border:1px solid var(--ls-color-info);color:var(--ls-color-info)}.alert-outlined-primary{background-color:transparent;border:1px solid var(--ls-color-primary);color:var(--ls-color-primary)}.alert-outlined-secondary{background-color:transparent;border:1px solid var(--ls-color-secondary);color:var(--ls-color-secondary)}.alert[style*=--alert-custom-color]{border-color:var(--alert-custom-color)}.alert-default-success[style*=--alert-custom-color],.alert-default-error[style*=--alert-custom-color],.alert-default-warning[style*=--alert-custom-color],.alert-default-info[style*=--alert-custom-color],.alert-default-primary[style*=--alert-custom-color],.alert-default-secondary[style*=--alert-custom-color]{border-left-color:var(--alert-custom-color);color:var(--alert-custom-color)}.alert-filled-success[style*=--alert-custom-color],.alert-filled-error[style*=--alert-custom-color],.alert-filled-warning[style*=--alert-custom-color],.alert-filled-info[style*=--alert-custom-color],.alert-filled-primary[style*=--alert-custom-color],.alert-filled-secondary[style*=--alert-custom-color]{background-color:var(--alert-custom-color)}.alert-outlined-success[style*=--alert-custom-color],.alert-outlined-error[style*=--alert-custom-color],.alert-outlined-warning[style*=--alert-custom-color],.alert-outlined-info[style*=--alert-custom-color],.alert-outlined-primary[style*=--alert-custom-color],.alert-outlined-secondary[style*=--alert-custom-color]{border-color:var(--alert-custom-color);color:var(--alert-custom-color)}body.dark .alert-default-success{background-color:var(--ls-color-success-dark-light);border-left-color:var(--ls-color-success);color:var(--ls-color-success)}body.dark .alert-default-error{background-color:var(--ls-color-danger-dark-light);border-left-color:var(--ls-color-danger);color:var(--ls-color-danger)}body.dark .alert-default-warning{background-color:var(--ls-color-warning-dark-light);border-left-color:var(--ls-color-warning);color:var(--ls-color-warning)}body.dark .alert-default-info{background-color:var(--ls-color-info-dark-light);border-left-color:var(--ls-color-info);color:var(--ls-color-info)}body.dark .alert-default-primary{background-color:var(--ls-color-primary-dark-light);border-left-color:var(--ls-color-primary);color:var(--ls-color-primary)}body.dark .alert-default-secondary{background-color:var(--ls-color-secondary-dark-light);border-left-color:var(--ls-color-secondary);color:var(--ls-color-secondary)}body.dark .alert-outlined-success{border-color:var(--ls-color-success);color:var(--ls-color-success)}body.dark .alert-outlined-error{border-color:var(--ls-color-danger);color:var(--ls-color-danger)}body.dark .alert-outlined-warning{border-color:var(--ls-color-warning);color:var(--ls-color-warning)}body.dark .alert-outlined-info{border-color:var(--ls-color-info);color:var(--ls-color-info)}body.dark .alert-outlined-primary{border-color:var(--ls-color-primary);color:var(--ls-color-primary)}body.dark .alert-outlined-secondary{border-color:var(--ls-color-secondary);color:var(--ls-color-secondary)}\n"] }]
|
|
2525
2528
|
}], propDecorators: { severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconMapping: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconMapping", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], alertTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "alertTitle", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], onClose: [{ type: i0.Output, args: ["onClose"] }] } });
|
|
2526
2529
|
|
|
2530
|
+
/**
|
|
2531
|
+
* Renders an anchored floating menu panel attached to a trigger element.
|
|
2532
|
+
*
|
|
2533
|
+
* Supports both **controlled** and **directive-driven** open modes:
|
|
2534
|
+
* - **Controlled**: bind `[(open)]` and respond to `opened`/`closed` outputs.
|
|
2535
|
+
* - **Directive-driven**: apply `lsMenuTriggerFor` to any host element;
|
|
2536
|
+
* the directive calls `setAnchorEl()` and `toggle()` automatically.
|
|
2537
|
+
*
|
|
2538
|
+
* Panel position is derived from the anchor element's bounding rect combined
|
|
2539
|
+
* with `anchorOrigin` (attachment point on the trigger) and `transformOrigin`
|
|
2540
|
+
* (attachment point on the panel). Position is recomputed each time the
|
|
2541
|
+
* panel opens via a `setTimeout(0)` deferral to ensure the panel is measured.
|
|
2542
|
+
*
|
|
2543
|
+
* When `disablePortal` is `false` (default), the panel uses `position: fixed`
|
|
2544
|
+
* for viewport-relative placement. When `true`, it uses `position: absolute`.
|
|
2545
|
+
*
|
|
2546
|
+
* Keyboard: `Escape` closes the panel; `ArrowDown`/`ArrowUp` move focus
|
|
2547
|
+
* between enabled `[role="menuitem"]` elements inside the panel.
|
|
2548
|
+
*
|
|
2549
|
+
* @example
|
|
2550
|
+
* ```html
|
|
2551
|
+
* <!-- Controlled -->
|
|
2552
|
+
* <ls-menu [(open)]="isOpen" [anchorEl]="triggerEl">
|
|
2553
|
+
* <ls-menu-item (itemClick)="onEdit()">Edit</ls-menu-item>
|
|
2554
|
+
* </ls-menu>
|
|
2555
|
+
*
|
|
2556
|
+
* <!-- Directive-driven -->
|
|
2557
|
+
* <button [lsMenuTriggerFor]="myMenu">Open</button>
|
|
2558
|
+
* <ls-menu #myMenu>
|
|
2559
|
+
* <ls-menu-item>Delete</ls-menu-item>
|
|
2560
|
+
* </ls-menu>
|
|
2561
|
+
* ```
|
|
2562
|
+
*/
|
|
2563
|
+
class MenuComponent {
|
|
2564
|
+
constructor() {
|
|
2565
|
+
this._document = inject(DOCUMENT);
|
|
2566
|
+
this._destroyRef = inject(DestroyRef);
|
|
2567
|
+
/** Controls the visibility of the menu panel. Supports two-way binding. */
|
|
2568
|
+
this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
|
|
2569
|
+
/**
|
|
2570
|
+
* Element used to position the menu panel.
|
|
2571
|
+
*
|
|
2572
|
+
* Accepts a native DOM element, an `ElementRef`, or any Angular component
|
|
2573
|
+
* that exposes a `nativeElement: HTMLElement` property (e.g. `ls-button`).
|
|
2574
|
+
* In templates, pass a template reference variable directly:
|
|
2575
|
+
* `[anchorEl]="btn"` where `#btn` is on any element or component.
|
|
2576
|
+
*
|
|
2577
|
+
* When using `lsMenuTriggerFor`, this is set automatically by the directive
|
|
2578
|
+
* via `setAnchorEl()`. When using controlled mode, bind directly.
|
|
2579
|
+
*
|
|
2580
|
+
* @default null
|
|
2581
|
+
*/
|
|
2582
|
+
this.anchorEl = input(null, ...(ngDevMode ? [{ debugName: "anchorEl" }] : []));
|
|
2583
|
+
/**
|
|
2584
|
+
* Defines the attachment point on the anchor element.
|
|
2585
|
+
*
|
|
2586
|
+
* Combined with `transformOrigin` to compute the panel's `top`/`left`
|
|
2587
|
+
* position via `getBoundingClientRect()`.
|
|
2588
|
+
*
|
|
2589
|
+
* @default { vertical: 'bottom', horizontal: 'left' }
|
|
2590
|
+
*/
|
|
2591
|
+
this.anchorOrigin = input({
|
|
2592
|
+
vertical: 'bottom',
|
|
2593
|
+
horizontal: 'left',
|
|
2594
|
+
}, ...(ngDevMode ? [{ debugName: "anchorOrigin" }] : []));
|
|
2595
|
+
/**
|
|
2596
|
+
* Defines the attachment point on the menu panel surface.
|
|
2597
|
+
*
|
|
2598
|
+
* The panel is translated so this point aligns with `anchorOrigin`.
|
|
2599
|
+
*
|
|
2600
|
+
* @default { vertical: 'top', horizontal: 'left' }
|
|
2601
|
+
*/
|
|
2602
|
+
this.transformOrigin = input({
|
|
2603
|
+
vertical: 'top',
|
|
2604
|
+
horizontal: 'left',
|
|
2605
|
+
}, ...(ngDevMode ? [{ debugName: "transformOrigin" }] : []));
|
|
2606
|
+
/**
|
|
2607
|
+
* When `false` (default), the panel uses `position: fixed` for
|
|
2608
|
+
* viewport-relative placement. When `true`, uses `position: absolute`
|
|
2609
|
+
* and renders relative to the nearest positioned ancestor.
|
|
2610
|
+
*
|
|
2611
|
+
* @default false
|
|
2612
|
+
*/
|
|
2613
|
+
this.disablePortal = input(false, ...(ngDevMode ? [{ debugName: "disablePortal" }] : []));
|
|
2614
|
+
/**
|
|
2615
|
+
* When `true`, the panel closes automatically after the user activates
|
|
2616
|
+
* a `ls-menu-item` (i.e., a `[role="menuitem"]` element) inside it.
|
|
2617
|
+
*
|
|
2618
|
+
* @default true
|
|
2619
|
+
*/
|
|
2620
|
+
this.closeOnClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnClick" }] : []));
|
|
2621
|
+
/**
|
|
2622
|
+
* Emits when the panel's opening animation completes.
|
|
2623
|
+
* Does NOT emit when `open` is set programmatically without animation.
|
|
2624
|
+
*/
|
|
2625
|
+
this.opened = output();
|
|
2626
|
+
/**
|
|
2627
|
+
* Emits when the panel's closing animation completes and the panel
|
|
2628
|
+
* is fully hidden. In controlled mode, the host can use this to update
|
|
2629
|
+
* state after the transition finishes.
|
|
2630
|
+
*/
|
|
2631
|
+
this.closed = output();
|
|
2632
|
+
/**
|
|
2633
|
+
* Emits when the user clicks the transparent backdrop behind the panel.
|
|
2634
|
+
* The menu closes automatically after this output emits.
|
|
2635
|
+
*/
|
|
2636
|
+
this.backdropClick = output();
|
|
2637
|
+
this._panelRef = viewChild('panelRef', ...(ngDevMode ? [{ debugName: "_panelRef" }] : []));
|
|
2638
|
+
this._isAnimating = signal(false, ...(ngDevMode ? [{ debugName: "_isAnimating" }] : []));
|
|
2639
|
+
this._wasOpen = false;
|
|
2640
|
+
this._previouslyFocused = null;
|
|
2641
|
+
this._savedBodyOverflow = '';
|
|
2642
|
+
this._savedBodyPaddingRight = '';
|
|
2643
|
+
this._resolvedAnchorEl = signal(null, ...(ngDevMode ? [{ debugName: "_resolvedAnchorEl" }] : []));
|
|
2644
|
+
this._repositionHandler = () => this._computeAndApplyPosition();
|
|
2645
|
+
// Manages animation state, scroll lock, focus, and repositioning listeners
|
|
2646
|
+
// when the panel opens or closes.
|
|
2647
|
+
effect(() => {
|
|
2648
|
+
const isOpen = this.open();
|
|
2649
|
+
untracked(() => {
|
|
2650
|
+
if (isOpen) {
|
|
2651
|
+
this._isAnimating.set(true);
|
|
2652
|
+
this._previouslyFocused = this._document.activeElement;
|
|
2653
|
+
this._savedBodyOverflow = this._document.body.style.overflow;
|
|
2654
|
+
this._savedBodyPaddingRight = this._document.body.style.paddingRight;
|
|
2655
|
+
const scrollbarWidth = this._getScrollbarWidth();
|
|
2656
|
+
if (scrollbarWidth > 0) {
|
|
2657
|
+
this._document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
2658
|
+
}
|
|
2659
|
+
this._document.body.style.overflow = 'hidden';
|
|
2660
|
+
setTimeout(() => this._panelRef()?.nativeElement.focus(), 0);
|
|
2661
|
+
window.addEventListener('resize', this._repositionHandler);
|
|
2662
|
+
window.addEventListener('scroll', this._repositionHandler, true);
|
|
2663
|
+
this._wasOpen = true;
|
|
2664
|
+
}
|
|
2665
|
+
else if (this._wasOpen) {
|
|
2666
|
+
this._isAnimating.set(true);
|
|
2667
|
+
window.removeEventListener('resize', this._repositionHandler);
|
|
2668
|
+
window.removeEventListener('scroll', this._repositionHandler, true);
|
|
2669
|
+
this._wasOpen = false;
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2672
|
+
});
|
|
2673
|
+
// Computes and applies panel position whenever the panel enters the DOM
|
|
2674
|
+
// or any positioning input changes. Using a separate effect (rather than
|
|
2675
|
+
// setTimeout) guarantees that Angular has already updated the viewChild
|
|
2676
|
+
// signal before this runs, so _panelRef() is always non-null here.
|
|
2677
|
+
effect(() => {
|
|
2678
|
+
const panel = this._panelRef()?.nativeElement;
|
|
2679
|
+
if (!panel)
|
|
2680
|
+
return;
|
|
2681
|
+
this._computeAndApplyPosition();
|
|
2682
|
+
});
|
|
2683
|
+
this._destroyRef.onDestroy(() => {
|
|
2684
|
+
window.removeEventListener('resize', this._repositionHandler);
|
|
2685
|
+
window.removeEventListener('scroll', this._repositionHandler, true);
|
|
2686
|
+
if (this._wasOpen) {
|
|
2687
|
+
this._document.body.style.overflow = this._savedBodyOverflow;
|
|
2688
|
+
this._document.body.style.paddingRight = this._savedBodyPaddingRight;
|
|
2689
|
+
this._previouslyFocused?.focus?.();
|
|
2690
|
+
}
|
|
2691
|
+
});
|
|
2692
|
+
}
|
|
2693
|
+
/** Toggles the panel between open and closed. */
|
|
2694
|
+
toggle() {
|
|
2695
|
+
this.open.set(!this.open());
|
|
2696
|
+
}
|
|
2697
|
+
/**
|
|
2698
|
+
* Sets the anchor element used for panel positioning.
|
|
2699
|
+
* Called automatically by `MenuTriggerDirective`.
|
|
2700
|
+
*/
|
|
2701
|
+
setAnchorEl(el) {
|
|
2702
|
+
this._resolvedAnchorEl.set(el);
|
|
2703
|
+
}
|
|
2704
|
+
/** Closes the panel without waiting for a user interaction. */
|
|
2705
|
+
requestClose() {
|
|
2706
|
+
this.open.set(false);
|
|
2707
|
+
}
|
|
2708
|
+
onBackdropClick(event) {
|
|
2709
|
+
this.backdropClick.emit(event);
|
|
2710
|
+
this.open.set(false);
|
|
2711
|
+
}
|
|
2712
|
+
onPanelClick(event) {
|
|
2713
|
+
if (!this.closeOnClick())
|
|
2714
|
+
return;
|
|
2715
|
+
const target = event.target;
|
|
2716
|
+
if (target.closest('[role="menuitem"]') !== null) {
|
|
2717
|
+
this.open.set(false);
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
onAnimationEnd() {
|
|
2721
|
+
this._isAnimating.set(false);
|
|
2722
|
+
if (this.open()) {
|
|
2723
|
+
this.opened.emit();
|
|
2724
|
+
}
|
|
2725
|
+
else {
|
|
2726
|
+
this._document.body.style.overflow = this._savedBodyOverflow;
|
|
2727
|
+
this._document.body.style.paddingRight = this._savedBodyPaddingRight;
|
|
2728
|
+
this.closed.emit();
|
|
2729
|
+
this._previouslyFocused?.focus?.();
|
|
2730
|
+
this._previouslyFocused = null;
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
onEscape() {
|
|
2734
|
+
if (this.open()) {
|
|
2735
|
+
this.open.set(false);
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
onArrowDown(event) {
|
|
2739
|
+
if (!this.open())
|
|
2740
|
+
return;
|
|
2741
|
+
event.preventDefault();
|
|
2742
|
+
this._moveFocus(1);
|
|
2743
|
+
}
|
|
2744
|
+
onArrowUp(event) {
|
|
2745
|
+
if (!this.open())
|
|
2746
|
+
return;
|
|
2747
|
+
event.preventDefault();
|
|
2748
|
+
this._moveFocus(-1);
|
|
2749
|
+
}
|
|
2750
|
+
_computeAndApplyPosition() {
|
|
2751
|
+
const rawAnchor = this.anchorEl() ?? this._resolvedAnchorEl();
|
|
2752
|
+
const panel = this._panelRef()?.nativeElement;
|
|
2753
|
+
if (!rawAnchor || !panel)
|
|
2754
|
+
return;
|
|
2755
|
+
const anchorEl = this._toHTMLElement(rawAnchor);
|
|
2756
|
+
if (!anchorEl)
|
|
2757
|
+
return;
|
|
2758
|
+
const anchorRect = anchorEl.getBoundingClientRect();
|
|
2759
|
+
const panelRect = panel.getBoundingClientRect();
|
|
2760
|
+
const ao = this.anchorOrigin();
|
|
2761
|
+
const to = this.transformOrigin();
|
|
2762
|
+
const anchorX = anchorRect.left +
|
|
2763
|
+
(ao.horizontal === 'center'
|
|
2764
|
+
? anchorRect.width / 2
|
|
2765
|
+
: ao.horizontal === 'right'
|
|
2766
|
+
? anchorRect.width
|
|
2767
|
+
: 0);
|
|
2768
|
+
const anchorY = anchorRect.top +
|
|
2769
|
+
(ao.vertical === 'center'
|
|
2770
|
+
? anchorRect.height / 2
|
|
2771
|
+
: ao.vertical === 'bottom'
|
|
2772
|
+
? anchorRect.height
|
|
2773
|
+
: 0);
|
|
2774
|
+
const transformX = to.horizontal === 'center'
|
|
2775
|
+
? panelRect.width / 2
|
|
2776
|
+
: to.horizontal === 'right'
|
|
2777
|
+
? panelRect.width
|
|
2778
|
+
: 0;
|
|
2779
|
+
const transformY = to.vertical === 'center'
|
|
2780
|
+
? panelRect.height / 2
|
|
2781
|
+
: to.vertical === 'bottom'
|
|
2782
|
+
? panelRect.height
|
|
2783
|
+
: 0;
|
|
2784
|
+
panel.style.setProperty('--menu-top', `${anchorY - transformY}px`);
|
|
2785
|
+
panel.style.setProperty('--menu-left', `${anchorX - transformX}px`);
|
|
2786
|
+
}
|
|
2787
|
+
/**
|
|
2788
|
+
* Resolves any supported anchor value to a plain `HTMLElement`.
|
|
2789
|
+
*
|
|
2790
|
+
* Handles: `HTMLElement`, `ElementRef<HTMLElement>`, and objects that expose
|
|
2791
|
+
* a `nativeElement: HTMLElement` property (e.g. `ls-button` component refs).
|
|
2792
|
+
*/
|
|
2793
|
+
_toHTMLElement(anchor) {
|
|
2794
|
+
if (!anchor)
|
|
2795
|
+
return null;
|
|
2796
|
+
if (anchor instanceof HTMLElement)
|
|
2797
|
+
return anchor;
|
|
2798
|
+
if (typeof anchor === 'object' &&
|
|
2799
|
+
anchor !== null &&
|
|
2800
|
+
'nativeElement' in anchor) {
|
|
2801
|
+
const el = anchor.nativeElement;
|
|
2802
|
+
return el instanceof HTMLElement ? el : null;
|
|
2803
|
+
}
|
|
2804
|
+
return null;
|
|
2805
|
+
}
|
|
2806
|
+
_moveFocus(direction) {
|
|
2807
|
+
const panel = this._panelRef()?.nativeElement;
|
|
2808
|
+
if (!panel)
|
|
2809
|
+
return;
|
|
2810
|
+
const items = Array.from(panel.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])'));
|
|
2811
|
+
if (items.length === 0)
|
|
2812
|
+
return;
|
|
2813
|
+
const currentIndex = items.indexOf(this._document.activeElement);
|
|
2814
|
+
const nextIndex = currentIndex === -1
|
|
2815
|
+
? direction === 1
|
|
2816
|
+
? 0
|
|
2817
|
+
: items.length - 1
|
|
2818
|
+
: (currentIndex + direction + items.length) % items.length;
|
|
2819
|
+
items[nextIndex]?.focus();
|
|
2820
|
+
}
|
|
2821
|
+
_getScrollbarWidth() {
|
|
2822
|
+
return window.innerWidth - this._document.documentElement.clientWidth;
|
|
2823
|
+
}
|
|
2824
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2825
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: MenuComponent, isStandalone: true, selector: "ls-menu", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, anchorEl: { classPropertyName: "anchorEl", publicName: "anchorEl", isSignal: true, isRequired: false, transformFunction: null }, anchorOrigin: { classPropertyName: "anchorOrigin", publicName: "anchorOrigin", isSignal: true, isRequired: false, transformFunction: null }, transformOrigin: { classPropertyName: "transformOrigin", publicName: "transformOrigin", isSignal: true, isRequired: false, transformFunction: null }, disablePortal: { classPropertyName: "disablePortal", publicName: "disablePortal", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed", backdropClick: "backdropClick" }, host: { listeners: { "document:keydown.escape": "onEscape()", "document:keydown.arrowdown": "onArrowDown($event)", "document:keydown.arrowup": "onArrowUp($event)" } }, viewQueries: [{ propertyName: "_panelRef", first: true, predicate: ["panelRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2826
|
+
@if (open() || _isAnimating()) {
|
|
2827
|
+
<div class="menu-backdrop" (click)="onBackdropClick($event)"></div>
|
|
2828
|
+
<div
|
|
2829
|
+
#panelRef
|
|
2830
|
+
class="menu-panel"
|
|
2831
|
+
[class.menu-panel-inline]="disablePortal()"
|
|
2832
|
+
[class.menu-enter]="open() && _isAnimating()"
|
|
2833
|
+
[class.menu-leave]="!open() && _isAnimating()"
|
|
2834
|
+
role="menu"
|
|
2835
|
+
tabindex="-1"
|
|
2836
|
+
(click)="onPanelClick($event)"
|
|
2837
|
+
(animationend)="onAnimationEnd()">
|
|
2838
|
+
<ng-content />
|
|
2839
|
+
</div>
|
|
2840
|
+
}
|
|
2841
|
+
`, isInline: true, styles: [":host{display:contents}.menu-backdrop{position:fixed;inset:0;z-index:var(--ls-menu-z-index);background-color:transparent}.menu-panel{position:fixed;top:var(--menu-top, 0px);left:var(--menu-left, 0px);z-index:calc(var(--ls-menu-z-index) + 1);min-width:10rem;padding:.25rem 0;background-color:#fff;border-radius:var(--ls-border-radius-md);box-shadow:0 4px 24px #0000001f;outline:none}.menu-panel.menu-panel-inline{position:absolute}@keyframes menu-enter-kf{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes menu-leave-kf{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.95) translateY(-4px)}}.menu-panel.menu-enter{animation:menu-enter-kf .15s ease-out forwards}.menu-panel.menu-leave{animation:menu-leave-kf .1s ease-in forwards}.menu-item{display:flex;align-items:center;width:100%;padding:.5rem 1rem;background:none;border:none;text-align:left;font-family:var(--ls-font-family);font-size:.875rem;color:#3b3f5c;cursor:pointer;transition:background-color var(--ls-transition-duration) ease}.menu-item:hover:not(:disabled){background-color:#f1f2f3}.menu-item:focus-visible{outline:2px solid var(--ls-color-primary);outline-offset:-2px;background-color:#f1f2f3}.menu-item-dense{padding-top:.25rem;padding-bottom:.25rem}.menu-item-no-gutters{padding-inline:0}.menu-item-divider{border-bottom:1px solid #e0e6ed}.menu-item-disabled{color:#888ea8;pointer-events:none;cursor:not-allowed}body.dark .menu-panel{background-color:#1b2e4b;box-shadow:0 4px 24px #0006}body.dark .menu-item{color:#e0e6ed}body.dark .menu-item:hover:not(:disabled){background-color:#253b5e}body.dark .menu-item:focus-visible{background-color:#253b5e}body.dark .menu-item-divider{border-bottom-color:#253b5e}body.dark .menu-item-disabled{color:#506690}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2842
|
+
}
|
|
2843
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MenuComponent, decorators: [{
|
|
2844
|
+
type: Component,
|
|
2845
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [], selector: 'ls-menu', standalone: true, template: `
|
|
2846
|
+
@if (open() || _isAnimating()) {
|
|
2847
|
+
<div class="menu-backdrop" (click)="onBackdropClick($event)"></div>
|
|
2848
|
+
<div
|
|
2849
|
+
#panelRef
|
|
2850
|
+
class="menu-panel"
|
|
2851
|
+
[class.menu-panel-inline]="disablePortal()"
|
|
2852
|
+
[class.menu-enter]="open() && _isAnimating()"
|
|
2853
|
+
[class.menu-leave]="!open() && _isAnimating()"
|
|
2854
|
+
role="menu"
|
|
2855
|
+
tabindex="-1"
|
|
2856
|
+
(click)="onPanelClick($event)"
|
|
2857
|
+
(animationend)="onAnimationEnd()">
|
|
2858
|
+
<ng-content />
|
|
2859
|
+
</div>
|
|
2860
|
+
}
|
|
2861
|
+
`, styles: [":host{display:contents}.menu-backdrop{position:fixed;inset:0;z-index:var(--ls-menu-z-index);background-color:transparent}.menu-panel{position:fixed;top:var(--menu-top, 0px);left:var(--menu-left, 0px);z-index:calc(var(--ls-menu-z-index) + 1);min-width:10rem;padding:.25rem 0;background-color:#fff;border-radius:var(--ls-border-radius-md);box-shadow:0 4px 24px #0000001f;outline:none}.menu-panel.menu-panel-inline{position:absolute}@keyframes menu-enter-kf{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes menu-leave-kf{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.95) translateY(-4px)}}.menu-panel.menu-enter{animation:menu-enter-kf .15s ease-out forwards}.menu-panel.menu-leave{animation:menu-leave-kf .1s ease-in forwards}.menu-item{display:flex;align-items:center;width:100%;padding:.5rem 1rem;background:none;border:none;text-align:left;font-family:var(--ls-font-family);font-size:.875rem;color:#3b3f5c;cursor:pointer;transition:background-color var(--ls-transition-duration) ease}.menu-item:hover:not(:disabled){background-color:#f1f2f3}.menu-item:focus-visible{outline:2px solid var(--ls-color-primary);outline-offset:-2px;background-color:#f1f2f3}.menu-item-dense{padding-top:.25rem;padding-bottom:.25rem}.menu-item-no-gutters{padding-inline:0}.menu-item-divider{border-bottom:1px solid #e0e6ed}.menu-item-disabled{color:#888ea8;pointer-events:none;cursor:not-allowed}body.dark .menu-panel{background-color:#1b2e4b;box-shadow:0 4px 24px #0006}body.dark .menu-item{color:#e0e6ed}body.dark .menu-item:hover:not(:disabled){background-color:#253b5e}body.dark .menu-item:focus-visible{background-color:#253b5e}body.dark .menu-item-divider{border-bottom-color:#253b5e}body.dark .menu-item-disabled{color:#506690}\n"] }]
|
|
2862
|
+
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], anchorEl: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchorEl", required: false }] }], anchorOrigin: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchorOrigin", required: false }] }], transformOrigin: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformOrigin", required: false }] }], disablePortal: [{ type: i0.Input, args: [{ isSignal: true, alias: "disablePortal", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], backdropClick: [{ type: i0.Output, args: ["backdropClick"] }], _panelRef: [{ type: i0.ViewChild, args: ['panelRef', { isSignal: true }] }], onEscape: [{
|
|
2863
|
+
type: HostListener,
|
|
2864
|
+
args: ['document:keydown.escape']
|
|
2865
|
+
}], onArrowDown: [{
|
|
2866
|
+
type: HostListener,
|
|
2867
|
+
args: ['document:keydown.arrowdown', ['$event']]
|
|
2868
|
+
}], onArrowUp: [{
|
|
2869
|
+
type: HostListener,
|
|
2870
|
+
args: ['document:keydown.arrowup', ['$event']]
|
|
2871
|
+
}] } });
|
|
2872
|
+
|
|
2873
|
+
/**
|
|
2874
|
+
* Interactive item rendered inside an `ls-menu` panel.
|
|
2875
|
+
*
|
|
2876
|
+
* Renders a `<button role="menuitem">` that projects its label via
|
|
2877
|
+
* `<ng-content>`. Visual density, gutters, and a bottom divider are
|
|
2878
|
+
* configurable via inputs. When `disabled` is `true`, the item is not
|
|
2879
|
+
* interactive and the `itemClick` output will not emit.
|
|
2880
|
+
*
|
|
2881
|
+
* @example
|
|
2882
|
+
* ```html
|
|
2883
|
+
* <ls-menu-item [dense]="true" (itemClick)="onEdit($event)">
|
|
2884
|
+
* Edit
|
|
2885
|
+
* </ls-menu-item>
|
|
2886
|
+
* ```
|
|
2887
|
+
*/
|
|
2888
|
+
class MenuItemComponent {
|
|
2889
|
+
constructor() {
|
|
2890
|
+
/**
|
|
2891
|
+
* Reduces the vertical padding of the item for compact layouts.
|
|
2892
|
+
*
|
|
2893
|
+
* @default false
|
|
2894
|
+
*/
|
|
2895
|
+
this.dense = input(false, ...(ngDevMode ? [{ debugName: "dense" }] : []));
|
|
2896
|
+
/**
|
|
2897
|
+
* Removes left and right padding when `true`.
|
|
2898
|
+
*
|
|
2899
|
+
* @default false
|
|
2900
|
+
*/
|
|
2901
|
+
this.disableGutters = input(false, ...(ngDevMode ? [{ debugName: "disableGutters" }] : []));
|
|
2902
|
+
/**
|
|
2903
|
+
* Adds a 1px border at the bottom of the item to act as a visual divider.
|
|
2904
|
+
*
|
|
2905
|
+
* @default false
|
|
2906
|
+
*/
|
|
2907
|
+
this.divider = input(false, ...(ngDevMode ? [{ debugName: "divider" }] : []));
|
|
2908
|
+
/**
|
|
2909
|
+
* Prevents interaction. Applies disabled styling, sets `aria-disabled="true"`,
|
|
2910
|
+
* and suppresses the `itemClick` output.
|
|
2911
|
+
*
|
|
2912
|
+
* @default false
|
|
2913
|
+
*/
|
|
2914
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
2915
|
+
/**
|
|
2916
|
+
* Emits the originating `MouseEvent` when the user activates the item.
|
|
2917
|
+
* Does NOT emit when `disabled` is `true`.
|
|
2918
|
+
*/
|
|
2919
|
+
this.itemClick = output();
|
|
2920
|
+
this._itemClasses = computed(() => {
|
|
2921
|
+
const classes = ['menu-item'];
|
|
2922
|
+
if (this.dense())
|
|
2923
|
+
classes.push('menu-item-dense');
|
|
2924
|
+
if (this.disableGutters())
|
|
2925
|
+
classes.push('menu-item-no-gutters');
|
|
2926
|
+
if (this.divider())
|
|
2927
|
+
classes.push('menu-item-divider');
|
|
2928
|
+
if (this.disabled())
|
|
2929
|
+
classes.push('menu-item-disabled');
|
|
2930
|
+
return classes.join(' ');
|
|
2931
|
+
}, ...(ngDevMode ? [{ debugName: "_itemClasses" }] : []));
|
|
2932
|
+
}
|
|
2933
|
+
handleClick(event) {
|
|
2934
|
+
if (this.disabled())
|
|
2935
|
+
return;
|
|
2936
|
+
this.itemClick.emit(event);
|
|
2937
|
+
}
|
|
2938
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2939
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: MenuItemComponent, isStandalone: true, selector: "ls-menu-item", inputs: { dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, disableGutters: { classPropertyName: "disableGutters", publicName: "disableGutters", isSignal: true, isRequired: false, transformFunction: null }, divider: { classPropertyName: "divider", publicName: "divider", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, ngImport: i0, template: `
|
|
2940
|
+
<button
|
|
2941
|
+
type="button"
|
|
2942
|
+
[class]="_itemClasses()"
|
|
2943
|
+
[disabled]="disabled()"
|
|
2944
|
+
[attr.aria-disabled]="disabled() ? 'true' : null"
|
|
2945
|
+
role="menuitem"
|
|
2946
|
+
(click)="handleClick($event)">
|
|
2947
|
+
<ng-content />
|
|
2948
|
+
</button>
|
|
2949
|
+
`, isInline: true, styles: [":host{display:contents}.menu-backdrop{position:fixed;inset:0;z-index:var(--ls-menu-z-index);background-color:transparent}.menu-panel{position:fixed;top:var(--menu-top, 0px);left:var(--menu-left, 0px);z-index:calc(var(--ls-menu-z-index) + 1);min-width:10rem;padding:.25rem 0;background-color:#fff;border-radius:var(--ls-border-radius-md);box-shadow:0 4px 24px #0000001f;outline:none}.menu-panel.menu-panel-inline{position:absolute}@keyframes menu-enter-kf{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes menu-leave-kf{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.95) translateY(-4px)}}.menu-panel.menu-enter{animation:menu-enter-kf .15s ease-out forwards}.menu-panel.menu-leave{animation:menu-leave-kf .1s ease-in forwards}.menu-item{display:flex;align-items:center;width:100%;padding:.5rem 1rem;background:none;border:none;text-align:left;font-family:var(--ls-font-family);font-size:.875rem;color:#3b3f5c;cursor:pointer;transition:background-color var(--ls-transition-duration) ease}.menu-item:hover:not(:disabled){background-color:#f1f2f3}.menu-item:focus-visible{outline:2px solid var(--ls-color-primary);outline-offset:-2px;background-color:#f1f2f3}.menu-item-dense{padding-top:.25rem;padding-bottom:.25rem}.menu-item-no-gutters{padding-inline:0}.menu-item-divider{border-bottom:1px solid #e0e6ed}.menu-item-disabled{color:#888ea8;pointer-events:none;cursor:not-allowed}body.dark .menu-panel{background-color:#1b2e4b;box-shadow:0 4px 24px #0006}body.dark .menu-item{color:#e0e6ed}body.dark .menu-item:hover:not(:disabled){background-color:#253b5e}body.dark .menu-item:focus-visible{background-color:#253b5e}body.dark .menu-item-divider{border-bottom-color:#253b5e}body.dark .menu-item-disabled{color:#506690}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2950
|
+
}
|
|
2951
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MenuItemComponent, decorators: [{
|
|
2952
|
+
type: Component,
|
|
2953
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [], selector: 'ls-menu-item', standalone: true, template: `
|
|
2954
|
+
<button
|
|
2955
|
+
type="button"
|
|
2956
|
+
[class]="_itemClasses()"
|
|
2957
|
+
[disabled]="disabled()"
|
|
2958
|
+
[attr.aria-disabled]="disabled() ? 'true' : null"
|
|
2959
|
+
role="menuitem"
|
|
2960
|
+
(click)="handleClick($event)">
|
|
2961
|
+
<ng-content />
|
|
2962
|
+
</button>
|
|
2963
|
+
`, styles: [":host{display:contents}.menu-backdrop{position:fixed;inset:0;z-index:var(--ls-menu-z-index);background-color:transparent}.menu-panel{position:fixed;top:var(--menu-top, 0px);left:var(--menu-left, 0px);z-index:calc(var(--ls-menu-z-index) + 1);min-width:10rem;padding:.25rem 0;background-color:#fff;border-radius:var(--ls-border-radius-md);box-shadow:0 4px 24px #0000001f;outline:none}.menu-panel.menu-panel-inline{position:absolute}@keyframes menu-enter-kf{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes menu-leave-kf{0%{opacity:1;transform:scale(1) translateY(0)}to{opacity:0;transform:scale(.95) translateY(-4px)}}.menu-panel.menu-enter{animation:menu-enter-kf .15s ease-out forwards}.menu-panel.menu-leave{animation:menu-leave-kf .1s ease-in forwards}.menu-item{display:flex;align-items:center;width:100%;padding:.5rem 1rem;background:none;border:none;text-align:left;font-family:var(--ls-font-family);font-size:.875rem;color:#3b3f5c;cursor:pointer;transition:background-color var(--ls-transition-duration) ease}.menu-item:hover:not(:disabled){background-color:#f1f2f3}.menu-item:focus-visible{outline:2px solid var(--ls-color-primary);outline-offset:-2px;background-color:#f1f2f3}.menu-item-dense{padding-top:.25rem;padding-bottom:.25rem}.menu-item-no-gutters{padding-inline:0}.menu-item-divider{border-bottom:1px solid #e0e6ed}.menu-item-disabled{color:#888ea8;pointer-events:none;cursor:not-allowed}body.dark .menu-panel{background-color:#1b2e4b;box-shadow:0 4px 24px #0006}body.dark .menu-item{color:#e0e6ed}body.dark .menu-item:hover:not(:disabled){background-color:#253b5e}body.dark .menu-item:focus-visible{background-color:#253b5e}body.dark .menu-item-divider{border-bottom-color:#253b5e}body.dark .menu-item-disabled{color:#506690}\n"] }]
|
|
2964
|
+
}], propDecorators: { dense: [{ type: i0.Input, args: [{ isSignal: true, alias: "dense", required: false }] }], disableGutters: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableGutters", required: false }] }], divider: [{ type: i0.Input, args: [{ isSignal: true, alias: "divider", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
|
|
2965
|
+
|
|
2966
|
+
/**
|
|
2967
|
+
* Connects any host element to a `MenuComponent` instance, enabling
|
|
2968
|
+
* click-to-toggle behavior without manual open-state management.
|
|
2969
|
+
*
|
|
2970
|
+
* Sets `anchorEl` on the linked `MenuComponent` to the host element
|
|
2971
|
+
* before toggling visibility, so the panel is correctly positioned
|
|
2972
|
+
* relative to the trigger. Also applies `aria-haspopup="menu"` to the
|
|
2973
|
+
* host for accessibility.
|
|
2974
|
+
*
|
|
2975
|
+
* @example
|
|
2976
|
+
* ```html
|
|
2977
|
+
* <button type="button" [lsMenuTriggerFor]="myMenu">Options</button>
|
|
2978
|
+
* <ls-menu #myMenu>
|
|
2979
|
+
* <ls-menu-item>Delete</ls-menu-item>
|
|
2980
|
+
* </ls-menu>
|
|
2981
|
+
* ```
|
|
2982
|
+
*/
|
|
2983
|
+
class MenuTriggerDirective {
|
|
2984
|
+
constructor() {
|
|
2985
|
+
/**
|
|
2986
|
+
* The `MenuComponent` instance this directive controls.
|
|
2987
|
+
* Assign a template reference variable of `ls-menu`.
|
|
2988
|
+
*/
|
|
2989
|
+
this.lsMenuTriggerFor = input.required(...(ngDevMode ? [{ debugName: "lsMenuTriggerFor" }] : []));
|
|
2990
|
+
this._elementRef = inject((ElementRef));
|
|
2991
|
+
}
|
|
2992
|
+
onClick() {
|
|
2993
|
+
const menu = this.lsMenuTriggerFor();
|
|
2994
|
+
menu.setAnchorEl(this._resolveAnchorElement());
|
|
2995
|
+
menu.toggle();
|
|
2996
|
+
}
|
|
2997
|
+
/**
|
|
2998
|
+
* Resolves the first ancestor element that has a real layout box.
|
|
2999
|
+
*
|
|
3000
|
+
* Angular component hosts commonly use `:host { display: contents }`,
|
|
3001
|
+
* which means the element itself has no bounding box and
|
|
3002
|
+
* `getBoundingClientRect()` returns all zeros. This method walks down
|
|
3003
|
+
* through `display: contents` wrappers until it reaches the first child
|
|
3004
|
+
* that participates in layout, so the menu panel is positioned relative
|
|
3005
|
+
* to the visible trigger element rather than a phantom box.
|
|
3006
|
+
*/
|
|
3007
|
+
_resolveAnchorElement() {
|
|
3008
|
+
let el = this._elementRef.nativeElement;
|
|
3009
|
+
while (el.firstElementChild && getComputedStyle(el).display === 'contents') {
|
|
3010
|
+
el = el.firstElementChild;
|
|
3011
|
+
}
|
|
3012
|
+
return el;
|
|
3013
|
+
}
|
|
3014
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
3015
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.2", type: MenuTriggerDirective, isStandalone: true, selector: "[lsMenuTriggerFor]", inputs: { lsMenuTriggerFor: { classPropertyName: "lsMenuTriggerFor", publicName: "lsMenuTriggerFor", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "aria-haspopup": "menu" }, listeners: { "click": "onClick()" } }, ngImport: i0 }); }
|
|
3016
|
+
}
|
|
3017
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MenuTriggerDirective, decorators: [{
|
|
3018
|
+
type: Directive,
|
|
3019
|
+
args: [{
|
|
3020
|
+
host: { 'aria-haspopup': 'menu' },
|
|
3021
|
+
selector: '[lsMenuTriggerFor]',
|
|
3022
|
+
standalone: true,
|
|
3023
|
+
}]
|
|
3024
|
+
}], propDecorators: { lsMenuTriggerFor: [{ type: i0.Input, args: [{ isSignal: true, alias: "lsMenuTriggerFor", required: true }] }], onClick: [{
|
|
3025
|
+
type: HostListener,
|
|
3026
|
+
args: ['click']
|
|
3027
|
+
}] } });
|
|
3028
|
+
|
|
2527
3029
|
class ModalActionsComponent {
|
|
2528
3030
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ModalActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2529
3031
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ModalActionsComponent, isStandalone: true, selector: "ls-modal-actions", host: { classAttribute: "modal-actions" }, ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
@@ -2980,20 +3482,135 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
2980
3482
|
`, styles: [":host{display:contents}.popover-panel{position:fixed;top:var(--popover-top, 0);left:var(--popover-left, 0);z-index:1050;background:var(--ls-color-white, #fff);border:1px solid var(--ls-color-border, #e0e6ed);border-radius:8px;box-shadow:0 4px 16px #0000001f;padding:12px 16px;animation-duration:.15s;animation-fill-mode:both;animation-timing-function:ease-out}.popover-enter{animation-name:popoverFadeIn}.popover-exit{animation-name:popoverFadeOut}@keyframes popoverFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes popoverFadeOut{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(4px)}}.popover-arrow{position:absolute;width:10px;height:10px;background:inherit;border:inherit;transform:rotate(45deg);z-index:-1}.popover-arrow-top{bottom:-6px;left:50%;margin-left:-5px;border-top:0;border-left:0}.popover-arrow-bottom{top:-6px;left:50%;margin-left:-5px;border-bottom:0;border-right:0}.popover-arrow-left{right:-6px;top:50%;margin-top:-5px;border-bottom:0;border-left:0}.popover-arrow-right{left:-6px;top:50%;margin-top:-5px;border-top:0;border-right:0}:host-context(body.dark) .popover-panel{background:#1b2e4b!important;border-color:#253b5c!important;color:#e0e6ed!important;box-shadow:0 4px 16px #00000080!important}:host-context(.dark) .popover-panel{background:#1b2e4b!important;border-color:#253b5c!important;color:#e0e6ed!important}\n"] }]
|
|
2981
3483
|
}], ctorParameters: () => [], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], showArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "showArrow", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], autoFlip: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFlip", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }, { type: i0.Output, args: ["isOpenChange"] }], onOpened: [{ type: i0.Output, args: ["onOpened"] }], onHidden: [{ type: i0.Output, args: ["onHidden"] }], _panelRef: [{ type: i0.ViewChild, args: ['panelRef', { isSignal: true }] }] } });
|
|
2982
3484
|
|
|
3485
|
+
/**
|
|
3486
|
+
* Renders an accessible pagination bar for navigating a paged data set.
|
|
3487
|
+
*
|
|
3488
|
+
* Supports both **controlled** and **uncontrolled** modes:
|
|
3489
|
+
* - **Controlled**: provide the `page` input and update it in response to
|
|
3490
|
+
* the `pageChange` output. The component reflects the external value.
|
|
3491
|
+
* - **Uncontrolled**: omit `page`. The component manages its own active
|
|
3492
|
+
* page via an internal signal, initialized from `defaultPage`.
|
|
3493
|
+
*
|
|
3494
|
+
* When the total page count exceeds 5, a 5-item sliding window is rendered
|
|
3495
|
+
* centered on the active page. Navigation buttons are rendered inside a
|
|
3496
|
+
* `<nav aria-label="pagination">` landmark. Each button receives
|
|
3497
|
+
* `aria-current="page"` (active) or `aria-disabled="true"` (boundary/disabled)
|
|
3498
|
+
* as appropriate.
|
|
3499
|
+
*
|
|
3500
|
+
* @example
|
|
3501
|
+
* ```html
|
|
3502
|
+
* <!-- Uncontrolled -->
|
|
3503
|
+
* <ls-pagination [count]="20" (pageChange)="onPage($event)" />
|
|
3504
|
+
*
|
|
3505
|
+
* <!-- Controlled -->
|
|
3506
|
+
* <ls-pagination
|
|
3507
|
+
* [count]="20"
|
|
3508
|
+
* [page]="currentPage"
|
|
3509
|
+
* (pageChange)="currentPage = $event" />
|
|
3510
|
+
* ```
|
|
3511
|
+
*/
|
|
2983
3512
|
class PaginationComponent {
|
|
2984
3513
|
constructor() {
|
|
3514
|
+
/**
|
|
3515
|
+
* Total number of pages in the data set.
|
|
3516
|
+
*
|
|
3517
|
+
* Must be a positive integer ≥ 1. Determines both the upper boundary for
|
|
3518
|
+
* navigation and the page window calculation.
|
|
3519
|
+
*
|
|
3520
|
+
* @default 1
|
|
3521
|
+
*/
|
|
2985
3522
|
this.count = input(1, ...(ngDevMode ? [{ debugName: "count" }] : []));
|
|
3523
|
+
/**
|
|
3524
|
+
* Active page index in controlled mode (1-based).
|
|
3525
|
+
*
|
|
3526
|
+
* When provided, the component reflects this value and does not maintain
|
|
3527
|
+
* internal page state. The host is responsible for updating this input in
|
|
3528
|
+
* response to `pageChange` emissions. Pass `undefined` to switch to
|
|
3529
|
+
* uncontrolled mode.
|
|
3530
|
+
*
|
|
3531
|
+
* @default undefined
|
|
3532
|
+
*/
|
|
2986
3533
|
this.page = input(undefined, ...(ngDevMode ? [{ debugName: "page" }] : []));
|
|
3534
|
+
/**
|
|
3535
|
+
* Initial active page used in uncontrolled mode (1-based).
|
|
3536
|
+
*
|
|
3537
|
+
* Consumed once on `ngOnInit`. Has no effect when `page` is provided.
|
|
3538
|
+
*
|
|
3539
|
+
* @default 1
|
|
3540
|
+
*/
|
|
2987
3541
|
this.defaultPage = input(1, ...(ngDevMode ? [{ debugName: "defaultPage" }] : []));
|
|
3542
|
+
/**
|
|
3543
|
+
* Color token applied to the active page item and button hover states.
|
|
3544
|
+
*
|
|
3545
|
+
* @default 'primary'
|
|
3546
|
+
*/
|
|
2988
3547
|
this.color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
3548
|
+
/**
|
|
3549
|
+
* Visual rendering style of page number items and navigation buttons.
|
|
3550
|
+
*
|
|
3551
|
+
* @default 'outlined'
|
|
3552
|
+
*/
|
|
2989
3553
|
this.variant = input('outlined', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
3554
|
+
/**
|
|
3555
|
+
* Border-radius style applied uniformly to all buttons in the bar.
|
|
3556
|
+
*
|
|
3557
|
+
* @default 'rounded'
|
|
3558
|
+
*/
|
|
2990
3559
|
this.shape = input('rounded', ...(ngDevMode ? [{ debugName: "shape" }] : []));
|
|
3560
|
+
/**
|
|
3561
|
+
* Physical dimensions (height, font size, padding) of all buttons.
|
|
3562
|
+
*
|
|
3563
|
+
* @default 'medium'
|
|
3564
|
+
*/
|
|
2991
3565
|
this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
3566
|
+
/**
|
|
3567
|
+
* Disables all buttons in the pagination bar.
|
|
3568
|
+
*
|
|
3569
|
+
* When `true`, every button receives `disabled` and
|
|
3570
|
+
* `aria-disabled="true"`. The `pageChange` output will not emit.
|
|
3571
|
+
*
|
|
3572
|
+
* @default false
|
|
3573
|
+
*/
|
|
2992
3574
|
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
3575
|
+
/**
|
|
3576
|
+
* Renders a "go to first page" button before the previous-page button.
|
|
3577
|
+
*
|
|
3578
|
+
* The button is automatically disabled and receives `aria-disabled="true"`
|
|
3579
|
+
* when the active page is already the first page.
|
|
3580
|
+
*
|
|
3581
|
+
* @default false
|
|
3582
|
+
*/
|
|
2993
3583
|
this.showFirstButton = input(false, ...(ngDevMode ? [{ debugName: "showFirstButton" }] : []));
|
|
3584
|
+
/**
|
|
3585
|
+
* Renders a "go to last page" button after the next-page button.
|
|
3586
|
+
*
|
|
3587
|
+
* The button is automatically disabled and receives `aria-disabled="true"`
|
|
3588
|
+
* when the active page is already the last page.
|
|
3589
|
+
*
|
|
3590
|
+
* @default false
|
|
3591
|
+
*/
|
|
2994
3592
|
this.showLastButton = input(false, ...(ngDevMode ? [{ debugName: "showLastButton" }] : []));
|
|
3593
|
+
/**
|
|
3594
|
+
* Hides the previous-page navigation button.
|
|
3595
|
+
*
|
|
3596
|
+
* @default false
|
|
3597
|
+
*/
|
|
2995
3598
|
this.hidePrevButton = input(false, ...(ngDevMode ? [{ debugName: "hidePrevButton" }] : []));
|
|
3599
|
+
/**
|
|
3600
|
+
* Hides the next-page navigation button.
|
|
3601
|
+
*
|
|
3602
|
+
* @default false
|
|
3603
|
+
*/
|
|
2996
3604
|
this.hideNextButton = input(false, ...(ngDevMode ? [{ debugName: "hideNextButton" }] : []));
|
|
3605
|
+
/**
|
|
3606
|
+
* Emits the target page number (1-based) when the user activates any
|
|
3607
|
+
* page item or navigation button.
|
|
3608
|
+
*
|
|
3609
|
+
* Does NOT emit when `disabled` is `true` or when the user clicks a
|
|
3610
|
+
* boundary button that is already at its limit (first/last page).
|
|
3611
|
+
* In controlled mode, the host must update the `page` input in response
|
|
3612
|
+
* to this event to reflect the navigation in the UI.
|
|
3613
|
+
*/
|
|
2997
3614
|
this.pageChange = output();
|
|
2998
3615
|
this._internalPage = signal(1, ...(ngDevMode ? [{ debugName: "_internalPage" }] : []));
|
|
2999
3616
|
this.activePage = computed(() => this.page() ?? this._internalPage(), ...(ngDevMode ? [{ debugName: "activePage" }] : []));
|
|
@@ -3209,11 +3826,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
3209
3826
|
`, styles: [":host{display:contents}.pg-icon-left{transform:rotate(90deg)}.pg-icon-right{transform:rotate(-90deg)}.pg-list{display:inline-flex;align-items:center;gap:.25rem;list-style:none;margin:0;padding:0}.pg-item{display:inline-flex;align-items:center;justify-content:center;font-weight:600;cursor:pointer;transition:all var(--ls-transition-duration) ease;border:2px solid transparent;background:none;outline:none;font-family:var(--ls-font-family);line-height:1;-webkit-user-select:none;user-select:none}.pg-item-sm{padding:.375rem .625rem;font-size:.75rem;min-width:1.75rem;height:1.75rem}.pg-item-md{padding:.5rem .875rem;font-size:.875rem;min-width:2.25rem;height:2.25rem}.pg-item-lg{padding:.625rem 1.25rem;font-size:1rem;min-width:2.75rem;height:2.75rem}.pg-item-rounded{border-radius:var(--ls-border-radius-md)}.pg-item-circular{border-radius:var(--ls-border-radius-full);padding-inline:0}.pg-item-circular.pg-item-sm{width:1.75rem}.pg-item-circular.pg-item-md{width:2.25rem}.pg-item-circular.pg-item-lg{width:2.75rem}.pg-item-disabled,.pg-item[disabled]{cursor:not-allowed;opacity:.6}.pg-item-solid-primary{background-color:var(--ls-color-white-light);color:var(--ls-color-dark)}.pg-item-solid-primary:not([disabled]):hover{background-color:var(--ls-color-primary);color:var(--ls-color-white)}.pg-item-solid-primary.pg-item-active{background-color:var(--ls-color-primary);color:var(--ls-color-white)}.pg-item-solid-secondary{background-color:var(--ls-color-white-light);color:var(--ls-color-dark)}.pg-item-solid-secondary:not([disabled]):hover{background-color:var(--ls-color-secondary);color:var(--ls-color-white)}.pg-item-solid-secondary.pg-item-active{background-color:var(--ls-color-secondary);color:var(--ls-color-white)}.pg-item-solid-default{background-color:var(--ls-color-white-light);color:var(--ls-color-dark)}.pg-item-solid-default:not([disabled]):hover{background-color:var(--ls-color-dark);color:var(--ls-color-white)}.pg-item-solid-default.pg-item-active{background-color:var(--ls-color-dark);color:var(--ls-color-white)}.pg-item-outlined-primary{background-color:transparent;border-color:var(--ls-color-white-light);color:var(--ls-color-dark)}.pg-item-outlined-primary:not([disabled]):hover{border-color:var(--ls-color-primary);color:var(--ls-color-primary)}.pg-item-outlined-primary.pg-item-active{border-color:var(--ls-color-primary);color:var(--ls-color-primary)}.pg-item-outlined-secondary{background-color:transparent;border-color:var(--ls-color-white-light);color:var(--ls-color-dark)}.pg-item-outlined-secondary:not([disabled]):hover{border-color:var(--ls-color-secondary);color:var(--ls-color-secondary)}.pg-item-outlined-secondary.pg-item-active{border-color:var(--ls-color-secondary);color:var(--ls-color-secondary)}.pg-item-outlined-default{background-color:transparent;border-color:var(--ls-color-white-light);color:var(--ls-color-dark)}.pg-item-outlined-default:not([disabled]):hover{border-color:var(--ls-color-dark);color:var(--ls-color-dark)}.pg-item-outlined-default.pg-item-active{border-color:var(--ls-color-dark);color:var(--ls-color-dark)}.pg-item-text-primary{background-color:transparent;border-color:transparent;color:var(--ls-color-white-dark)}.pg-item-text-primary:not([disabled]):hover{background-color:#4361ee1a;color:var(--ls-color-primary)}.pg-item-text-primary.pg-item-active{color:var(--ls-color-primary)}.pg-item-text-secondary{background-color:transparent;border-color:transparent;color:var(--ls-color-white-dark)}.pg-item-text-secondary:not([disabled]):hover{background-color:#805dca1a;color:var(--ls-color-secondary)}.pg-item-text-secondary.pg-item-active{color:var(--ls-color-secondary)}.pg-item-text-default{background-color:transparent;border-color:transparent;color:var(--ls-color-white-dark)}.pg-item-text-default:not([disabled]):hover{background-color:#3b3f5c1a;color:var(--ls-color-dark)}.pg-item-text-default.pg-item-active{color:var(--ls-color-dark)}body.dark .pg-item-solid-primary,body.dark .pg-item-solid-secondary,body.dark .pg-item-solid-default{background-color:#191e3a;color:var(--ls-color-white-light)}body.dark .pg-item-solid-primary:not([disabled]):hover,body.dark .pg-item-solid-primary.pg-item-active{background-color:var(--ls-color-primary);color:var(--ls-color-white-light)}body.dark .pg-item-solid-secondary:not([disabled]):hover,body.dark .pg-item-solid-secondary.pg-item-active{background-color:var(--ls-color-secondary);color:var(--ls-color-white-light)}body.dark .pg-item-solid-default:not([disabled]):hover,body.dark .pg-item-solid-default.pg-item-active{background-color:var(--ls-color-dark);color:var(--ls-color-white-light)}body.dark .pg-item-outlined-primary,body.dark .pg-item-outlined-secondary,body.dark .pg-item-outlined-default{border-color:#191e3a;color:var(--ls-color-white-light)}body.dark .pg-item-outlined-primary:not([disabled]):hover,body.dark .pg-item-outlined-primary.pg-item-active{border-color:var(--ls-color-primary);color:var(--ls-color-white-light)}body.dark .pg-item-outlined-secondary:not([disabled]):hover,body.dark .pg-item-outlined-secondary.pg-item-active{border-color:var(--ls-color-secondary);color:var(--ls-color-white-light)}body.dark .pg-item-outlined-default:not([disabled]):hover,body.dark .pg-item-outlined-default.pg-item-active{border-color:var(--ls-color-dark);color:var(--ls-color-white-light)}body.dark .pg-item-text-primary,body.dark .pg-item-text-secondary,body.dark .pg-item-text-default{color:var(--ls-color-white-dark)}body.dark .pg-item-text-primary:not([disabled]):hover,body.dark .pg-item-text-primary.pg-item-active{color:var(--ls-color-primary)}body.dark .pg-item-text-secondary:not([disabled]):hover,body.dark .pg-item-text-secondary.pg-item-active{color:var(--ls-color-secondary)}body.dark .pg-item-text-default:not([disabled]):hover,body.dark .pg-item-text-default.pg-item-active{color:var(--ls-color-white-light)}\n"] }]
|
|
3210
3827
|
}], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }], defaultPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultPage", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showFirstButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFirstButton", required: false }] }], showLastButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLastButton", required: false }] }], hidePrevButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePrevButton", required: false }] }], hideNextButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideNextButton", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }] } });
|
|
3211
3828
|
|
|
3829
|
+
class BreadcrumbComponent {
|
|
3830
|
+
constructor() {
|
|
3831
|
+
this.items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
3832
|
+
this.variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
3833
|
+
this.separator = input('/', ...(ngDevMode ? [{ debugName: "separator" }] : []));
|
|
3834
|
+
this.color = input('gray', ...(ngDevMode ? [{ debugName: "color" }] : [])); // El nuevo input de color
|
|
3835
|
+
// Lógica para el color dinámico
|
|
3836
|
+
this._colorStyle = computed(() => {
|
|
3837
|
+
const c = this.color();
|
|
3838
|
+
const value = c === 'primary' ? 'var(--ls-color-primary)' :
|
|
3839
|
+
c === 'secondary' ? 'var(--ls-color-secondary)' : c;
|
|
3840
|
+
return { '--ls-breadcrumb-main-color': value };
|
|
3841
|
+
}, ...(ngDevMode ? [{ debugName: "_colorStyle" }] : []));
|
|
3842
|
+
this._classes = computed(() => {
|
|
3843
|
+
return `ls-breadcrumb ls-breadcrumb--${this.variant()}`;
|
|
3844
|
+
}, ...(ngDevMode ? [{ debugName: "_classes" }] : []));
|
|
3845
|
+
this._isTemplateSeparator = computed(() => {
|
|
3846
|
+
return this.separator() instanceof TemplateRef;
|
|
3847
|
+
}, ...(ngDevMode ? [{ debugName: "_isTemplateSeparator" }] : []));
|
|
3848
|
+
}
|
|
3849
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3850
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: BreadcrumbComponent, isStandalone: true, selector: "ls-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
3851
|
+
<nav aria-label="Breadcrumb" [style]="_colorStyle()">
|
|
3852
|
+
<ol [class]="_classes()">
|
|
3853
|
+
@for (item of items(); track item.label; let isLast = $last) {
|
|
3854
|
+
<li class="ls-breadcrumb-item" [class.ls-breadcrumb-item--active]="isLast">
|
|
3855
|
+
|
|
3856
|
+
@if (item.icon) {
|
|
3857
|
+
<ls-icon
|
|
3858
|
+
[name]="$any(item.icon)"
|
|
3859
|
+
iconClass="ls-breadcrumb-icon" />
|
|
3860
|
+
}
|
|
3861
|
+
|
|
3862
|
+
@if (isLast) {
|
|
3863
|
+
<span aria-current="page">{{ item.label }}</span>
|
|
3864
|
+
} @else if (item.url) {
|
|
3865
|
+
<a [href]="item.url">{{ item.label }}</a>
|
|
3866
|
+
} @else {
|
|
3867
|
+
<span>{{ item.label }}</span>
|
|
3868
|
+
}
|
|
3869
|
+
</li>
|
|
3870
|
+
|
|
3871
|
+
@if (!isLast && variant() !== 'arrowed') {
|
|
3872
|
+
<li class="ls-breadcrumb-separator" aria-hidden="true">
|
|
3873
|
+
@if (_isTemplateSeparator()) {
|
|
3874
|
+
<ng-container *ngTemplateOutlet="$any(separator())" />
|
|
3875
|
+
} @else {
|
|
3876
|
+
{{ separator() }}
|
|
3877
|
+
}
|
|
3878
|
+
</li>
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
</ol>
|
|
3882
|
+
</nav>
|
|
3883
|
+
`, isInline: true, styles: [":host{display:block;--ls-breadcrumb-main-color: #4361ee}.ls-breadcrumb{display:flex;align-items:center;flex-wrap:wrap;list-style:none;margin:0;padding:0;font-family:var(--ls-font-family, sans-serif);font-size:.875rem}.ls-breadcrumb-item{display:inline-flex;align-items:center;gap:.5rem;color:#6c757d}.ls-breadcrumb-item a{color:inherit;text-decoration:none!important;transition:color .2s;border:none}.ls-breadcrumb-item a:hover{text-decoration:none!important;color:var(--ls-breadcrumb-main-color)}.ls-breadcrumb-icon{width:1.15rem;height:1.15rem;display:flex;align-items:center;justify-content:center;color:currentColor}.ls-breadcrumb-icon svg{width:100%;height:100%;display:block}.ls-breadcrumb-separator{margin:0 .5rem;color:#888ea8;-webkit-user-select:none;user-select:none}.ls-breadcrumb--default .ls-breadcrumb-item--active{color:#000;font-weight:600}.ls-breadcrumb--dotted .ls-breadcrumb-separator{font-size:0;display:flex;align-items:center}.ls-breadcrumb--dotted .ls-breadcrumb-separator:before{content:\"\";width:6px;height:6px;background:var(--ls-breadcrumb-main-color);border-radius:50%;display:inline-block}.ls-breadcrumb--dotted .ls-breadcrumb-item--active{color:#000;font-weight:600}.ls-breadcrumb--arrowed{gap:0}.ls-breadcrumb--arrowed .ls-breadcrumb-item{position:relative;background:#e9ecef;padding:.5rem 1rem .5rem 1.5rem;margin-left:-10px;clip-path:polygon(calc(100% - 12px) 0%,100% 50%,calc(100% - 12px) 100%,0% 100%,12px 50%,0% 0%);filter:drop-shadow(1px 0 1px rgba(0,0,0,.08));color:#515365}.ls-breadcrumb--arrowed .ls-breadcrumb-item:first-child{margin-left:0;padding-left:.75rem;clip-path:polygon(calc(100% - 12px) 0%,100% 50%,calc(100% - 12px) 100%,0% 100%,0% 0%);border-radius:4px 0 0 4px}.ls-breadcrumb--arrowed .ls-breadcrumb-item:last-child{padding-right:1.25rem;clip-path:polygon(100% 0%,100% 100%,0% 100%,12px 50%,0% 0%);border-radius:0 4px 4px 0}.ls-breadcrumb--arrowed .ls-breadcrumb-item--active{background:var(--ls-breadcrumb-main-color)!important;color:#fff!important;z-index:10!important}.ls-breadcrumb--arrowed .ls-breadcrumb-item:nth-child(1){z-index:5}.ls-breadcrumb--arrowed .ls-breadcrumb-item:nth-child(2){z-index:4}.ls-breadcrumb--arrowed .ls-breadcrumb-item:nth-child(3){z-index:3}body.dark .ls-breadcrumb-item{color:#bfc9d4}body.dark .ls-breadcrumb--default .ls-breadcrumb-item--active,body.dark .ls-breadcrumb--dotted .ls-breadcrumb-item--active{color:#fff!important}body.dark .ls-breadcrumb--arrowed .ls-breadcrumb-item:not(.ls-breadcrumb-item--active){background:#1b2e4b!important;color:#e0e6ed!important}body.dark .ls-breadcrumb-separator{color:#3b3f5c}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "ls-icon", inputs: ["name", "iconClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3884
|
+
}
|
|
3885
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BreadcrumbComponent, decorators: [{
|
|
3886
|
+
type: Component,
|
|
3887
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, IconComponent], selector: 'ls-breadcrumb', standalone: true, template: `
|
|
3888
|
+
<nav aria-label="Breadcrumb" [style]="_colorStyle()">
|
|
3889
|
+
<ol [class]="_classes()">
|
|
3890
|
+
@for (item of items(); track item.label; let isLast = $last) {
|
|
3891
|
+
<li class="ls-breadcrumb-item" [class.ls-breadcrumb-item--active]="isLast">
|
|
3892
|
+
|
|
3893
|
+
@if (item.icon) {
|
|
3894
|
+
<ls-icon
|
|
3895
|
+
[name]="$any(item.icon)"
|
|
3896
|
+
iconClass="ls-breadcrumb-icon" />
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
@if (isLast) {
|
|
3900
|
+
<span aria-current="page">{{ item.label }}</span>
|
|
3901
|
+
} @else if (item.url) {
|
|
3902
|
+
<a [href]="item.url">{{ item.label }}</a>
|
|
3903
|
+
} @else {
|
|
3904
|
+
<span>{{ item.label }}</span>
|
|
3905
|
+
}
|
|
3906
|
+
</li>
|
|
3907
|
+
|
|
3908
|
+
@if (!isLast && variant() !== 'arrowed') {
|
|
3909
|
+
<li class="ls-breadcrumb-separator" aria-hidden="true">
|
|
3910
|
+
@if (_isTemplateSeparator()) {
|
|
3911
|
+
<ng-container *ngTemplateOutlet="$any(separator())" />
|
|
3912
|
+
} @else {
|
|
3913
|
+
{{ separator() }}
|
|
3914
|
+
}
|
|
3915
|
+
</li>
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3918
|
+
</ol>
|
|
3919
|
+
</nav>
|
|
3920
|
+
`, styles: [":host{display:block;--ls-breadcrumb-main-color: #4361ee}.ls-breadcrumb{display:flex;align-items:center;flex-wrap:wrap;list-style:none;margin:0;padding:0;font-family:var(--ls-font-family, sans-serif);font-size:.875rem}.ls-breadcrumb-item{display:inline-flex;align-items:center;gap:.5rem;color:#6c757d}.ls-breadcrumb-item a{color:inherit;text-decoration:none!important;transition:color .2s;border:none}.ls-breadcrumb-item a:hover{text-decoration:none!important;color:var(--ls-breadcrumb-main-color)}.ls-breadcrumb-icon{width:1.15rem;height:1.15rem;display:flex;align-items:center;justify-content:center;color:currentColor}.ls-breadcrumb-icon svg{width:100%;height:100%;display:block}.ls-breadcrumb-separator{margin:0 .5rem;color:#888ea8;-webkit-user-select:none;user-select:none}.ls-breadcrumb--default .ls-breadcrumb-item--active{color:#000;font-weight:600}.ls-breadcrumb--dotted .ls-breadcrumb-separator{font-size:0;display:flex;align-items:center}.ls-breadcrumb--dotted .ls-breadcrumb-separator:before{content:\"\";width:6px;height:6px;background:var(--ls-breadcrumb-main-color);border-radius:50%;display:inline-block}.ls-breadcrumb--dotted .ls-breadcrumb-item--active{color:#000;font-weight:600}.ls-breadcrumb--arrowed{gap:0}.ls-breadcrumb--arrowed .ls-breadcrumb-item{position:relative;background:#e9ecef;padding:.5rem 1rem .5rem 1.5rem;margin-left:-10px;clip-path:polygon(calc(100% - 12px) 0%,100% 50%,calc(100% - 12px) 100%,0% 100%,12px 50%,0% 0%);filter:drop-shadow(1px 0 1px rgba(0,0,0,.08));color:#515365}.ls-breadcrumb--arrowed .ls-breadcrumb-item:first-child{margin-left:0;padding-left:.75rem;clip-path:polygon(calc(100% - 12px) 0%,100% 50%,calc(100% - 12px) 100%,0% 100%,0% 0%);border-radius:4px 0 0 4px}.ls-breadcrumb--arrowed .ls-breadcrumb-item:last-child{padding-right:1.25rem;clip-path:polygon(100% 0%,100% 100%,0% 100%,12px 50%,0% 0%);border-radius:0 4px 4px 0}.ls-breadcrumb--arrowed .ls-breadcrumb-item--active{background:var(--ls-breadcrumb-main-color)!important;color:#fff!important;z-index:10!important}.ls-breadcrumb--arrowed .ls-breadcrumb-item:nth-child(1){z-index:5}.ls-breadcrumb--arrowed .ls-breadcrumb-item:nth-child(2){z-index:4}.ls-breadcrumb--arrowed .ls-breadcrumb-item:nth-child(3){z-index:3}body.dark .ls-breadcrumb-item{color:#bfc9d4}body.dark .ls-breadcrumb--default .ls-breadcrumb-item--active,body.dark .ls-breadcrumb--dotted .ls-breadcrumb-item--active{color:#fff!important}body.dark .ls-breadcrumb--arrowed .ls-breadcrumb-item:not(.ls-breadcrumb-item--active){background:#1b2e4b!important;color:#e0e6ed!important}body.dark .ls-breadcrumb-separator{color:#3b3f5c}\n"] }]
|
|
3921
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
|
|
3922
|
+
|
|
3212
3923
|
// @lumston/ds-angular — public API surface
|
|
3213
3924
|
|
|
3214
3925
|
/**
|
|
3215
3926
|
* Generated bundle index. Do not edit.
|
|
3216
3927
|
*/
|
|
3217
3928
|
|
|
3218
|
-
export { AlertComponent, AvatarComponent, AvatarGroupComponent, BadgeComponent, ButtonComponent, CheckboxComponent, ChipComponent, DropdownComponent, ICON_REGISTRY, IconButtonComponent, IconComponent, LinkComponent, LoaderComponent, LogoComponent, LsDropdownContentDirective, ModalActionsComponent, ModalComponent, ModalContentComponent, ModalStackService, ModalTitleComponent, PaginationComponent, PopoverComponent, ProgressBarComponent, RadioButtonComponent, SliderComponent, SwitchComponent, TagComponent, TextComponent, TooltipComponent };
|
|
3929
|
+
export { AlertComponent, AvatarComponent, AvatarGroupComponent, BadgeComponent, BreadcrumbComponent, ButtonComponent, CheckboxComponent, ChipComponent, DropdownComponent, ICON_REGISTRY, IconButtonComponent, IconComponent, LinkComponent, LoaderComponent, LogoComponent, LsDropdownContentDirective, MenuComponent, MenuItemComponent, MenuTriggerDirective, ModalActionsComponent, ModalComponent, ModalContentComponent, ModalStackService, ModalTitleComponent, PaginationComponent, PopoverComponent, ProgressBarComponent, RadioButtonComponent, SliderComponent, SwitchComponent, TagComponent, TextComponent, TooltipComponent };
|
|
3219
3930
|
//# sourceMappingURL=lumston-ds-angular.mjs.map
|