@byuhbll/components 6.0.0-rc.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/byuhbll-components.mjs +268 -3
- package/fesm2022/byuhbll-components.mjs.map +1 -1
- package/index.d.ts +130 -4
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { CommonModule, DatePipe, NgIf, NgClass } from '@angular/common';
|
|
|
3
3
|
import { toSignal, toObservable } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { HttpClient } from '@angular/common/http';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { Input, ViewChild, ChangeDetectionStrategy, Component, input, EventEmitter, Output, inject, computed, ViewChildren, Pipe, Renderer2, DOCUMENT, viewChild, HostListener, ElementRef, Injector, runInInjectionContext, effect, ViewEncapsulation, booleanAttribute, createComponent, Injectable } from '@angular/core';
|
|
6
|
+
import { Input, ViewChild, ChangeDetectionStrategy, Component, input, EventEmitter, Output, inject, computed, ViewChildren, Pipe, Renderer2, DOCUMENT, viewChild, HostListener, ElementRef, Injector, runInInjectionContext, effect, ViewEncapsulation, booleanAttribute, createComponent, Injectable, signal, ContentChildren } from '@angular/core';
|
|
7
7
|
import { trigger, transition, group, style, query, animate, animateChild } from '@angular/animations';
|
|
8
8
|
import { map, of, switchMap, shareReplay, combineLatest, Subject, Subscription } from 'rxjs';
|
|
9
9
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
@@ -1095,7 +1095,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1095
1095
|
}] } });
|
|
1096
1096
|
|
|
1097
1097
|
const defaultOidcBaseUri = 'https://keycloak.lib.byu.edu/';
|
|
1098
|
-
const defaultOidcDefaultIdp = '
|
|
1098
|
+
const defaultOidcDefaultIdp = 'ces';
|
|
1099
1099
|
class ImpersonateUserPipe {
|
|
1100
1100
|
transform(user) {
|
|
1101
1101
|
return `${user.name} (${user.netId || 'Unknown'})${user.restricted ? ' — Restricted' : ''}`;
|
|
@@ -2580,6 +2580,271 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
2580
2580
|
args: [{ providedIn: 'root' }]
|
|
2581
2581
|
}], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
|
|
2582
2582
|
|
|
2583
|
+
/**
|
|
2584
|
+
* A flexible, reusable button component that supports multiple button types
|
|
2585
|
+
* and various content combinations (icon before, title, icon after).
|
|
2586
|
+
*
|
|
2587
|
+
* @example
|
|
2588
|
+
* ```html
|
|
2589
|
+
* <!-- Primary button with icon and title -->
|
|
2590
|
+
* <lib-button
|
|
2591
|
+
* buttonType="primary"
|
|
2592
|
+
* title="Copy Citation"
|
|
2593
|
+
* iconBefore="content_copy"
|
|
2594
|
+
* (buttonClick)="copyCitation()">
|
|
2595
|
+
* </lib-button>
|
|
2596
|
+
*
|
|
2597
|
+
* <!-- Secondary button with title only -->
|
|
2598
|
+
* <lib-button
|
|
2599
|
+
* buttonType="secondary"
|
|
2600
|
+
* title="Cancel"
|
|
2601
|
+
* (buttonClick)="cancelAction()">
|
|
2602
|
+
* </lib-button>
|
|
2603
|
+
*
|
|
2604
|
+
* <!-- Transparent button with icon after title -->
|
|
2605
|
+
* <lib-button
|
|
2606
|
+
* buttonType="transparent"
|
|
2607
|
+
* title="Download"
|
|
2608
|
+
* iconAfter="download"
|
|
2609
|
+
* (buttonClick)="downloadFile()">
|
|
2610
|
+
* </lib-button>
|
|
2611
|
+
*
|
|
2612
|
+
* <!-- Thin button -->
|
|
2613
|
+
* <lib-button
|
|
2614
|
+
* buttonType="primary"
|
|
2615
|
+
* title="Submit"
|
|
2616
|
+
* [isThin]="true"
|
|
2617
|
+
* (buttonClick)="submitForm()">
|
|
2618
|
+
* </lib-button>
|
|
2619
|
+
* ```
|
|
2620
|
+
*/
|
|
2621
|
+
class ButtonComponent {
|
|
2622
|
+
constructor() {
|
|
2623
|
+
this.buttonType = 'primary';
|
|
2624
|
+
this.disabled = false;
|
|
2625
|
+
this.isThin = false;
|
|
2626
|
+
this.buttonClick = new EventEmitter();
|
|
2627
|
+
}
|
|
2628
|
+
/**
|
|
2629
|
+
* Handles button click events and emits the buttonClick event if the button is not disabled.
|
|
2630
|
+
*/
|
|
2631
|
+
onButtonClick() {
|
|
2632
|
+
if (!this.disabled) {
|
|
2633
|
+
this.buttonClick.emit();
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2637
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ButtonComponent, isStandalone: true, selector: "lib-button", inputs: { buttonType: "buttonType", title: "title", iconBefore: "iconBefore", iconAfter: "iconAfter", disabled: "disabled", isThin: "isThin", ariaLabel: "ariaLabel" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [class]=\"'btn btn-' + buttonType + (isThin ? ' btn-thin' : '') + (title ? '' : ' btn-icon-only')\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"ariaLabel ? ariaLabel : null\"\n (click)=\"onButtonClick()\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (iconBefore) {\n <span class=\"icon material-symbols-outlined\" [ngClass]=\"{ 'icon-before': title }\">{{ iconBefore }}</span>\n }\n\n @if (title) {\n <span class=\"button-title\">{{ title }}</span>\n }\n\n @if (iconAfter) {\n <span class=\"icon icon-after material-symbols-outlined\">{{ iconAfter }}</span>\n }\n</button>\n", styles: [".btn{padding:.75rem 1.5rem;border-radius:.25rem;font-size:1rem;font-weight:600;cursor:pointer;transition:all .2s ease;border:none;display:inline-flex;align-items:center;outline:none;line-height:1.5rem}.btn.btn-thin{padding:.25rem 2.25rem;border-radius:.5rem;font-weight:400}.btn.btn-thin .icon img{height:1.25rem}.btn:disabled{cursor:not-allowed;color:#767676}.btn:disabled:not(.btn-transparent){background-color:#e7e7e7;border:.0625rem solid #767676}.btn:focus-visible{outline:.125rem solid #b967c7;outline-offset:.125rem}.btn .icon{display:flex;align-items:center;justify-content:center}.btn .icon img{height:1.5rem;width:auto}.btn .icon.icon-before{margin-right:.25rem}.btn .icon.icon-after{margin-left:.25rem}.btn .button-title{flex-shrink:0}.btn-icon-only{padding:.75rem}.btn-primary{background-color:#0047ba;color:#fff;border:.0625rem solid #0047ba}.btn-primary:hover:not(:disabled){background-color:#003995}.btn-secondary{background-color:#fff;color:#00245d;border:.0625rem solid #0047ba}.btn-secondary:hover:not(:disabled){background-color:#e5edf8}.btn-transparent{background-color:transparent;color:#00245d}.btn-transparent:hover:not(:disabled){background-color:#e5edf8}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
2638
|
+
}
|
|
2639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
2640
|
+
type: Component,
|
|
2641
|
+
args: [{ selector: 'lib-button', standalone: true, imports: [CommonModule], template: "<button\n type=\"button\"\n [class]=\"'btn btn-' + buttonType + (isThin ? ' btn-thin' : '') + (title ? '' : ' btn-icon-only')\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"ariaLabel ? ariaLabel : null\"\n (click)=\"onButtonClick()\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (iconBefore) {\n <span class=\"icon material-symbols-outlined\" [ngClass]=\"{ 'icon-before': title }\">{{ iconBefore }}</span>\n }\n\n @if (title) {\n <span class=\"button-title\">{{ title }}</span>\n }\n\n @if (iconAfter) {\n <span class=\"icon icon-after material-symbols-outlined\">{{ iconAfter }}</span>\n }\n</button>\n", styles: [".btn{padding:.75rem 1.5rem;border-radius:.25rem;font-size:1rem;font-weight:600;cursor:pointer;transition:all .2s ease;border:none;display:inline-flex;align-items:center;outline:none;line-height:1.5rem}.btn.btn-thin{padding:.25rem 2.25rem;border-radius:.5rem;font-weight:400}.btn.btn-thin .icon img{height:1.25rem}.btn:disabled{cursor:not-allowed;color:#767676}.btn:disabled:not(.btn-transparent){background-color:#e7e7e7;border:.0625rem solid #767676}.btn:focus-visible{outline:.125rem solid #b967c7;outline-offset:.125rem}.btn .icon{display:flex;align-items:center;justify-content:center}.btn .icon img{height:1.5rem;width:auto}.btn .icon.icon-before{margin-right:.25rem}.btn .icon.icon-after{margin-left:.25rem}.btn .button-title{flex-shrink:0}.btn-icon-only{padding:.75rem}.btn-primary{background-color:#0047ba;color:#fff;border:.0625rem solid #0047ba}.btn-primary:hover:not(:disabled){background-color:#003995}.btn-secondary{background-color:#fff;color:#00245d;border:.0625rem solid #0047ba}.btn-secondary:hover:not(:disabled){background-color:#e5edf8}.btn-transparent{background-color:transparent;color:#00245d}.btn-transparent:hover:not(:disabled){background-color:#e5edf8}\n"] }]
|
|
2642
|
+
}], propDecorators: { buttonType: [{
|
|
2643
|
+
type: Input
|
|
2644
|
+
}], title: [{
|
|
2645
|
+
type: Input
|
|
2646
|
+
}], iconBefore: [{
|
|
2647
|
+
type: Input
|
|
2648
|
+
}], iconAfter: [{
|
|
2649
|
+
type: Input
|
|
2650
|
+
}], disabled: [{
|
|
2651
|
+
type: Input
|
|
2652
|
+
}], isThin: [{
|
|
2653
|
+
type: Input
|
|
2654
|
+
}], ariaLabel: [{
|
|
2655
|
+
type: Input
|
|
2656
|
+
}], buttonClick: [{
|
|
2657
|
+
type: Output
|
|
2658
|
+
}] } });
|
|
2659
|
+
|
|
2660
|
+
class ButtonGroupItemComponent {
|
|
2661
|
+
constructor() {
|
|
2662
|
+
this.disabled = false;
|
|
2663
|
+
this.buttonClick = new EventEmitter();
|
|
2664
|
+
// Set by parent button group after content projection
|
|
2665
|
+
this.isActive = false;
|
|
2666
|
+
}
|
|
2667
|
+
/**
|
|
2668
|
+
* Handles the button click event and emits the button's ID to the parent component.
|
|
2669
|
+
*/
|
|
2670
|
+
onClick() {
|
|
2671
|
+
this.buttonClick.emit(this.id);
|
|
2672
|
+
}
|
|
2673
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonGroupItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2674
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ButtonGroupItemComponent, isStandalone: true, selector: "lib-button-group-item", inputs: { id: "id", title: "title", icon: "icon", ariaLabel: "ariaLabel", disabled: "disabled", position: "position" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"tab-btn\"\n [class.first]=\"position === 'first'\"\n [class.last]=\"position === 'last'\"\n [class.active]=\"isActive\"\n [disabled]=\"disabled\"\n (click)=\"onClick()\"\n role=\"tab\"\n [attr.aria-pressed]=\"isActive\"\n [attr.aria-label]=\"ariaLabel ? ariaLabel : null\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (icon) {\n <span class=\"icon material-symbols-outlined\">{{ icon }}</span>\n }\n\n @if (title) {\n <span class=\"button-title\">{{ title }}</span>\n }\n</button>\n", styles: [".tab-btn{padding:.5rem 1rem;font-size:1rem;font-weight:400;line-height:1.5rem;color:#00245d;background-color:#fff;cursor:pointer;position:relative;border:.0625rem solid #d0d0d0;border-left:none;border-radius:0;transition:all .2s ease;display:inline-flex;align-items:center;justify-content:center;height:2.5rem}.tab-btn:not(:disabled):hover{background-color:#e5edf8}.tab-btn.active{background-color:#0047ba;color:#fff;z-index:2}.tab-btn.active:not(:disabled):hover{background-color:#003995}.tab-btn:focus-visible{outline:.125rem solid #b967c7;outline-offset:.125rem;z-index:3}.tab-btn:disabled{cursor:not-allowed;color:#767676;background-color:#e7e7e7;border-color:#767676}.tab-btn .icon{display:flex;align-items:center;justify-content:center}.tab-btn .icon img{height:1.5rem;width:auto}.tab-btn .button-title{flex-shrink:0}.tab-btn.first{border-radius:.25rem 0 0 .25rem;border-left:.0625rem solid #d0d0d0}.tab-btn.first:disabled{border-left:.0625rem solid #767676}.tab-btn.last{border-radius:0 .25rem .25rem 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
2675
|
+
}
|
|
2676
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonGroupItemComponent, decorators: [{
|
|
2677
|
+
type: Component,
|
|
2678
|
+
args: [{ selector: 'lib-button-group-item', standalone: true, imports: [CommonModule], template: "<button\n type=\"button\"\n class=\"tab-btn\"\n [class.first]=\"position === 'first'\"\n [class.last]=\"position === 'last'\"\n [class.active]=\"isActive\"\n [disabled]=\"disabled\"\n (click)=\"onClick()\"\n role=\"tab\"\n [attr.aria-pressed]=\"isActive\"\n [attr.aria-label]=\"ariaLabel ? ariaLabel : null\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (icon) {\n <span class=\"icon material-symbols-outlined\">{{ icon }}</span>\n }\n\n @if (title) {\n <span class=\"button-title\">{{ title }}</span>\n }\n</button>\n", styles: [".tab-btn{padding:.5rem 1rem;font-size:1rem;font-weight:400;line-height:1.5rem;color:#00245d;background-color:#fff;cursor:pointer;position:relative;border:.0625rem solid #d0d0d0;border-left:none;border-radius:0;transition:all .2s ease;display:inline-flex;align-items:center;justify-content:center;height:2.5rem}.tab-btn:not(:disabled):hover{background-color:#e5edf8}.tab-btn.active{background-color:#0047ba;color:#fff;z-index:2}.tab-btn.active:not(:disabled):hover{background-color:#003995}.tab-btn:focus-visible{outline:.125rem solid #b967c7;outline-offset:.125rem;z-index:3}.tab-btn:disabled{cursor:not-allowed;color:#767676;background-color:#e7e7e7;border-color:#767676}.tab-btn .icon{display:flex;align-items:center;justify-content:center}.tab-btn .icon img{height:1.5rem;width:auto}.tab-btn .button-title{flex-shrink:0}.tab-btn.first{border-radius:.25rem 0 0 .25rem;border-left:.0625rem solid #d0d0d0}.tab-btn.first:disabled{border-left:.0625rem solid #767676}.tab-btn.last{border-radius:0 .25rem .25rem 0}\n"] }]
|
|
2679
|
+
}], propDecorators: { id: [{
|
|
2680
|
+
type: Input,
|
|
2681
|
+
args: [{ required: true }]
|
|
2682
|
+
}], title: [{
|
|
2683
|
+
type: Input
|
|
2684
|
+
}], icon: [{
|
|
2685
|
+
type: Input
|
|
2686
|
+
}], ariaLabel: [{
|
|
2687
|
+
type: Input
|
|
2688
|
+
}], disabled: [{
|
|
2689
|
+
type: Input
|
|
2690
|
+
}], position: [{
|
|
2691
|
+
type: Input
|
|
2692
|
+
}], buttonClick: [{
|
|
2693
|
+
type: Output
|
|
2694
|
+
}] } });
|
|
2695
|
+
|
|
2696
|
+
class ButtonGroupComponent {
|
|
2697
|
+
constructor() {
|
|
2698
|
+
this.activeButtonChange = new EventEmitter();
|
|
2699
|
+
this.elementRef = inject(ElementRef);
|
|
2700
|
+
this.activeButtonId = signal('', ...(ngDevMode ? [{ debugName: "activeButtonId" }] : []));
|
|
2701
|
+
this.subscriptions = [];
|
|
2702
|
+
}
|
|
2703
|
+
/**
|
|
2704
|
+
* Angular lifecycle hook called after content projection is initialized.
|
|
2705
|
+
* Sets up the initial active button and subscribes to button click events from all button items.
|
|
2706
|
+
*/
|
|
2707
|
+
ngAfterContentInit() {
|
|
2708
|
+
// Handle both Angular components (via ContentChildren) and custom elements (via DOM)
|
|
2709
|
+
if (this.buttonItems.length > 0) {
|
|
2710
|
+
// Angular component usage
|
|
2711
|
+
this.initializeActiveButton();
|
|
2712
|
+
this.buttonItems.forEach((item) => {
|
|
2713
|
+
const sub = item.buttonClick.subscribe((id) => this.onButtonClick(id));
|
|
2714
|
+
this.subscriptions.push(sub);
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
else {
|
|
2718
|
+
// Custom element usage - delay slightly to ensure custom elements are fully initialized
|
|
2719
|
+
setTimeout(() => {
|
|
2720
|
+
this.initializeCustomElements();
|
|
2721
|
+
}, 0);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
/**
|
|
2725
|
+
* Initializes custom element children when used as web components.
|
|
2726
|
+
*/
|
|
2727
|
+
initializeCustomElements() {
|
|
2728
|
+
const hostElement = this.elementRef.nativeElement;
|
|
2729
|
+
const customElementChildren = Array.from(hostElement.querySelectorAll('hbll-button-group-item, lib-button-group-item'));
|
|
2730
|
+
if (customElementChildren.length > 0) {
|
|
2731
|
+
// Set position attributes - first and last explicitly, rest are middle
|
|
2732
|
+
customElementChildren[0].setAttribute('position', 'first');
|
|
2733
|
+
if (customElementChildren.length > 1) {
|
|
2734
|
+
customElementChildren[customElementChildren.length - 1].setAttribute('position', 'last');
|
|
2735
|
+
}
|
|
2736
|
+
for (let i = 1; i < customElementChildren.length - 1; i++) {
|
|
2737
|
+
customElementChildren[i].setAttribute('position', 'middle');
|
|
2738
|
+
}
|
|
2739
|
+
const initialId = this.initialActiveId;
|
|
2740
|
+
if (initialId) {
|
|
2741
|
+
this.activeButtonId.set(initialId);
|
|
2742
|
+
customElementChildren.forEach((item) => {
|
|
2743
|
+
const itemId = item.getAttribute('id');
|
|
2744
|
+
if (itemId === initialId) {
|
|
2745
|
+
this.setActiveState(item, true);
|
|
2746
|
+
}
|
|
2747
|
+
else {
|
|
2748
|
+
this.setActiveState(item, false);
|
|
2749
|
+
}
|
|
2750
|
+
});
|
|
2751
|
+
}
|
|
2752
|
+
// Listen to clicks on custom elements
|
|
2753
|
+
customElementChildren.forEach((item) => {
|
|
2754
|
+
item.addEventListener('click', () => {
|
|
2755
|
+
const itemId = item.getAttribute('id');
|
|
2756
|
+
if (itemId && !item.hasAttribute('disabled')) {
|
|
2757
|
+
this.handleCustomElementClick(itemId, customElementChildren);
|
|
2758
|
+
}
|
|
2759
|
+
});
|
|
2760
|
+
});
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
/**
|
|
2764
|
+
* Sets the active state on a custom element by toggling the active class on its button.
|
|
2765
|
+
*/
|
|
2766
|
+
setActiveState(element, isActive) {
|
|
2767
|
+
const button = element.querySelector('.tab-btn');
|
|
2768
|
+
if (button) {
|
|
2769
|
+
if (isActive) {
|
|
2770
|
+
button.classList.add('active');
|
|
2771
|
+
}
|
|
2772
|
+
else {
|
|
2773
|
+
button.classList.remove('active');
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
/**
|
|
2778
|
+
* Handles click events for custom element children.
|
|
2779
|
+
*/
|
|
2780
|
+
handleCustomElementClick(buttonId, children) {
|
|
2781
|
+
this.activeButtonId.set(buttonId);
|
|
2782
|
+
this.activeButtonChange.emit(buttonId);
|
|
2783
|
+
children.forEach((item) => {
|
|
2784
|
+
const itemId = item.getAttribute('id');
|
|
2785
|
+
const isActive = itemId === buttonId;
|
|
2786
|
+
this.setActiveState(item, isActive);
|
|
2787
|
+
});
|
|
2788
|
+
}
|
|
2789
|
+
/**
|
|
2790
|
+
* Angular lifecycle hook called when the component is destroyed.
|
|
2791
|
+
* Cleans up all subscriptions to prevent memory leaks.
|
|
2792
|
+
*/
|
|
2793
|
+
ngOnDestroy() {
|
|
2794
|
+
this.subscriptions.forEach((sub) => sub.unsubscribe());
|
|
2795
|
+
}
|
|
2796
|
+
/**
|
|
2797
|
+
* Initializes the active button state based on the initialActiveId input.
|
|
2798
|
+
* Sets the active state on the matching button item if an initial ID is provided.
|
|
2799
|
+
*/
|
|
2800
|
+
initializeActiveButton() {
|
|
2801
|
+
const items = this.buttonItems.toArray();
|
|
2802
|
+
const initialId = this.initialActiveId;
|
|
2803
|
+
// Set position - first and last explicitly, rest are middle
|
|
2804
|
+
if (items.length > 0) {
|
|
2805
|
+
items[0].position = 'first';
|
|
2806
|
+
if (items.length > 1) {
|
|
2807
|
+
items[items.length - 1].position = 'last';
|
|
2808
|
+
}
|
|
2809
|
+
for (let i = 1; i < items.length - 1; i++) {
|
|
2810
|
+
items[i].position = 'middle';
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2813
|
+
// Set active state
|
|
2814
|
+
if (initialId) {
|
|
2815
|
+
items.forEach((item) => {
|
|
2816
|
+
item.isActive = item.id === initialId;
|
|
2817
|
+
});
|
|
2818
|
+
this.activeButtonId.set(initialId);
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
/**
|
|
2822
|
+
* Handles button click events from child button items.
|
|
2823
|
+
* Updates the active button state and emits the activeButtonChange event.
|
|
2824
|
+
* @param buttonId - The ID of the clicked button
|
|
2825
|
+
*/
|
|
2826
|
+
onButtonClick(buttonId) {
|
|
2827
|
+
this.activeButtonId.set(buttonId);
|
|
2828
|
+
this.activeButtonChange.emit(buttonId);
|
|
2829
|
+
this.buttonItems.forEach((item) => {
|
|
2830
|
+
item.isActive = item.id === buttonId;
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2834
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ButtonGroupComponent, isStandalone: true, selector: "lib-button-group", inputs: { initialActiveId: "initialActiveId" }, outputs: { activeButtonChange: "activeButtonChange" }, queries: [{ propertyName: "buttonItems", predicate: ButtonGroupItemComponent }], ngImport: i0, template: "<div class=\"button-group\" role=\"tablist\">\n <ng-content></ng-content>\n</div>\n", styles: [".button-group{display:flex;overflow-x:auto;overflow-y:visible;-webkit-overflow-scrolling:touch;padding:.25rem}\n"] }); }
|
|
2835
|
+
}
|
|
2836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonGroupComponent, decorators: [{
|
|
2837
|
+
type: Component,
|
|
2838
|
+
args: [{ selector: 'lib-button-group', standalone: true, imports: [ButtonGroupItemComponent], template: "<div class=\"button-group\" role=\"tablist\">\n <ng-content></ng-content>\n</div>\n", styles: [".button-group{display:flex;overflow-x:auto;overflow-y:visible;-webkit-overflow-scrolling:touch;padding:.25rem}\n"] }]
|
|
2839
|
+
}], propDecorators: { initialActiveId: [{
|
|
2840
|
+
type: Input
|
|
2841
|
+
}], activeButtonChange: [{
|
|
2842
|
+
type: Output
|
|
2843
|
+
}], buttonItems: [{
|
|
2844
|
+
type: ContentChildren,
|
|
2845
|
+
args: [ButtonGroupItemComponent]
|
|
2846
|
+
}] } });
|
|
2847
|
+
|
|
2583
2848
|
/*
|
|
2584
2849
|
* Public API Surface of components
|
|
2585
2850
|
*/
|
|
@@ -2588,5 +2853,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
2588
2853
|
* Generated bundle index. Do not edit.
|
|
2589
2854
|
*/
|
|
2590
2855
|
|
|
2591
|
-
export { ADVANCED_SEARCH_FIELD_MAP, ADVANCED_SEARCH_OPTIONS, ADVANCED_SEARCH_QUALIFIER_MAP, HbllFooterComponent, HbllHeaderComponent, HbllItemTypeIconPipe, HeaderWithImpersonationComponent, ImpersonateModalComponent, ImpersonateUserPipe, ImpersonationBannerComponent, LIBRARY_HOURS_API_URL, SnackbarComponent, SnackbarService, SsSearchBarComponent, StatusButtonComponent, defaultOidcBaseUri, defaultOidcDefaultIdp, getUserStatusFromRoles, isAdvancedSearchExternalFieldOption, isAdvancedSearchFieldOption, isAdvancedSearchLocalFieldOption, isSearchScope };
|
|
2856
|
+
export { ADVANCED_SEARCH_FIELD_MAP, ADVANCED_SEARCH_OPTIONS, ADVANCED_SEARCH_QUALIFIER_MAP, ButtonComponent, ButtonGroupComponent, ButtonGroupItemComponent, HbllFooterComponent, HbllHeaderComponent, HbllItemTypeIconPipe, HeaderWithImpersonationComponent, ImpersonateModalComponent, ImpersonateUserPipe, ImpersonationBannerComponent, LIBRARY_HOURS_API_URL, SnackbarComponent, SnackbarService, SsSearchBarComponent, StatusButtonComponent, defaultOidcBaseUri, defaultOidcDefaultIdp, getUserStatusFromRoles, isAdvancedSearchExternalFieldOption, isAdvancedSearchFieldOption, isAdvancedSearchLocalFieldOption, isSearchScope };
|
|
2592
2857
|
//# sourceMappingURL=byuhbll-components.mjs.map
|