@byuhbll/components 5.0.2 → 5.0.3-beta.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/esm2022/lib/button/button.mjs +95 -0
- package/esm2022/lib/button-group/button-group.component.mjs +63 -0
- package/esm2022/lib/subatomic-components/button-group-item/button-group-item.component.mjs +29 -0
- package/esm2022/public-api.mjs +3 -1
- package/fesm2022/byuhbll-components.mjs +179 -2
- package/fesm2022/byuhbll-components.mjs.map +1 -1
- package/lib/button/button.d.ts +139 -0
- package/lib/button-group/button-group.component.d.ts +17 -0
- package/lib/subatomic-components/button-group-item/button-group-item.component.d.ts +18 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "@angular/common";
|
|
5
|
+
/**
|
|
6
|
+
* A flexible, reusable button component that supports multiple button types
|
|
7
|
+
* and various content combinations (icon before, title, icon after).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```html
|
|
11
|
+
* <!-- Primary button with icon and title -->
|
|
12
|
+
* <app-hbll-button-custom-component
|
|
13
|
+
* buttonType="primary"
|
|
14
|
+
* title="Copy Citation"
|
|
15
|
+
* iconBefore="../../assets/copy.svg"
|
|
16
|
+
* iconAlt="Copy icon"
|
|
17
|
+
* (buttonClick)="copyCitation()">
|
|
18
|
+
* </app-hbll-button-custom-component>
|
|
19
|
+
*
|
|
20
|
+
* <!-- Secondary button with title only -->
|
|
21
|
+
* <app-hbll-button-custom-component
|
|
22
|
+
* buttonType="secondary"
|
|
23
|
+
* title="Cancel"
|
|
24
|
+
* (buttonClick)="cancelAction()">
|
|
25
|
+
* </app-hbll-button-custom-component>
|
|
26
|
+
*
|
|
27
|
+
* <!-- Transparent button with icon after title -->
|
|
28
|
+
* <app-hbll-button-custom-component
|
|
29
|
+
* buttonType="transparent"
|
|
30
|
+
* title="Download"
|
|
31
|
+
* iconAfter="../../assets/download.svg"
|
|
32
|
+
* iconAlt="Download icon"
|
|
33
|
+
* (buttonClick)="downloadFile()">
|
|
34
|
+
* </app-hbll-button-custom-component>
|
|
35
|
+
*
|
|
36
|
+
* <!-- Thin button with reduced padding -->
|
|
37
|
+
* <app-hbll-button-custom-component
|
|
38
|
+
* buttonType="primary"
|
|
39
|
+
* title="Submit"
|
|
40
|
+
* [isThin]="true"
|
|
41
|
+
* (buttonClick)="submitForm()">
|
|
42
|
+
* </app-hbll-button-custom-component>
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export class ButtonComponent {
|
|
46
|
+
constructor() {
|
|
47
|
+
/**
|
|
48
|
+
* The visual style of the button
|
|
49
|
+
* @default 'primary'
|
|
50
|
+
*/
|
|
51
|
+
this.buttonType = 'primary';
|
|
52
|
+
/**
|
|
53
|
+
* Whether the button is disabled
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
this.disabled = false;
|
|
57
|
+
/**
|
|
58
|
+
* Whether the button should have thin padding
|
|
59
|
+
* @default false
|
|
60
|
+
*/
|
|
61
|
+
this.isThin = false;
|
|
62
|
+
/**
|
|
63
|
+
* Event emitted when the button is clicked or activated via keyboard
|
|
64
|
+
*/
|
|
65
|
+
this.buttonClick = new EventEmitter();
|
|
66
|
+
}
|
|
67
|
+
onButtonClick() {
|
|
68
|
+
if (!this.disabled) {
|
|
69
|
+
this.buttonClick.emit();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
73
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.0", type: ButtonComponent, isStandalone: true, selector: "lib-button", inputs: { buttonType: "buttonType", title: "title", iconBefore: "iconBefore", iconAfter: "iconAfter", iconAlt: "iconAlt", disabled: "disabled", isThin: "isThin" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [class]=\"'btn btn-' + buttonType + (isThin ? ' btn-thin' : '')\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"title || iconAlt\"\n (click)=\"onButtonClick()\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n <!-- Icon before title -->\n <span class=\"icon icon-before\" *ngIf=\"iconBefore\">\n <img\n [src]=\"iconBefore\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n\n <!-- Title text -->\n <span class=\"button-title\" *ngIf=\"title\">{{ title }}</span>\n\n <!-- Icon after title -->\n <span class=\"icon icon-after\" *ngIf=\"iconAfter\">\n <img\n [src]=\"iconAfter\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n</button>\n", styles: [".btn{padding:.8rem 2rem;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}.btn.btn-thin{padding:.4rem 2rem;border-radius:.5rem}.btn:disabled{cursor:not-allowed;color:#767676}.btn:disabled:not(.btn-transparent){background-color:#e7e7e7;border:1px solid #767676}.btn:focus{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-primary{background-color:#0047ba;color:#fff;border:1px solid #0047ba}.btn-primary:hover:not(:disabled){background-color:#003995}.btn-secondary{background-color:#fff;color:#00245d;border:1px 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}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
|
74
|
+
}
|
|
75
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
76
|
+
type: Component,
|
|
77
|
+
args: [{ selector: 'lib-button', standalone: true, imports: [CommonModule], template: "<button\n type=\"button\"\n [class]=\"'btn btn-' + buttonType + (isThin ? ' btn-thin' : '')\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"title || iconAlt\"\n (click)=\"onButtonClick()\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n <!-- Icon before title -->\n <span class=\"icon icon-before\" *ngIf=\"iconBefore\">\n <img\n [src]=\"iconBefore\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n\n <!-- Title text -->\n <span class=\"button-title\" *ngIf=\"title\">{{ title }}</span>\n\n <!-- Icon after title -->\n <span class=\"icon icon-after\" *ngIf=\"iconAfter\">\n <img\n [src]=\"iconAfter\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n</button>\n", styles: [".btn{padding:.8rem 2rem;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}.btn.btn-thin{padding:.4rem 2rem;border-radius:.5rem}.btn:disabled{cursor:not-allowed;color:#767676}.btn:disabled:not(.btn-transparent){background-color:#e7e7e7;border:1px solid #767676}.btn:focus{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-primary{background-color:#0047ba;color:#fff;border:1px solid #0047ba}.btn-primary:hover:not(:disabled){background-color:#003995}.btn-secondary{background-color:#fff;color:#00245d;border:1px 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}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"] }]
|
|
78
|
+
}], propDecorators: { buttonType: [{
|
|
79
|
+
type: Input
|
|
80
|
+
}], title: [{
|
|
81
|
+
type: Input
|
|
82
|
+
}], iconBefore: [{
|
|
83
|
+
type: Input
|
|
84
|
+
}], iconAfter: [{
|
|
85
|
+
type: Input
|
|
86
|
+
}], iconAlt: [{
|
|
87
|
+
type: Input
|
|
88
|
+
}], disabled: [{
|
|
89
|
+
type: Input
|
|
90
|
+
}], isThin: [{
|
|
91
|
+
type: Input
|
|
92
|
+
}], buttonClick: [{
|
|
93
|
+
type: Output
|
|
94
|
+
}] } });
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL2J1dHRvbi9idXR0b24udHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvYnV0dG9uL2J1dHRvbi5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7QUErRC9DOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Q0c7QUFRSCxNQUFNLE9BQU8sZUFBZTtJQVA1QjtRQVFJOzs7V0FHRztRQUNNLGVBQVUsR0FBZSxTQUFTLENBQUM7UUEwQjVDOzs7V0FHRztRQUNNLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFFbkM7OztXQUdHO1FBQ00sV0FBTSxHQUFZLEtBQUssQ0FBQztRQUVqQzs7V0FFRztRQUNPLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztLQU9wRDtJQUxHLGFBQWE7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUIsQ0FBQztJQUNMLENBQUM7OEdBcERRLGVBQWU7a0dBQWYsZUFBZSxtUkMvRzVCLGdsQ0F5Q0EsazVDRGtFYyxZQUFZOzsyRkFJYixlQUFlO2tCQVAzQixTQUFTOytCQUNJLFlBQVksY0FDVixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUM7OEJBU2QsVUFBVTtzQkFBbEIsS0FBSztnQkFNRyxLQUFLO3NCQUFiLEtBQUs7Z0JBTUcsVUFBVTtzQkFBbEIsS0FBSztnQkFNRyxTQUFTO3NCQUFqQixLQUFLO2dCQU1HLE9BQU87c0JBQWYsS0FBSztnQkFNRyxRQUFRO3NCQUFoQixLQUFLO2dCQU1HLE1BQU07c0JBQWQsS0FBSztnQkFLSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbmV4cG9ydCB0eXBlIEJ1dHRvblR5cGUgPSAncHJpbWFyeScgfCAnc2Vjb25kYXJ5JyB8ICd0cmFuc3BhcmVudCc7XG5cbi8qKlxuICogSW50ZXJmYWNlIHJlcHJlc2VudGluZyBhbGwgaW5wdXQgcHJvcGVydGllcyBmb3IgdGhlIEJ1dHRvbkNvbXBvbmVudC5cbiAqIFVzZSB0aGlzIHdoZW4gYSBwYXJlbnQgY29tcG9uZW50IG5lZWRzIHRvIGFjY2VwdCBidXR0b24gY29uZmlndXJhdGlvbiBhcyBhIHBhcmFtZXRlci5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogZXhwb3J0IGNsYXNzIFBhcmVudENvbXBvbmVudCB7XG4gKiAgIEBJbnB1dCgpIGJ1dHRvbkNvbmZpZzogQnV0dG9uSW5wdXRzID0ge1xuICogICAgIGJ1dHRvblR5cGU6ICdwcmltYXJ5JyxcbiAqICAgICB0aXRsZTogJ0NsaWNrIE1lJyxcbiAqICAgICBkaXNhYmxlZDogZmFsc2VcbiAqICAgfTtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1dHRvbklucHV0cyB7XG4gICAgLyoqXG4gICAgICogVGhlIHZpc3VhbCBzdHlsZSBvZiB0aGUgYnV0dG9uXG4gICAgICogQGRlZmF1bHQgJ3ByaW1hcnknXG4gICAgICovXG4gICAgYnV0dG9uVHlwZT86IEJ1dHRvblR5cGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGV4dCBjb250ZW50IGRpc3BsYXllZCBvbiB0aGUgYnV0dG9uXG4gICAgICogQG9wdGlvbmFsXG4gICAgICovXG4gICAgdGl0bGU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBQYXRoIHRvIGFuIGljb24gaW1hZ2UgZGlzcGxheWVkIGJlZm9yZSB0aGUgdGl0bGVcbiAgICAgKiBAb3B0aW9uYWxcbiAgICAgKi9cbiAgICBpY29uQmVmb3JlPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUGF0aCB0byBhbiBpY29uIGltYWdlIGRpc3BsYXllZCBhZnRlciB0aGUgdGl0bGVcbiAgICAgKiBAb3B0aW9uYWxcbiAgICAgKi9cbiAgICBpY29uQWZ0ZXI/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBbHRlcm5hdGl2ZSB0ZXh0IGZvciBpY29uIGFjY2Vzc2liaWxpdHlcbiAgICAgKiBAb3B0aW9uYWxcbiAgICAgKi9cbiAgICBpY29uQWx0Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgYnV0dG9uIGlzIGRpc2FibGVkXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBkaXNhYmxlZD86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBidXR0b24gc2hvdWxkIGhhdmUgdGhpbiBwYWRkaW5nXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBpc1RoaW4/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgZmxleGlibGUsIHJldXNhYmxlIGJ1dHRvbiBjb21wb25lbnQgdGhhdCBzdXBwb3J0cyBtdWx0aXBsZSBidXR0b24gdHlwZXNcbiAqIGFuZCB2YXJpb3VzIGNvbnRlbnQgY29tYmluYXRpb25zIChpY29uIGJlZm9yZSwgdGl0bGUsIGljb24gYWZ0ZXIpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8IS0tIFByaW1hcnkgYnV0dG9uIHdpdGggaWNvbiBhbmQgdGl0bGUgLS0+XG4gKiA8YXBwLWhibGwtYnV0dG9uLWN1c3RvbS1jb21wb25lbnRcbiAqICAgYnV0dG9uVHlwZT1cInByaW1hcnlcIlxuICogICB0aXRsZT1cIkNvcHkgQ2l0YXRpb25cIlxuICogICBpY29uQmVmb3JlPVwiLi4vLi4vYXNzZXRzL2NvcHkuc3ZnXCJcbiAqICAgaWNvbkFsdD1cIkNvcHkgaWNvblwiXG4gKiAgIChidXR0b25DbGljayk9XCJjb3B5Q2l0YXRpb24oKVwiPlxuICogPC9hcHAtaGJsbC1idXR0b24tY3VzdG9tLWNvbXBvbmVudD5cbiAqXG4gKiA8IS0tIFNlY29uZGFyeSBidXR0b24gd2l0aCB0aXRsZSBvbmx5IC0tPlxuICogPGFwcC1oYmxsLWJ1dHRvbi1jdXN0b20tY29tcG9uZW50XG4gKiAgIGJ1dHRvblR5cGU9XCJzZWNvbmRhcnlcIlxuICogICB0aXRsZT1cIkNhbmNlbFwiXG4gKiAgIChidXR0b25DbGljayk9XCJjYW5jZWxBY3Rpb24oKVwiPlxuICogPC9hcHAtaGJsbC1idXR0b24tY3VzdG9tLWNvbXBvbmVudD5cbiAqXG4gKiA8IS0tIFRyYW5zcGFyZW50IGJ1dHRvbiB3aXRoIGljb24gYWZ0ZXIgdGl0bGUgLS0+XG4gKiA8YXBwLWhibGwtYnV0dG9uLWN1c3RvbS1jb21wb25lbnRcbiAqICAgYnV0dG9uVHlwZT1cInRyYW5zcGFyZW50XCJcbiAqICAgdGl0bGU9XCJEb3dubG9hZFwiXG4gKiAgIGljb25BZnRlcj1cIi4uLy4uL2Fzc2V0cy9kb3dubG9hZC5zdmdcIlxuICogICBpY29uQWx0PVwiRG93bmxvYWQgaWNvblwiXG4gKiAgIChidXR0b25DbGljayk9XCJkb3dubG9hZEZpbGUoKVwiPlxuICogPC9hcHAtaGJsbC1idXR0b24tY3VzdG9tLWNvbXBvbmVudD5cbiAqXG4gKiA8IS0tIFRoaW4gYnV0dG9uIHdpdGggcmVkdWNlZCBwYWRkaW5nIC0tPlxuICogPGFwcC1oYmxsLWJ1dHRvbi1jdXN0b20tY29tcG9uZW50XG4gKiAgIGJ1dHRvblR5cGU9XCJwcmltYXJ5XCJcbiAqICAgdGl0bGU9XCJTdWJtaXRcIlxuICogICBbaXNUaGluXT1cInRydWVcIlxuICogICAoYnV0dG9uQ2xpY2spPVwic3VibWl0Rm9ybSgpXCI+XG4gKiA8L2FwcC1oYmxsLWJ1dHRvbi1jdXN0b20tY29tcG9uZW50PlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLWJ1dHRvbicsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vYnV0dG9uLmh0bWwnLFxuICAgIHN0eWxlVXJsOiAnLi9idXR0b24uc2NzcycsXG59KVxuZXhwb3J0IGNsYXNzIEJ1dHRvbkNvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogVGhlIHZpc3VhbCBzdHlsZSBvZiB0aGUgYnV0dG9uXG4gICAgICogQGRlZmF1bHQgJ3ByaW1hcnknXG4gICAgICovXG4gICAgQElucHV0KCkgYnV0dG9uVHlwZTogQnV0dG9uVHlwZSA9ICdwcmltYXJ5JztcblxuICAgIC8qKlxuICAgICAqIFRoZSB0ZXh0IGNvbnRlbnQgZGlzcGxheWVkIG9uIHRoZSBidXR0b25cbiAgICAgKiBAb3B0aW9uYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSB0aXRsZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhdGggdG8gYW4gaWNvbiBpbWFnZSBkaXNwbGF5ZWQgYmVmb3JlIHRoZSB0aXRsZVxuICAgICAqIEBvcHRpb25hbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGljb25CZWZvcmU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBQYXRoIHRvIGFuIGljb24gaW1hZ2UgZGlzcGxheWVkIGFmdGVyIHRoZSB0aXRsZVxuICAgICAqIEBvcHRpb25hbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGljb25BZnRlcj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFsdGVybmF0aXZlIHRleHQgZm9yIGljb24gYWNjZXNzaWJpbGl0eVxuICAgICAqIEBvcHRpb25hbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGljb25BbHQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBidXR0b24gaXMgZGlzYWJsZWRcbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBidXR0b24gc2hvdWxkIGhhdmUgdGhpbiBwYWRkaW5nXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKSBpc1RoaW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgYnV0dG9uIGlzIGNsaWNrZWQgb3IgYWN0aXZhdGVkIHZpYSBrZXlib2FyZFxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBidXR0b25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAgIG9uQnV0dG9uQ2xpY2soKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5idXR0b25DbGljay5lbWl0KCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8YnV0dG9uXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgW2NsYXNzXT1cIididG4gYnRuLScgKyBidXR0b25UeXBlICsgKGlzVGhpbiA/ICcgYnRuLXRoaW4nIDogJycpXCJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIFthdHRyLmFyaWEtbGFiZWxdPVwidGl0bGUgfHwgaWNvbkFsdFwiXG4gICAgKGNsaWNrKT1cIm9uQnV0dG9uQ2xpY2soKVwiXG4gICAgW2F0dHIudGFiaW5kZXhdPVwiZGlzYWJsZWQgPyAtMSA6IDBcIlxuPlxuICAgIDwhLS0gSWNvbiBiZWZvcmUgdGl0bGUgLS0+XG4gICAgPHNwYW4gY2xhc3M9XCJpY29uIGljb24tYmVmb3JlXCIgKm5nSWY9XCJpY29uQmVmb3JlXCI+XG4gICAgICAgIDxpbWdcbiAgICAgICAgICAgIFtzcmNdPVwiaWNvbkJlZm9yZVwiXG4gICAgICAgICAgICBbY2xhc3NdPVwiXG4gICAgICAgIGRpc2FibGVkXG4gICAgICAgICAgPyAnZGlzYWJsZWQtaWNvbidcbiAgICAgICAgICA6IGJ1dHRvblR5cGUgPT09ICdwcmltYXJ5J1xuICAgICAgICAgID8gJ3doaXRlLWljb24nXG4gICAgICAgICAgOiAnZGFyay1pY29uJ1xuICAgICAgXCJcbiAgICAgICAgICAgIFthbHRdPVwiaWNvbkFsdCB8fCAnJ1wiXG4gICAgICAgIC8+XG4gICAgPC9zcGFuPlxuXG4gICAgPCEtLSBUaXRsZSB0ZXh0IC0tPlxuICAgIDxzcGFuIGNsYXNzPVwiYnV0dG9uLXRpdGxlXCIgKm5nSWY9XCJ0aXRsZVwiPnt7IHRpdGxlIH19PC9zcGFuPlxuXG4gICAgPCEtLSBJY29uIGFmdGVyIHRpdGxlIC0tPlxuICAgIDxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLWFmdGVyXCIgKm5nSWY9XCJpY29uQWZ0ZXJcIj5cbiAgICAgICAgPGltZ1xuICAgICAgICAgICAgW3NyY109XCJpY29uQWZ0ZXJcIlxuICAgICAgICAgICAgW2NsYXNzXT1cIlxuICAgICAgICBkaXNhYmxlZFxuICAgICAgICAgID8gJ2Rpc2FibGVkLWljb24nXG4gICAgICAgICAgOiBidXR0b25UeXBlID09PSAncHJpbWFyeSdcbiAgICAgICAgICA/ICd3aGl0ZS1pY29uJ1xuICAgICAgICAgIDogJ2RhcmstaWNvbidcbiAgICAgIFwiXG4gICAgICAgICAgICBbYWx0XT1cImljb25BbHQgfHwgJydcIlxuICAgICAgICAvPlxuICAgIDwvc3Bhbj5cbjwvYnV0dG9uPlxuIl19
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, signal, } from '@angular/core';
|
|
2
|
+
import { ButtonGroupItemComponent, } from '../subatomic-components/button-group-item/button-group-item.component';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class ButtonGroupComponent {
|
|
5
|
+
constructor() {
|
|
6
|
+
// Input: Whether the button group is disabled
|
|
7
|
+
this.disabled = false;
|
|
8
|
+
// Output: Emits the id of the active button when changed
|
|
9
|
+
this.activeButtonChange = new EventEmitter();
|
|
10
|
+
// Internal state: Currently active button id
|
|
11
|
+
this.activeButtonId = signal('');
|
|
12
|
+
}
|
|
13
|
+
ngOnInit() {
|
|
14
|
+
this.initializeActiveButton();
|
|
15
|
+
}
|
|
16
|
+
ngOnChanges(changes) {
|
|
17
|
+
// When buttons or initialActiveId change (important for web components)
|
|
18
|
+
if (changes['buttons'] || changes['initialActiveId']) {
|
|
19
|
+
this.initializeActiveButton();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
initializeActiveButton() {
|
|
23
|
+
// Set initial active button
|
|
24
|
+
const initial = this.initialActiveId;
|
|
25
|
+
if (initial) {
|
|
26
|
+
this.activeButtonId.set(initial);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Find the first active button from the config
|
|
30
|
+
const activeButton = this.buttons?.find((btn) => btn.isActive);
|
|
31
|
+
if (activeButton) {
|
|
32
|
+
this.activeButtonId.set(activeButton.id);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Handle button click
|
|
37
|
+
onButtonClick(buttonId) {
|
|
38
|
+
if (!this.disabled) {
|
|
39
|
+
this.activeButtonId.set(buttonId);
|
|
40
|
+
this.activeButtonChange.emit(buttonId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Check if a button is active
|
|
44
|
+
isButtonActive(buttonId) {
|
|
45
|
+
return this.activeButtonId() === buttonId;
|
|
46
|
+
}
|
|
47
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
48
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", type: ButtonGroupComponent, isStandalone: true, selector: "lib-button-group", inputs: { buttons: "buttons", initialActiveId: "initialActiveId", disabled: "disabled" }, outputs: { activeButtonChange: "activeButtonChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"button-group\" role=\"tablist\">\n @for (button of buttons; track button.id) {\n <lib-button-group-item\n [button]=\"button\"\n [isActive]=\"isButtonActive(button.id)\"\n [disabled]=\"disabled\"\n (buttonClick)=\"onButtonClick($event)\"\n class=\"button-group-item\"\n />\n }\n</div>\n", styles: [".button-group{display:flex}.button-group lib-button-group-item:first-child::ng-deep .tab-btn{border-radius:.25rem 0 0 .25rem;border-left:1px solid #d0d0d0}.button-group lib-button-group-item:first-child::ng-deep .tab-btn:disabled{border-left:1px solid #767676}.button-group lib-button-group-item:last-child::ng-deep .tab-btn{border-radius:0 .25rem .25rem 0}@media (max-width: 640px){.button-group{overflow-x:auto;-webkit-overflow-scrolling:touch}}\n"], dependencies: [{ kind: "component", type: ButtonGroupItemComponent, selector: "lib-button-group-item", inputs: ["button", "isActive", "disabled"], outputs: ["buttonClick"] }] }); }
|
|
49
|
+
}
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupComponent, decorators: [{
|
|
51
|
+
type: Component,
|
|
52
|
+
args: [{ selector: 'lib-button-group', standalone: true, imports: [ButtonGroupItemComponent], template: "<div class=\"button-group\" role=\"tablist\">\n @for (button of buttons; track button.id) {\n <lib-button-group-item\n [button]=\"button\"\n [isActive]=\"isButtonActive(button.id)\"\n [disabled]=\"disabled\"\n (buttonClick)=\"onButtonClick($event)\"\n class=\"button-group-item\"\n />\n }\n</div>\n", styles: [".button-group{display:flex}.button-group lib-button-group-item:first-child::ng-deep .tab-btn{border-radius:.25rem 0 0 .25rem;border-left:1px solid #d0d0d0}.button-group lib-button-group-item:first-child::ng-deep .tab-btn:disabled{border-left:1px solid #767676}.button-group lib-button-group-item:last-child::ng-deep .tab-btn{border-radius:0 .25rem .25rem 0}@media (max-width: 640px){.button-group{overflow-x:auto;-webkit-overflow-scrolling:touch}}\n"] }]
|
|
53
|
+
}], propDecorators: { buttons: [{
|
|
54
|
+
type: Input,
|
|
55
|
+
args: [{ required: true }]
|
|
56
|
+
}], initialActiveId: [{
|
|
57
|
+
type: Input
|
|
58
|
+
}], disabled: [{
|
|
59
|
+
type: Input
|
|
60
|
+
}], activeButtonChange: [{
|
|
61
|
+
type: Output
|
|
62
|
+
}] } });
|
|
63
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLWdyb3VwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9idXR0b24tZ3JvdXAvYnV0dG9uLWdyb3VwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9idXR0b24tZ3JvdXAvYnV0dG9uLWdyb3VwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osTUFBTSxHQUlULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFSCx3QkFBd0IsR0FDM0IsTUFBTSx1RUFBdUUsQ0FBQzs7QUFTL0UsTUFBTSxPQUFPLG9CQUFvQjtJQVBqQztRQWNJLDhDQUE4QztRQUNyQyxhQUFRLEdBQVksS0FBSyxDQUFDO1FBRW5DLHlEQUF5RDtRQUMvQyx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRTFELDZDQUE2QztRQUM3QyxtQkFBYyxHQUFHLE1BQU0sQ0FBUyxFQUFFLENBQUMsQ0FBQztLQXVDdkM7SUFyQ0csUUFBUTtRQUNKLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDOUIsd0VBQXdFO1FBQ3hFLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDbkQsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDbEMsQ0FBQztJQUNMLENBQUM7SUFFTyxzQkFBc0I7UUFDMUIsNEJBQTRCO1FBQzVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDckMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JDLENBQUM7YUFBTSxDQUFDO1lBQ0osK0NBQStDO1lBQy9DLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0QsSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDZixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDN0MsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQsc0JBQXNCO0lBQ3RCLGFBQWEsQ0FBQyxRQUFnQjtRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDM0MsQ0FBQztJQUNMLENBQUM7SUFFRCw4QkFBOEI7SUFDOUIsY0FBYyxDQUFDLFFBQWdCO1FBQzNCLE9BQU8sSUFBSSxDQUFDLGNBQWMsRUFBRSxLQUFLLFFBQVEsQ0FBQztJQUM5QyxDQUFDOzhHQXBEUSxvQkFBb0I7a0dBQXBCLG9CQUFvQixrUEN0QmpDLHVYQVdBLDJmRE9jLHdCQUF3Qjs7MkZBSXpCLG9CQUFvQjtrQkFQaEMsU0FBUzsrQkFDSSxrQkFBa0IsY0FDaEIsSUFBSSxXQUNQLENBQUMsd0JBQXdCLENBQUM7OEJBTVIsT0FBTztzQkFBakMsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBR2hCLGVBQWU7c0JBQXZCLEtBQUs7Z0JBR0csUUFBUTtzQkFBaEIsS0FBSztnQkFHSSxrQkFBa0I7c0JBQTNCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIENvbXBvbmVudCxcbiAgICBJbnB1dCxcbiAgICBPdXRwdXQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIHNpZ25hbCxcbiAgICBPbkluaXQsXG4gICAgT25DaGFuZ2VzLFxuICAgIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBCdXR0b25Db25maWcsXG4gICAgQnV0dG9uR3JvdXBJdGVtQ29tcG9uZW50LFxufSBmcm9tICcuLi9zdWJhdG9taWMtY29tcG9uZW50cy9idXR0b24tZ3JvdXAtaXRlbS9idXR0b24tZ3JvdXAtaXRlbS5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2xpYi1idXR0b24tZ3JvdXAnLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW0J1dHRvbkdyb3VwSXRlbUNvbXBvbmVudF0sXG4gICAgdGVtcGxhdGVVcmw6ICcuL2J1dHRvbi1ncm91cC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmw6ICcuL2J1dHRvbi1ncm91cC5jb21wb25lbnQuc2NzcycsXG59KVxuZXhwb3J0IGNsYXNzIEJ1dHRvbkdyb3VwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICAgIC8vIElucHV0OiBBcnJheSBvZiBidXR0b24gY29uZmlndXJhdGlvbnNcbiAgICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBidXR0b25zITogQnV0dG9uQ29uZmlnW107XG5cbiAgICAvLyBJbnB1dDogT3B0aW9uYWwgaW5pdGlhbCBhY3RpdmUgYnV0dG9uIGlkXG4gICAgQElucHV0KCkgaW5pdGlhbEFjdGl2ZUlkPzogc3RyaW5nO1xuXG4gICAgLy8gSW5wdXQ6IFdoZXRoZXIgdGhlIGJ1dHRvbiBncm91cCBpcyBkaXNhYmxlZFxuICAgIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvLyBPdXRwdXQ6IEVtaXRzIHRoZSBpZCBvZiB0aGUgYWN0aXZlIGJ1dHRvbiB3aGVuIGNoYW5nZWRcbiAgICBAT3V0cHV0KCkgYWN0aXZlQnV0dG9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgICAvLyBJbnRlcm5hbCBzdGF0ZTogQ3VycmVudGx5IGFjdGl2ZSBidXR0b24gaWRcbiAgICBhY3RpdmVCdXR0b25JZCA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluaXRpYWxpemVBY3RpdmVCdXR0b24oKTtcbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIC8vIFdoZW4gYnV0dG9ucyBvciBpbml0aWFsQWN0aXZlSWQgY2hhbmdlIChpbXBvcnRhbnQgZm9yIHdlYiBjb21wb25lbnRzKVxuICAgICAgICBpZiAoY2hhbmdlc1snYnV0dG9ucyddIHx8IGNoYW5nZXNbJ2luaXRpYWxBY3RpdmVJZCddKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVBY3RpdmVCdXR0b24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdGlhbGl6ZUFjdGl2ZUJ1dHRvbigpOiB2b2lkIHtcbiAgICAgICAgLy8gU2V0IGluaXRpYWwgYWN0aXZlIGJ1dHRvblxuICAgICAgICBjb25zdCBpbml0aWFsID0gdGhpcy5pbml0aWFsQWN0aXZlSWQ7XG4gICAgICAgIGlmIChpbml0aWFsKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbklkLnNldChpbml0aWFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IGFjdGl2ZSBidXR0b24gZnJvbSB0aGUgY29uZmlnXG4gICAgICAgICAgICBjb25zdCBhY3RpdmVCdXR0b24gPSB0aGlzLmJ1dHRvbnM/LmZpbmQoKGJ0bikgPT4gYnRuLmlzQWN0aXZlKTtcbiAgICAgICAgICAgIGlmIChhY3RpdmVCdXR0b24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbklkLnNldChhY3RpdmVCdXR0b24uaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGJ1dHRvbiBjbGlja1xuICAgIG9uQnV0dG9uQ2xpY2soYnV0dG9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uSWQuc2V0KGJ1dHRvbklkKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uQ2hhbmdlLmVtaXQoYnV0dG9uSWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYSBidXR0b24gaXMgYWN0aXZlXG4gICAgaXNCdXR0b25BY3RpdmUoYnV0dG9uSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hY3RpdmVCdXR0b25JZCgpID09PSBidXR0b25JZDtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiYnV0dG9uLWdyb3VwXCIgcm9sZT1cInRhYmxpc3RcIj5cbiAgICBAZm9yIChidXR0b24gb2YgYnV0dG9uczsgdHJhY2sgYnV0dG9uLmlkKSB7XG4gICAgICAgIDxsaWItYnV0dG9uLWdyb3VwLWl0ZW1cbiAgICAgICAgICAgIFtidXR0b25dPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIFtpc0FjdGl2ZV09XCJpc0J1dHRvbkFjdGl2ZShidXR0b24uaWQpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25CdXR0b25DbGljaygkZXZlbnQpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiYnV0dG9uLWdyb3VwLWl0ZW1cIlxuICAgICAgICAvPlxuICAgIH1cbjwvZGl2PlxuIl19
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class ButtonGroupItemComponent {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.isActive = false;
|
|
7
|
+
this.disabled = false;
|
|
8
|
+
this.buttonClick = new EventEmitter();
|
|
9
|
+
}
|
|
10
|
+
onClick() {
|
|
11
|
+
this.buttonClick.emit(this.button.id);
|
|
12
|
+
}
|
|
13
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
14
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", type: ButtonGroupItemComponent, isStandalone: true, selector: "lib-button-group-item", inputs: { button: "button", isActive: "isActive", disabled: "disabled" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"isActive\"\n [disabled]=\"disabled\"\n (click)=\"onClick()\"\n role=\"tab\"\n [attr.aria-pressed]=\"isActive\"\n [attr.aria-label]=\"button.title\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (button.icon) {\n <span class=\"icon\">\n <img\n [src]=\"button.icon\"\n [class]=\"disabled ? 'disabled-icon' : isActive ? 'white-icon' : 'dark-icon'\"\n [alt]=\"button.iconAlt || ''\"\n />\n </span>\n }\n\n @if (button.title) {\n <span class=\"button-title\">{{ button.title }}</span>\n }\n</button>\n", styles: [".tab-btn{padding:.5rem;font-size:1rem;font-weight:400;color:#00245d;background-color:#fff;cursor:pointer;position:relative;border:1px solid #d0d0d0;border-left:none;border-radius:0;transition:all .2s ease;display:inline-flex;align-items:center;justify-content:center;gap:.25rem;height:2.3rem}.tab-btn:not(:disabled):hover{background-color:#e5edf8}.tab-btn.active{background-color:#0047ba;color:#fff;z-index:10}.tab-btn.active:not(:disabled):hover{background-color:#003995}.tab-btn:focus{outline:.125rem solid #b967c7;outline-offset:.125rem}.tab-btn:disabled{cursor:not-allowed;color:#767676;background-color:#e7e7e7;border:1px solid #767676}.tab-btn .icon{display:flex;align-items:center;justify-content:center}.tab-btn .icon img{height:1rem;width:auto}.tab-btn .button-title{flex-shrink:0}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
15
|
+
}
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupItemComponent, decorators: [{
|
|
17
|
+
type: Component,
|
|
18
|
+
args: [{ selector: 'lib-button-group-item', standalone: true, imports: [CommonModule], template: "<button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"isActive\"\n [disabled]=\"disabled\"\n (click)=\"onClick()\"\n role=\"tab\"\n [attr.aria-pressed]=\"isActive\"\n [attr.aria-label]=\"button.title\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (button.icon) {\n <span class=\"icon\">\n <img\n [src]=\"button.icon\"\n [class]=\"disabled ? 'disabled-icon' : isActive ? 'white-icon' : 'dark-icon'\"\n [alt]=\"button.iconAlt || ''\"\n />\n </span>\n }\n\n @if (button.title) {\n <span class=\"button-title\">{{ button.title }}</span>\n }\n</button>\n", styles: [".tab-btn{padding:.5rem;font-size:1rem;font-weight:400;color:#00245d;background-color:#fff;cursor:pointer;position:relative;border:1px solid #d0d0d0;border-left:none;border-radius:0;transition:all .2s ease;display:inline-flex;align-items:center;justify-content:center;gap:.25rem;height:2.3rem}.tab-btn:not(:disabled):hover{background-color:#e5edf8}.tab-btn.active{background-color:#0047ba;color:#fff;z-index:10}.tab-btn.active:not(:disabled):hover{background-color:#003995}.tab-btn:focus{outline:.125rem solid #b967c7;outline-offset:.125rem}.tab-btn:disabled{cursor:not-allowed;color:#767676;background-color:#e7e7e7;border:1px solid #767676}.tab-btn .icon{display:flex;align-items:center;justify-content:center}.tab-btn .icon img{height:1rem;width:auto}.tab-btn .button-title{flex-shrink:0}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"] }]
|
|
19
|
+
}], propDecorators: { button: [{
|
|
20
|
+
type: Input,
|
|
21
|
+
args: [{ required: true }]
|
|
22
|
+
}], isActive: [{
|
|
23
|
+
type: Input
|
|
24
|
+
}], disabled: [{
|
|
25
|
+
type: Input
|
|
26
|
+
}], buttonClick: [{
|
|
27
|
+
type: Output
|
|
28
|
+
}] } });
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLWdyb3VwLWl0ZW0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL3N1YmF0b21pYy1jb21wb25lbnRzL2J1dHRvbi1ncm91cC1pdGVtL2J1dHRvbi1ncm91cC1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9zdWJhdG9taWMtY29tcG9uZW50cy9idXR0b24tZ3JvdXAtaXRlbS9idXR0b24tZ3JvdXAtaXRlbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFpQi9DLE1BQU0sT0FBTyx3QkFBd0I7SUFQckM7UUFTYSxhQUFRLEdBQVksS0FBSyxDQUFDO1FBQzFCLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFDekIsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO0tBS3REO0lBSEcsT0FBTztRQUNILElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUMsQ0FBQzs4R0FSUSx3QkFBd0I7a0dBQXhCLHdCQUF3QixvTUNsQnJDLHFyQkF5QkEsbXBDRFhjLFlBQVk7OzJGQUliLHdCQUF3QjtrQkFQcEMsU0FBUzsrQkFDSSx1QkFBdUIsY0FDckIsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDOzhCQUtJLE1BQU07c0JBQWhDLEtBQUs7dUJBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFO2dCQUNoQixRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0ksV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJ1dHRvbkNvbmZpZyB7XG4gICAgaWQ6IHN0cmluZztcbiAgICB0aXRsZT86IHN0cmluZztcbiAgICBpc0FjdGl2ZTogYm9vbGVhbjtcbiAgICBpY29uPzogc3RyaW5nO1xuICAgIGljb25BbHQ/OiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLWJ1dHRvbi1ncm91cC1pdGVtJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9idXR0b24tZ3JvdXAtaXRlbS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmw6ICcuL2J1dHRvbi1ncm91cC1pdGVtLmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgQnV0dG9uR3JvdXBJdGVtQ29tcG9uZW50IHtcbiAgICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBidXR0b24hOiBCdXR0b25Db25maWc7XG4gICAgQElucHV0KCkgaXNBY3RpdmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBPdXRwdXQoKSBidXR0b25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgb25DbGljaygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5idXR0b25DbGljay5lbWl0KHRoaXMuYnV0dG9uLmlkKTtcbiAgICB9XG59XG4iLCI8YnV0dG9uXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgY2xhc3M9XCJ0YWItYnRuXCJcbiAgICBbY2xhc3MuYWN0aXZlXT1cImlzQWN0aXZlXCJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIChjbGljayk9XCJvbkNsaWNrKClcIlxuICAgIHJvbGU9XCJ0YWJcIlxuICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCJpc0FjdGl2ZVwiXG4gICAgW2F0dHIuYXJpYS1sYWJlbF09XCJidXR0b24udGl0bGVcIlxuICAgIFthdHRyLnRhYmluZGV4XT1cImRpc2FibGVkID8gLTEgOiAwXCJcbj5cbiAgICBAaWYgKGJ1dHRvbi5pY29uKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvblwiPlxuICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgIFtzcmNdPVwiYnV0dG9uLmljb25cIlxuICAgICAgICAgICAgICAgIFtjbGFzc109XCJkaXNhYmxlZCA/ICdkaXNhYmxlZC1pY29uJyA6IGlzQWN0aXZlID8gJ3doaXRlLWljb24nIDogJ2RhcmstaWNvbidcIlxuICAgICAgICAgICAgICAgIFthbHRdPVwiYnV0dG9uLmljb25BbHQgfHwgJydcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC9zcGFuPlxuICAgIH1cblxuICAgIEBpZiAoYnV0dG9uLnRpdGxlKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYnV0dG9uLXRpdGxlXCI+e3sgYnV0dG9uLnRpdGxlIH19PC9zcGFuPlxuICAgIH1cbjwvYnV0dG9uPlxuIl19
|
package/esm2022/public-api.mjs
CHANGED
|
@@ -16,4 +16,6 @@ export * from './lib/snackbar/snackbar.component';
|
|
|
16
16
|
export { getUserStatusFromRoles } from './lib/contact-utils';
|
|
17
17
|
export { ADVANCED_SEARCH_QUALIFIER_MAP, ADVANCED_SEARCH_FIELD_MAP, ADVANCED_SEARCH_OPTIONS, } from './lib/ss-search-bar/constants';
|
|
18
18
|
export * from './lib/status-button/status-button.component';
|
|
19
|
-
|
|
19
|
+
export * from './lib/button/button';
|
|
20
|
+
export * from './lib/button-group/button-group.component';
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLHlDQUF5QyxDQUFDO0FBQ3hELGNBQWMsc0NBQXNDLENBQUM7QUFDckQsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxjQUFjLHFFQUFxRSxDQUFDO0FBQ3BGLGNBQWMscURBQXFELENBQUM7QUFDcEUsY0FBYywyREFBMkQsQ0FBQztBQUMxRSxjQUFjLDZDQUE2QyxDQUFDO0FBQzVELGNBQWMsa0RBQWtELENBQUM7QUFDakUsY0FBYywrQ0FBK0MsQ0FBQztBQUM5RCxjQUFjLGdEQUFnRCxDQUFDO0FBQy9ELGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyxtQ0FBbUMsQ0FBQztBQUNsRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM3RCxPQUFPLEVBQ0gsNkJBQTZCLEVBQzdCLHlCQUF5QixFQUN6Qix1QkFBdUIsR0FDMUIsTUFBTSwrQkFBK0IsQ0FBQztBQUN2QyxjQUFjLDZDQUE2QyxDQUFDO0FBQzVELGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYywyQ0FBMkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2YgY29tcG9uZW50c1xuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL2hibGwtaGVhZGVyL2hibGwtaGVhZGVyLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9waXBlcy9oYmxsLWl0ZW0tdHlwZS1pY29uLnBpcGUnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvaGJsbC1mb290ZXIvaGJsbC1mb290ZXIuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2hlYWRlci13aXRoLWltcGVyc29uYXRpb24vaGVhZGVyLXdpdGgtaW1wZXJzb25hdGlvbi5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvaW1wZXJzb25hdGUtbW9kYWwvaW1wZXJzb25hdGUtbW9kYWwuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2ltcGVyc29uYXRpb24tYmFubmVyL2ltcGVyc29uYXRpb24tYmFubmVyLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zcy1zZWFyY2gtYmFyL3NzLXNlYXJjaC1iYXIuY29tcG9uZW50JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3NzLXNlYXJjaC1iYXIvbW9kZWxzL2FkdmFuY2VkLXNlYXJjaC5tb2RlbCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zcy1zZWFyY2gtYmFyL21vZGVscy9zZWFyY2gtc2NvcGUubW9kZWwnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvc3Mtc2VhcmNoLWJhci9tb2RlbHMvc2VhcmNoLWNvbmZpZy5tb2RlbCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9zbmFja2Jhci9zbmFja2Jhci5zZXJ2aWNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3NuYWNrYmFyL3NuYWNrYmFyLmNvbXBvbmVudCc7XG5leHBvcnQgeyBnZXRVc2VyU3RhdHVzRnJvbVJvbGVzIH0gZnJvbSAnLi9saWIvY29udGFjdC11dGlscyc7XG5leHBvcnQge1xuICAgIEFEVkFOQ0VEX1NFQVJDSF9RVUFMSUZJRVJfTUFQLFxuICAgIEFEVkFOQ0VEX1NFQVJDSF9GSUVMRF9NQVAsXG4gICAgQURWQU5DRURfU0VBUkNIX09QVElPTlMsXG59IGZyb20gJy4vbGliL3NzLXNlYXJjaC1iYXIvY29uc3RhbnRzJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3N0YXR1cy1idXR0b24vc3RhdHVzLWJ1dHRvbi5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvYnV0dG9uL2J1dHRvbic7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9idXR0b24tZ3JvdXAvYnV0dG9uLWdyb3VwLmNvbXBvbmVudCc7XG4iXX0=
|
|
@@ -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 } 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';
|
|
@@ -2581,6 +2581,183 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImpor
|
|
|
2581
2581
|
args: [{ providedIn: 'root' }]
|
|
2582
2582
|
}], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
|
|
2583
2583
|
|
|
2584
|
+
/**
|
|
2585
|
+
* A flexible, reusable button component that supports multiple button types
|
|
2586
|
+
* and various content combinations (icon before, title, icon after).
|
|
2587
|
+
*
|
|
2588
|
+
* @example
|
|
2589
|
+
* ```html
|
|
2590
|
+
* <!-- Primary button with icon and title -->
|
|
2591
|
+
* <app-hbll-button-custom-component
|
|
2592
|
+
* buttonType="primary"
|
|
2593
|
+
* title="Copy Citation"
|
|
2594
|
+
* iconBefore="../../assets/copy.svg"
|
|
2595
|
+
* iconAlt="Copy icon"
|
|
2596
|
+
* (buttonClick)="copyCitation()">
|
|
2597
|
+
* </app-hbll-button-custom-component>
|
|
2598
|
+
*
|
|
2599
|
+
* <!-- Secondary button with title only -->
|
|
2600
|
+
* <app-hbll-button-custom-component
|
|
2601
|
+
* buttonType="secondary"
|
|
2602
|
+
* title="Cancel"
|
|
2603
|
+
* (buttonClick)="cancelAction()">
|
|
2604
|
+
* </app-hbll-button-custom-component>
|
|
2605
|
+
*
|
|
2606
|
+
* <!-- Transparent button with icon after title -->
|
|
2607
|
+
* <app-hbll-button-custom-component
|
|
2608
|
+
* buttonType="transparent"
|
|
2609
|
+
* title="Download"
|
|
2610
|
+
* iconAfter="../../assets/download.svg"
|
|
2611
|
+
* iconAlt="Download icon"
|
|
2612
|
+
* (buttonClick)="downloadFile()">
|
|
2613
|
+
* </app-hbll-button-custom-component>
|
|
2614
|
+
*
|
|
2615
|
+
* <!-- Thin button with reduced padding -->
|
|
2616
|
+
* <app-hbll-button-custom-component
|
|
2617
|
+
* buttonType="primary"
|
|
2618
|
+
* title="Submit"
|
|
2619
|
+
* [isThin]="true"
|
|
2620
|
+
* (buttonClick)="submitForm()">
|
|
2621
|
+
* </app-hbll-button-custom-component>
|
|
2622
|
+
* ```
|
|
2623
|
+
*/
|
|
2624
|
+
class ButtonComponent {
|
|
2625
|
+
constructor() {
|
|
2626
|
+
/**
|
|
2627
|
+
* The visual style of the button
|
|
2628
|
+
* @default 'primary'
|
|
2629
|
+
*/
|
|
2630
|
+
this.buttonType = 'primary';
|
|
2631
|
+
/**
|
|
2632
|
+
* Whether the button is disabled
|
|
2633
|
+
* @default false
|
|
2634
|
+
*/
|
|
2635
|
+
this.disabled = false;
|
|
2636
|
+
/**
|
|
2637
|
+
* Whether the button should have thin padding
|
|
2638
|
+
* @default false
|
|
2639
|
+
*/
|
|
2640
|
+
this.isThin = false;
|
|
2641
|
+
/**
|
|
2642
|
+
* Event emitted when the button is clicked or activated via keyboard
|
|
2643
|
+
*/
|
|
2644
|
+
this.buttonClick = new EventEmitter();
|
|
2645
|
+
}
|
|
2646
|
+
onButtonClick() {
|
|
2647
|
+
if (!this.disabled) {
|
|
2648
|
+
this.buttonClick.emit();
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2652
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.0", type: ButtonComponent, isStandalone: true, selector: "lib-button", inputs: { buttonType: "buttonType", title: "title", iconBefore: "iconBefore", iconAfter: "iconAfter", iconAlt: "iconAlt", disabled: "disabled", isThin: "isThin" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n type=\"button\"\n [class]=\"'btn btn-' + buttonType + (isThin ? ' btn-thin' : '')\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"title || iconAlt\"\n (click)=\"onButtonClick()\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n <!-- Icon before title -->\n <span class=\"icon icon-before\" *ngIf=\"iconBefore\">\n <img\n [src]=\"iconBefore\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n\n <!-- Title text -->\n <span class=\"button-title\" *ngIf=\"title\">{{ title }}</span>\n\n <!-- Icon after title -->\n <span class=\"icon icon-after\" *ngIf=\"iconAfter\">\n <img\n [src]=\"iconAfter\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n</button>\n", styles: [".btn{padding:.8rem 2rem;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}.btn.btn-thin{padding:.4rem 2rem;border-radius:.5rem}.btn:disabled{cursor:not-allowed;color:#767676}.btn:disabled:not(.btn-transparent){background-color:#e7e7e7;border:1px solid #767676}.btn:focus{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-primary{background-color:#0047ba;color:#fff;border:1px solid #0047ba}.btn-primary:hover:not(:disabled){background-color:#003995}.btn-secondary{background-color:#fff;color:#00245d;border:1px 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}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
|
2653
|
+
}
|
|
2654
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
2655
|
+
type: Component,
|
|
2656
|
+
args: [{ selector: 'lib-button', standalone: true, imports: [CommonModule], template: "<button\n type=\"button\"\n [class]=\"'btn btn-' + buttonType + (isThin ? ' btn-thin' : '')\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"title || iconAlt\"\n (click)=\"onButtonClick()\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n <!-- Icon before title -->\n <span class=\"icon icon-before\" *ngIf=\"iconBefore\">\n <img\n [src]=\"iconBefore\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n\n <!-- Title text -->\n <span class=\"button-title\" *ngIf=\"title\">{{ title }}</span>\n\n <!-- Icon after title -->\n <span class=\"icon icon-after\" *ngIf=\"iconAfter\">\n <img\n [src]=\"iconAfter\"\n [class]=\"\n disabled\n ? 'disabled-icon'\n : buttonType === 'primary'\n ? 'white-icon'\n : 'dark-icon'\n \"\n [alt]=\"iconAlt || ''\"\n />\n </span>\n</button>\n", styles: [".btn{padding:.8rem 2rem;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}.btn.btn-thin{padding:.4rem 2rem;border-radius:.5rem}.btn:disabled{cursor:not-allowed;color:#767676}.btn:disabled:not(.btn-transparent){background-color:#e7e7e7;border:1px solid #767676}.btn:focus{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-primary{background-color:#0047ba;color:#fff;border:1px solid #0047ba}.btn-primary:hover:not(:disabled){background-color:#003995}.btn-secondary{background-color:#fff;color:#00245d;border:1px 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}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"] }]
|
|
2657
|
+
}], propDecorators: { buttonType: [{
|
|
2658
|
+
type: Input
|
|
2659
|
+
}], title: [{
|
|
2660
|
+
type: Input
|
|
2661
|
+
}], iconBefore: [{
|
|
2662
|
+
type: Input
|
|
2663
|
+
}], iconAfter: [{
|
|
2664
|
+
type: Input
|
|
2665
|
+
}], iconAlt: [{
|
|
2666
|
+
type: Input
|
|
2667
|
+
}], disabled: [{
|
|
2668
|
+
type: Input
|
|
2669
|
+
}], isThin: [{
|
|
2670
|
+
type: Input
|
|
2671
|
+
}], buttonClick: [{
|
|
2672
|
+
type: Output
|
|
2673
|
+
}] } });
|
|
2674
|
+
|
|
2675
|
+
class ButtonGroupItemComponent {
|
|
2676
|
+
constructor() {
|
|
2677
|
+
this.isActive = false;
|
|
2678
|
+
this.disabled = false;
|
|
2679
|
+
this.buttonClick = new EventEmitter();
|
|
2680
|
+
}
|
|
2681
|
+
onClick() {
|
|
2682
|
+
this.buttonClick.emit(this.button.id);
|
|
2683
|
+
}
|
|
2684
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2685
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", type: ButtonGroupItemComponent, isStandalone: true, selector: "lib-button-group-item", inputs: { button: "button", isActive: "isActive", disabled: "disabled" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"isActive\"\n [disabled]=\"disabled\"\n (click)=\"onClick()\"\n role=\"tab\"\n [attr.aria-pressed]=\"isActive\"\n [attr.aria-label]=\"button.title\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (button.icon) {\n <span class=\"icon\">\n <img\n [src]=\"button.icon\"\n [class]=\"disabled ? 'disabled-icon' : isActive ? 'white-icon' : 'dark-icon'\"\n [alt]=\"button.iconAlt || ''\"\n />\n </span>\n }\n\n @if (button.title) {\n <span class=\"button-title\">{{ button.title }}</span>\n }\n</button>\n", styles: [".tab-btn{padding:.5rem;font-size:1rem;font-weight:400;color:#00245d;background-color:#fff;cursor:pointer;position:relative;border:1px solid #d0d0d0;border-left:none;border-radius:0;transition:all .2s ease;display:inline-flex;align-items:center;justify-content:center;gap:.25rem;height:2.3rem}.tab-btn:not(:disabled):hover{background-color:#e5edf8}.tab-btn.active{background-color:#0047ba;color:#fff;z-index:10}.tab-btn.active:not(:disabled):hover{background-color:#003995}.tab-btn:focus{outline:.125rem solid #b967c7;outline-offset:.125rem}.tab-btn:disabled{cursor:not-allowed;color:#767676;background-color:#e7e7e7;border:1px solid #767676}.tab-btn .icon{display:flex;align-items:center;justify-content:center}.tab-btn .icon img{height:1rem;width:auto}.tab-btn .button-title{flex-shrink:0}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
2686
|
+
}
|
|
2687
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupItemComponent, decorators: [{
|
|
2688
|
+
type: Component,
|
|
2689
|
+
args: [{ selector: 'lib-button-group-item', standalone: true, imports: [CommonModule], template: "<button\n type=\"button\"\n class=\"tab-btn\"\n [class.active]=\"isActive\"\n [disabled]=\"disabled\"\n (click)=\"onClick()\"\n role=\"tab\"\n [attr.aria-pressed]=\"isActive\"\n [attr.aria-label]=\"button.title\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n>\n @if (button.icon) {\n <span class=\"icon\">\n <img\n [src]=\"button.icon\"\n [class]=\"disabled ? 'disabled-icon' : isActive ? 'white-icon' : 'dark-icon'\"\n [alt]=\"button.iconAlt || ''\"\n />\n </span>\n }\n\n @if (button.title) {\n <span class=\"button-title\">{{ button.title }}</span>\n }\n</button>\n", styles: [".tab-btn{padding:.5rem;font-size:1rem;font-weight:400;color:#00245d;background-color:#fff;cursor:pointer;position:relative;border:1px solid #d0d0d0;border-left:none;border-radius:0;transition:all .2s ease;display:inline-flex;align-items:center;justify-content:center;gap:.25rem;height:2.3rem}.tab-btn:not(:disabled):hover{background-color:#e5edf8}.tab-btn.active{background-color:#0047ba;color:#fff;z-index:10}.tab-btn.active:not(:disabled):hover{background-color:#003995}.tab-btn:focus{outline:.125rem solid #b967c7;outline-offset:.125rem}.tab-btn:disabled{cursor:not-allowed;color:#767676;background-color:#e7e7e7;border:1px solid #767676}.tab-btn .icon{display:flex;align-items:center;justify-content:center}.tab-btn .icon img{height:1rem;width:auto}.tab-btn .button-title{flex-shrink:0}.white-icon{filter:invert(100%) sepia(0%) saturate(7489%) hue-rotate(149deg) brightness(104%) contrast(100%)}.dark-icon{filter:invert(12%) sepia(44%) saturate(3863%) hue-rotate(207deg) brightness(90%) contrast(105%)}.disabled-icon{filter:invert(48%) sepia(0%) saturate(0%) hue-rotate(146deg) brightness(96%) contrast(88%)}\n"] }]
|
|
2690
|
+
}], propDecorators: { button: [{
|
|
2691
|
+
type: Input,
|
|
2692
|
+
args: [{ required: true }]
|
|
2693
|
+
}], isActive: [{
|
|
2694
|
+
type: Input
|
|
2695
|
+
}], disabled: [{
|
|
2696
|
+
type: Input
|
|
2697
|
+
}], buttonClick: [{
|
|
2698
|
+
type: Output
|
|
2699
|
+
}] } });
|
|
2700
|
+
|
|
2701
|
+
class ButtonGroupComponent {
|
|
2702
|
+
constructor() {
|
|
2703
|
+
// Input: Whether the button group is disabled
|
|
2704
|
+
this.disabled = false;
|
|
2705
|
+
// Output: Emits the id of the active button when changed
|
|
2706
|
+
this.activeButtonChange = new EventEmitter();
|
|
2707
|
+
// Internal state: Currently active button id
|
|
2708
|
+
this.activeButtonId = signal('');
|
|
2709
|
+
}
|
|
2710
|
+
ngOnInit() {
|
|
2711
|
+
this.initializeActiveButton();
|
|
2712
|
+
}
|
|
2713
|
+
ngOnChanges(changes) {
|
|
2714
|
+
// When buttons or initialActiveId change (important for web components)
|
|
2715
|
+
if (changes['buttons'] || changes['initialActiveId']) {
|
|
2716
|
+
this.initializeActiveButton();
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
initializeActiveButton() {
|
|
2720
|
+
// Set initial active button
|
|
2721
|
+
const initial = this.initialActiveId;
|
|
2722
|
+
if (initial) {
|
|
2723
|
+
this.activeButtonId.set(initial);
|
|
2724
|
+
}
|
|
2725
|
+
else {
|
|
2726
|
+
// Find the first active button from the config
|
|
2727
|
+
const activeButton = this.buttons?.find((btn) => btn.isActive);
|
|
2728
|
+
if (activeButton) {
|
|
2729
|
+
this.activeButtonId.set(activeButton.id);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
// Handle button click
|
|
2734
|
+
onButtonClick(buttonId) {
|
|
2735
|
+
if (!this.disabled) {
|
|
2736
|
+
this.activeButtonId.set(buttonId);
|
|
2737
|
+
this.activeButtonChange.emit(buttonId);
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
// Check if a button is active
|
|
2741
|
+
isButtonActive(buttonId) {
|
|
2742
|
+
return this.activeButtonId() === buttonId;
|
|
2743
|
+
}
|
|
2744
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2745
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", type: ButtonGroupComponent, isStandalone: true, selector: "lib-button-group", inputs: { buttons: "buttons", initialActiveId: "initialActiveId", disabled: "disabled" }, outputs: { activeButtonChange: "activeButtonChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"button-group\" role=\"tablist\">\n @for (button of buttons; track button.id) {\n <lib-button-group-item\n [button]=\"button\"\n [isActive]=\"isButtonActive(button.id)\"\n [disabled]=\"disabled\"\n (buttonClick)=\"onButtonClick($event)\"\n class=\"button-group-item\"\n />\n }\n</div>\n", styles: [".button-group{display:flex}.button-group lib-button-group-item:first-child::ng-deep .tab-btn{border-radius:.25rem 0 0 .25rem;border-left:1px solid #d0d0d0}.button-group lib-button-group-item:first-child::ng-deep .tab-btn:disabled{border-left:1px solid #767676}.button-group lib-button-group-item:last-child::ng-deep .tab-btn{border-radius:0 .25rem .25rem 0}@media (max-width: 640px){.button-group{overflow-x:auto;-webkit-overflow-scrolling:touch}}\n"], dependencies: [{ kind: "component", type: ButtonGroupItemComponent, selector: "lib-button-group-item", inputs: ["button", "isActive", "disabled"], outputs: ["buttonClick"] }] }); }
|
|
2746
|
+
}
|
|
2747
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ButtonGroupComponent, decorators: [{
|
|
2748
|
+
type: Component,
|
|
2749
|
+
args: [{ selector: 'lib-button-group', standalone: true, imports: [ButtonGroupItemComponent], template: "<div class=\"button-group\" role=\"tablist\">\n @for (button of buttons; track button.id) {\n <lib-button-group-item\n [button]=\"button\"\n [isActive]=\"isButtonActive(button.id)\"\n [disabled]=\"disabled\"\n (buttonClick)=\"onButtonClick($event)\"\n class=\"button-group-item\"\n />\n }\n</div>\n", styles: [".button-group{display:flex}.button-group lib-button-group-item:first-child::ng-deep .tab-btn{border-radius:.25rem 0 0 .25rem;border-left:1px solid #d0d0d0}.button-group lib-button-group-item:first-child::ng-deep .tab-btn:disabled{border-left:1px solid #767676}.button-group lib-button-group-item:last-child::ng-deep .tab-btn{border-radius:0 .25rem .25rem 0}@media (max-width: 640px){.button-group{overflow-x:auto;-webkit-overflow-scrolling:touch}}\n"] }]
|
|
2750
|
+
}], propDecorators: { buttons: [{
|
|
2751
|
+
type: Input,
|
|
2752
|
+
args: [{ required: true }]
|
|
2753
|
+
}], initialActiveId: [{
|
|
2754
|
+
type: Input
|
|
2755
|
+
}], disabled: [{
|
|
2756
|
+
type: Input
|
|
2757
|
+
}], activeButtonChange: [{
|
|
2758
|
+
type: Output
|
|
2759
|
+
}] } });
|
|
2760
|
+
|
|
2584
2761
|
/*
|
|
2585
2762
|
* Public API Surface of components
|
|
2586
2763
|
*/
|
|
@@ -2589,5 +2766,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImpor
|
|
|
2589
2766
|
* Generated bundle index. Do not edit.
|
|
2590
2767
|
*/
|
|
2591
2768
|
|
|
2592
|
-
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 };
|
|
2769
|
+
export { ADVANCED_SEARCH_FIELD_MAP, ADVANCED_SEARCH_OPTIONS, ADVANCED_SEARCH_QUALIFIER_MAP, ButtonComponent, ButtonGroupComponent, HbllFooterComponent, HbllHeaderComponent, HbllItemTypeIconPipe, HeaderWithImpersonationComponent, ImpersonateModalComponent, ImpersonateUserPipe, ImpersonationBannerComponent, LIBRARY_HOURS_API_URL, SnackbarComponent, SnackbarService, SsSearchBarComponent, StatusButtonComponent, defaultOidcBaseUri, defaultOidcDefaultIdp, getUserStatusFromRoles, isAdvancedSearchExternalFieldOption, isAdvancedSearchFieldOption, isAdvancedSearchLocalFieldOption, isSearchScope };
|
|
2593
2770
|
//# sourceMappingURL=byuhbll-components.mjs.map
|