@byuhbll/components 5.2.0-beta.0 → 5.2.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.
@@ -3,7 +3,7 @@ import { CommonModule, DatePipe, DOCUMENT, LowerCasePipe, NgIf, NgClass } from '
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 { Component, ChangeDetectionStrategy, ViewChild, Input, input, EventEmitter, Output, inject, computed, ViewChildren, Pipe, Renderer2, viewChild, HostListener, ElementRef, Injector, runInInjectionContext, effect, ViewEncapsulation, booleanAttribute, createComponent, Injectable } from '@angular/core';
6
+ import { Component, ChangeDetectionStrategy, ViewChild, Input, input, EventEmitter, Output, inject, computed, ViewChildren, Pipe, Renderer2, viewChild, HostListener, ElementRef, Injector, runInInjectionContext, effect, ViewEncapsulation, booleanAttribute, createComponent, Injectable, signal, ContentChildren } from '@angular/core';
7
7
  import { trigger, transition, group, style, query, animateChild, animate } from '@angular/animations';
8
8
  import { map, of, switchMap, shareReplay, combineLatest, Subject, Subscription } from 'rxjs';
9
9
  import { BreakpointObserver } from '@angular/cdk/layout';
@@ -1104,7 +1104,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImpor
1104
1104
  }] } });
1105
1105
 
1106
1106
  const defaultOidcBaseUri = 'https://keycloak.lib.byu.edu/';
1107
- const defaultOidcDefaultIdp = 'byu-realm';
1107
+ const defaultOidcDefaultIdp = 'ces';
1108
1108
  class ImpersonateUserPipe {
1109
1109
  transform(user) {
1110
1110
  return `${user.name} (${user.netId || 'Unknown'})${user.restricted ? ' — Restricted' : ''}`;
@@ -2062,8 +2062,6 @@ class SimpleSearchComponent {
2062
2062
  constructor() {
2063
2063
  this.fb = inject(FormBuilder);
2064
2064
  this.subscription = new Subscription();
2065
- this.draftQuery = '';
2066
- this.isPatching = false;
2067
2065
  this.simpleSearch = new EventEmitter();
2068
2066
  this.clearSimpleSearch = new EventEmitter();
2069
2067
  this.isSubmitted = false;
@@ -2081,32 +2079,11 @@ class SimpleSearchComponent {
2081
2079
  this.isSubmitted = false;
2082
2080
  };
2083
2081
  this.clearQuery = () => {
2084
- this.isPatching = true;
2085
2082
  this.simpleQuery.setValue('');
2086
- this.isPatching = false;
2087
- this.draftQuery = '';
2088
2083
  this.clearSimpleSearch.emit();
2089
2084
  };
2090
2085
  this.setupForm = () => {
2091
- const incoming = this.config.q || this.config.advancedSearchQueryRows[0]?.query || '';
2092
- const current = this.simpleQuery.value ?? '';
2093
- // If we received a real query (submitted/synced), it should win.
2094
- if (incoming) {
2095
- if (incoming !== current) {
2096
- this.isPatching = true;
2097
- this.simpleQuery.setValue(incoming);
2098
- this.isPatching = false;
2099
- }
2100
- this.draftQuery = incoming; // keep draft aligned
2101
- return;
2102
- }
2103
- // No incoming query (tab switch before submit).
2104
- // Preserve what the user already typed (current/draft). Do NOT clear.
2105
- if (!current && this.draftQuery) {
2106
- this.isPatching = true;
2107
- this.simpleQuery.setValue(this.draftQuery);
2108
- this.isPatching = false;
2109
- }
2086
+ this.simpleQuery.setValue(this.config.q || this.config.advancedSearchQueryRows[0]?.query || '');
2110
2087
  };
2111
2088
  this.showSearchValidationToolTip = () => {
2112
2089
  this.searchInput.nativeElement.focus();
@@ -2126,19 +2103,14 @@ class SimpleSearchComponent {
2126
2103
  }
2127
2104
  ngOnInit() {
2128
2105
  // Ensure validation tooltip closes when uses enters a query
2129
- console.log('>>> Initializing');
2130
2106
  this.subscription.add(this.simpleQuery.valueChanges
2131
2107
  .pipe(startWith(''))
2132
2108
  .pipe(filter(() => !!this.inputTooltip))
2133
- .subscribe((v) => {
2109
+ .subscribe(() => {
2134
2110
  this.inputTooltip.disabled = true;
2135
- if (this.isPatching)
2136
- return;
2137
- this.draftQuery = v ?? '';
2138
2111
  }));
2139
2112
  }
2140
2113
  ngOnDestroy() {
2141
- console.log('>>> Destroying');
2142
2114
  this.subscription.unsubscribe();
2143
2115
  }
2144
2116
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: SimpleSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -2617,6 +2589,271 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImpor
2617
2589
  args: [{ providedIn: 'root' }]
2618
2590
  }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
2619
2591
 
2592
+ /**
2593
+ * A flexible, reusable button component that supports multiple button types
2594
+ * and various content combinations (icon before, title, icon after).
2595
+ *
2596
+ * @example
2597
+ * ```html
2598
+ * <!-- Primary button with icon and title -->
2599
+ * <lib-button
2600
+ * buttonType="primary"
2601
+ * title="Copy Citation"
2602
+ * iconBefore="content_copy"
2603
+ * (buttonClick)="copyCitation()">
2604
+ * </lib-button>
2605
+ *
2606
+ * <!-- Secondary button with title only -->
2607
+ * <lib-button
2608
+ * buttonType="secondary"
2609
+ * title="Cancel"
2610
+ * (buttonClick)="cancelAction()">
2611
+ * </lib-button>
2612
+ *
2613
+ * <!-- Transparent button with icon after title -->
2614
+ * <lib-button
2615
+ * buttonType="transparent"
2616
+ * title="Download"
2617
+ * iconAfter="download"
2618
+ * (buttonClick)="downloadFile()">
2619
+ * </lib-button>
2620
+ *
2621
+ * <!-- Thin button -->
2622
+ * <lib-button
2623
+ * buttonType="primary"
2624
+ * title="Submit"
2625
+ * [isThin]="true"
2626
+ * (buttonClick)="submitForm()">
2627
+ * </lib-button>
2628
+ * ```
2629
+ */
2630
+ class ButtonComponent {
2631
+ constructor() {
2632
+ this.buttonType = 'primary';
2633
+ this.disabled = false;
2634
+ this.isThin = false;
2635
+ this.buttonClick = new EventEmitter();
2636
+ }
2637
+ /**
2638
+ * Handles button click events and emits the buttonClick event if the button is not disabled.
2639
+ */
2640
+ onButtonClick() {
2641
+ if (!this.disabled) {
2642
+ this.buttonClick.emit();
2643
+ }
2644
+ }
2645
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2646
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", 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"] }] }); }
2647
+ }
2648
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonComponent, decorators: [{
2649
+ type: Component,
2650
+ 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"] }]
2651
+ }], propDecorators: { buttonType: [{
2652
+ type: Input
2653
+ }], title: [{
2654
+ type: Input
2655
+ }], iconBefore: [{
2656
+ type: Input
2657
+ }], iconAfter: [{
2658
+ type: Input
2659
+ }], disabled: [{
2660
+ type: Input
2661
+ }], isThin: [{
2662
+ type: Input
2663
+ }], ariaLabel: [{
2664
+ type: Input
2665
+ }], buttonClick: [{
2666
+ type: Output
2667
+ }] } });
2668
+
2669
+ class ButtonGroupItemComponent {
2670
+ constructor() {
2671
+ this.disabled = false;
2672
+ this.buttonClick = new EventEmitter();
2673
+ // Set by parent button group after content projection
2674
+ this.isActive = false;
2675
+ }
2676
+ /**
2677
+ * Handles the button click event and emits the button's ID to the parent component.
2678
+ */
2679
+ onClick() {
2680
+ this.buttonClick.emit(this.id);
2681
+ }
2682
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2683
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", 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 }] }); }
2684
+ }
2685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupItemComponent, decorators: [{
2686
+ type: Component,
2687
+ 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"] }]
2688
+ }], propDecorators: { id: [{
2689
+ type: Input,
2690
+ args: [{ required: true }]
2691
+ }], title: [{
2692
+ type: Input
2693
+ }], icon: [{
2694
+ type: Input
2695
+ }], ariaLabel: [{
2696
+ type: Input
2697
+ }], disabled: [{
2698
+ type: Input
2699
+ }], position: [{
2700
+ type: Input
2701
+ }], buttonClick: [{
2702
+ type: Output
2703
+ }] } });
2704
+
2705
+ class ButtonGroupComponent {
2706
+ constructor() {
2707
+ this.activeButtonChange = new EventEmitter();
2708
+ this.elementRef = inject(ElementRef);
2709
+ this.activeButtonId = signal('');
2710
+ this.subscriptions = [];
2711
+ }
2712
+ /**
2713
+ * Angular lifecycle hook called after content projection is initialized.
2714
+ * Sets up the initial active button and subscribes to button click events from all button items.
2715
+ */
2716
+ ngAfterContentInit() {
2717
+ // Handle both Angular components (via ContentChildren) and custom elements (via DOM)
2718
+ if (this.buttonItems.length > 0) {
2719
+ // Angular component usage
2720
+ this.initializeActiveButton();
2721
+ this.buttonItems.forEach((item) => {
2722
+ const sub = item.buttonClick.subscribe((id) => this.onButtonClick(id));
2723
+ this.subscriptions.push(sub);
2724
+ });
2725
+ }
2726
+ else {
2727
+ // Custom element usage - delay slightly to ensure custom elements are fully initialized
2728
+ setTimeout(() => {
2729
+ this.initializeCustomElements();
2730
+ }, 0);
2731
+ }
2732
+ }
2733
+ /**
2734
+ * Initializes custom element children when used as web components.
2735
+ */
2736
+ initializeCustomElements() {
2737
+ const hostElement = this.elementRef.nativeElement;
2738
+ const customElementChildren = Array.from(hostElement.querySelectorAll('hbll-button-group-item, lib-button-group-item'));
2739
+ if (customElementChildren.length > 0) {
2740
+ // Set position attributes - first and last explicitly, rest are middle
2741
+ customElementChildren[0].setAttribute('position', 'first');
2742
+ if (customElementChildren.length > 1) {
2743
+ customElementChildren[customElementChildren.length - 1].setAttribute('position', 'last');
2744
+ }
2745
+ for (let i = 1; i < customElementChildren.length - 1; i++) {
2746
+ customElementChildren[i].setAttribute('position', 'middle');
2747
+ }
2748
+ const initialId = this.initialActiveId;
2749
+ if (initialId) {
2750
+ this.activeButtonId.set(initialId);
2751
+ customElementChildren.forEach((item) => {
2752
+ const itemId = item.getAttribute('id');
2753
+ if (itemId === initialId) {
2754
+ this.setActiveState(item, true);
2755
+ }
2756
+ else {
2757
+ this.setActiveState(item, false);
2758
+ }
2759
+ });
2760
+ }
2761
+ // Listen to clicks on custom elements
2762
+ customElementChildren.forEach((item) => {
2763
+ item.addEventListener('click', () => {
2764
+ const itemId = item.getAttribute('id');
2765
+ if (itemId && !item.hasAttribute('disabled')) {
2766
+ this.handleCustomElementClick(itemId, customElementChildren);
2767
+ }
2768
+ });
2769
+ });
2770
+ }
2771
+ }
2772
+ /**
2773
+ * Sets the active state on a custom element by toggling the active class on its button.
2774
+ */
2775
+ setActiveState(element, isActive) {
2776
+ const button = element.querySelector('.tab-btn');
2777
+ if (button) {
2778
+ if (isActive) {
2779
+ button.classList.add('active');
2780
+ }
2781
+ else {
2782
+ button.classList.remove('active');
2783
+ }
2784
+ }
2785
+ }
2786
+ /**
2787
+ * Handles click events for custom element children.
2788
+ */
2789
+ handleCustomElementClick(buttonId, children) {
2790
+ this.activeButtonId.set(buttonId);
2791
+ this.activeButtonChange.emit(buttonId);
2792
+ children.forEach((item) => {
2793
+ const itemId = item.getAttribute('id');
2794
+ const isActive = itemId === buttonId;
2795
+ this.setActiveState(item, isActive);
2796
+ });
2797
+ }
2798
+ /**
2799
+ * Angular lifecycle hook called when the component is destroyed.
2800
+ * Cleans up all subscriptions to prevent memory leaks.
2801
+ */
2802
+ ngOnDestroy() {
2803
+ this.subscriptions.forEach((sub) => sub.unsubscribe());
2804
+ }
2805
+ /**
2806
+ * Initializes the active button state based on the initialActiveId input.
2807
+ * Sets the active state on the matching button item if an initial ID is provided.
2808
+ */
2809
+ initializeActiveButton() {
2810
+ const items = this.buttonItems.toArray();
2811
+ const initialId = this.initialActiveId;
2812
+ // Set position - first and last explicitly, rest are middle
2813
+ if (items.length > 0) {
2814
+ items[0].position = 'first';
2815
+ if (items.length > 1) {
2816
+ items[items.length - 1].position = 'last';
2817
+ }
2818
+ for (let i = 1; i < items.length - 1; i++) {
2819
+ items[i].position = 'middle';
2820
+ }
2821
+ }
2822
+ // Set active state
2823
+ if (initialId) {
2824
+ items.forEach((item) => {
2825
+ item.isActive = item.id === initialId;
2826
+ });
2827
+ this.activeButtonId.set(initialId);
2828
+ }
2829
+ }
2830
+ /**
2831
+ * Handles button click events from child button items.
2832
+ * Updates the active button state and emits the activeButtonChange event.
2833
+ * @param buttonId - The ID of the clicked button
2834
+ */
2835
+ onButtonClick(buttonId) {
2836
+ this.activeButtonId.set(buttonId);
2837
+ this.activeButtonChange.emit(buttonId);
2838
+ this.buttonItems.forEach((item) => {
2839
+ item.isActive = item.id === buttonId;
2840
+ });
2841
+ }
2842
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2843
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.0", 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"] }); }
2844
+ }
2845
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupComponent, decorators: [{
2846
+ type: Component,
2847
+ 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"] }]
2848
+ }], propDecorators: { initialActiveId: [{
2849
+ type: Input
2850
+ }], activeButtonChange: [{
2851
+ type: Output
2852
+ }], buttonItems: [{
2853
+ type: ContentChildren,
2854
+ args: [ButtonGroupItemComponent]
2855
+ }] } });
2856
+
2620
2857
  /*
2621
2858
  * Public API Surface of components
2622
2859
  */
@@ -2625,5 +2862,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImpor
2625
2862
  * Generated bundle index. Do not edit.
2626
2863
  */
2627
2864
 
2628
- 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 };
2865
+ 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 };
2629
2866
  //# sourceMappingURL=byuhbll-components.mjs.map