hopesf-angular-dev-utils 1.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.
@@ -0,0 +1,765 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, Output, Input, Component, forwardRef, ContentChild, createComponent, Injectable } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
6
+ import { Subject } from 'rxjs';
7
+
8
+ class ButtonComponent {
9
+ constructor() {
10
+ this.variant = 'primary';
11
+ this.size = 'md';
12
+ this.type = 'button';
13
+ this.disabled = false;
14
+ this.loading = false;
15
+ this.fullWidth = false;
16
+ this.clicked = new EventEmitter();
17
+ }
18
+ get buttonClasses() {
19
+ const classes = ['adu-button', `adu-button-${this.variant}`, `adu-button-${this.size}`];
20
+ if (this.fullWidth) {
21
+ classes.push('w-full');
22
+ }
23
+ return classes.join(' ');
24
+ }
25
+ handleClick(event) {
26
+ if (!this.disabled && !this.loading) {
27
+ this.clicked.emit(event);
28
+ }
29
+ }
30
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
31
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ButtonComponent, isStandalone: true, selector: "adu-button", inputs: { variant: "variant", size: "size", type: "type", disabled: "disabled", loading: "loading", fullWidth: "fullWidth" }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
32
+ <button
33
+ [type]="type"
34
+ [disabled]="disabled || loading"
35
+ [class]="buttonClasses"
36
+ (click)="handleClick($event)"
37
+ >
38
+ <span *ngIf="loading" class="adu-button-spinner"></span>
39
+ <ng-content></ng-content>
40
+ </button>
41
+ `, isInline: true, styles: [".adu-button{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border-radius:.5rem;font-weight:500;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.adu-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-offset-width: 2px }.adu-button:disabled{cursor:not-allowed;opacity:.5}.adu-button-primary{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-primary:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.adu-button-primary:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1)) }.adu-button-secondary{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-secondary:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.adu-button-secondary:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity, 1)) }.adu-button-success{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-success:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.adu-button-success:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity, 1)) }.adu-button-danger{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-danger:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.adu-button-danger:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1)) }.adu-button-warning{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-warning:hover{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.adu-button-warning:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(234 179 8 / var(--tw-ring-opacity, 1)) }.adu-button-ghost{border-width:1px;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));background-color:transparent;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.adu-button-ghost:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.adu-button-ghost:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity, 1)) }.adu-button-sm{padding:.375rem .75rem;font-size:.875rem;line-height:1.25rem}.adu-button-md{padding:.5rem 1rem;font-size:1rem;line-height:1.5rem}.adu-button-lg{padding:.75rem 1.5rem;font-size:1.125rem;line-height:1.75rem}.adu-button-spinner{display:inline-block;height:1rem;width:1rem}@keyframes spin{to{transform:rotate(360deg)}}.adu-button-spinner{animation:spin 1s linear infinite;border-radius:9999px;border-width:2px;border-color:currentColor;border-top-color:transparent}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
42
+ }
43
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ButtonComponent, decorators: [{
44
+ type: Component,
45
+ args: [{ selector: 'adu-button', standalone: true, imports: [CommonModule], template: `
46
+ <button
47
+ [type]="type"
48
+ [disabled]="disabled || loading"
49
+ [class]="buttonClasses"
50
+ (click)="handleClick($event)"
51
+ >
52
+ <span *ngIf="loading" class="adu-button-spinner"></span>
53
+ <ng-content></ng-content>
54
+ </button>
55
+ `, styles: [".adu-button{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;border-radius:.5rem;font-weight:500;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.adu-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-offset-width: 2px }.adu-button:disabled{cursor:not-allowed;opacity:.5}.adu-button-primary{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-primary:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.adu-button-primary:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1)) }.adu-button-secondary{--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-secondary:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.adu-button-secondary:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity, 1)) }.adu-button-success{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-success:hover{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.adu-button-success:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(34 197 94 / var(--tw-ring-opacity, 1)) }.adu-button-danger{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-danger:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.adu-button-danger:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1)) }.adu-button-warning{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.adu-button-warning:hover{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.adu-button-warning:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(234 179 8 / var(--tw-ring-opacity, 1)) }.adu-button-ghost{border-width:1px;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));background-color:transparent;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.adu-button-ghost:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.adu-button-ghost:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity, 1)) }.adu-button-sm{padding:.375rem .75rem;font-size:.875rem;line-height:1.25rem}.adu-button-md{padding:.5rem 1rem;font-size:1rem;line-height:1.5rem}.adu-button-lg{padding:.75rem 1.5rem;font-size:1.125rem;line-height:1.75rem}.adu-button-spinner{display:inline-block;height:1rem;width:1rem}@keyframes spin{to{transform:rotate(360deg)}}.adu-button-spinner{animation:spin 1s linear infinite;border-radius:9999px;border-width:2px;border-color:currentColor;border-top-color:transparent}\n"] }]
56
+ }], propDecorators: { variant: [{
57
+ type: Input
58
+ }], size: [{
59
+ type: Input
60
+ }], type: [{
61
+ type: Input
62
+ }], disabled: [{
63
+ type: Input
64
+ }], loading: [{
65
+ type: Input
66
+ }], fullWidth: [{
67
+ type: Input
68
+ }], clicked: [{
69
+ type: Output
70
+ }] } });
71
+
72
+ class InputComponent {
73
+ constructor() {
74
+ this.id = `adu-input-${Math.random().toString(36).substr(2, 9)}`;
75
+ this.label = '';
76
+ this.type = 'text';
77
+ this.placeholder = '';
78
+ this.size = 'md';
79
+ this.disabled = false;
80
+ this.readonly = false;
81
+ this.required = false;
82
+ this.error = '';
83
+ this.hint = '';
84
+ this.icon = '';
85
+ this.value = '';
86
+ this.onChange = () => { };
87
+ this.onTouched = () => { };
88
+ }
89
+ get inputClasses() {
90
+ const classes = ['adu-input', `adu-input-${this.size}`];
91
+ if (this.error) {
92
+ classes.push('adu-input-error-state');
93
+ }
94
+ if (this.icon) {
95
+ classes.push('pr-10');
96
+ }
97
+ return classes.join(' ');
98
+ }
99
+ onInputChange(event) {
100
+ const input = event.target;
101
+ this.value = input.value;
102
+ this.onChange(this.value);
103
+ }
104
+ writeValue(value) {
105
+ this.value = value || '';
106
+ }
107
+ registerOnChange(fn) {
108
+ this.onChange = fn;
109
+ }
110
+ registerOnTouched(fn) {
111
+ this.onTouched = fn;
112
+ }
113
+ setDisabledState(isDisabled) {
114
+ this.disabled = isDisabled;
115
+ }
116
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
117
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: InputComponent, isStandalone: true, selector: "adu-input", inputs: { id: "id", label: "label", type: "type", placeholder: "placeholder", size: "size", disabled: "disabled", readonly: "readonly", required: "required", error: "error", hint: "hint", icon: "icon" }, providers: [
118
+ {
119
+ provide: NG_VALUE_ACCESSOR,
120
+ useExisting: forwardRef(() => InputComponent),
121
+ multi: true
122
+ }
123
+ ], ngImport: i0, template: `
124
+ <div class="adu-input-wrapper">
125
+ <label *ngIf="label" [for]="id" class="adu-input-label">
126
+ {{ label }}
127
+ <span *ngIf="required" class="text-red-500">*</span>
128
+ </label>
129
+
130
+ <div class="relative">
131
+ <input
132
+ [id]="id"
133
+ [type]="type"
134
+ [placeholder]="placeholder"
135
+ [disabled]="disabled"
136
+ [readonly]="readonly"
137
+ [value]="value"
138
+ [class]="inputClasses"
139
+ (input)="onInputChange($event)"
140
+ (blur)="onTouched()"
141
+ />
142
+ <span *ngIf="icon" class="adu-input-icon">{{ icon }}</span>
143
+ </div>
144
+
145
+ <p *ngIf="error" class="adu-input-error">{{ error }}</p>
146
+ <p *ngIf="hint && !error" class="adu-input-hint">{{ hint }}</p>
147
+ </div>
148
+ `, isInline: true, styles: [".adu-input-wrapper{width:100%}.adu-input-label{margin-bottom:.25rem;display:block;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.adu-input{width:100%;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.adu-input:focus{border-color:transparent;outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1)) }.adu-input:disabled{cursor:not-allowed;--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.adu-input::placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.adu-input-sm{padding:.375rem .75rem;font-size:.875rem;line-height:1.25rem}.adu-input-md{padding:.5rem 1rem;font-size:1rem;line-height:1.5rem}.adu-input-lg{padding:.75rem 1.25rem;font-size:1.125rem;line-height:1.75rem}.adu-input-error-state{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.adu-input-error-state:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1)) }.adu-input-icon{pointer-events:none;position:absolute;right:.75rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.adu-input-error{margin-top:.25rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.adu-input-hint{margin-top:.25rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
149
+ }
150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InputComponent, decorators: [{
151
+ type: Component,
152
+ args: [{ selector: 'adu-input', standalone: true, imports: [CommonModule], providers: [
153
+ {
154
+ provide: NG_VALUE_ACCESSOR,
155
+ useExisting: forwardRef(() => InputComponent),
156
+ multi: true
157
+ }
158
+ ], template: `
159
+ <div class="adu-input-wrapper">
160
+ <label *ngIf="label" [for]="id" class="adu-input-label">
161
+ {{ label }}
162
+ <span *ngIf="required" class="text-red-500">*</span>
163
+ </label>
164
+
165
+ <div class="relative">
166
+ <input
167
+ [id]="id"
168
+ [type]="type"
169
+ [placeholder]="placeholder"
170
+ [disabled]="disabled"
171
+ [readonly]="readonly"
172
+ [value]="value"
173
+ [class]="inputClasses"
174
+ (input)="onInputChange($event)"
175
+ (blur)="onTouched()"
176
+ />
177
+ <span *ngIf="icon" class="adu-input-icon">{{ icon }}</span>
178
+ </div>
179
+
180
+ <p *ngIf="error" class="adu-input-error">{{ error }}</p>
181
+ <p *ngIf="hint && !error" class="adu-input-hint">{{ hint }}</p>
182
+ </div>
183
+ `, styles: [".adu-input-wrapper{width:100%}.adu-input-label{margin-bottom:.25rem;display:block;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.adu-input{width:100%;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.adu-input:focus{border-color:transparent;outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1)) }.adu-input:disabled{cursor:not-allowed;--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.adu-input::placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.adu-input-sm{padding:.375rem .75rem;font-size:.875rem;line-height:1.25rem}.adu-input-md{padding:.5rem 1rem;font-size:1rem;line-height:1.5rem}.adu-input-lg{padding:.75rem 1.25rem;font-size:1.125rem;line-height:1.75rem}.adu-input-error-state{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.adu-input-error-state:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1)) }.adu-input-icon{pointer-events:none;position:absolute;right:.75rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.adu-input-error{margin-top:.25rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.adu-input-hint{margin-top:.25rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}\n"] }]
184
+ }], propDecorators: { id: [{
185
+ type: Input
186
+ }], label: [{
187
+ type: Input
188
+ }], type: [{
189
+ type: Input
190
+ }], placeholder: [{
191
+ type: Input
192
+ }], size: [{
193
+ type: Input
194
+ }], disabled: [{
195
+ type: Input
196
+ }], readonly: [{
197
+ type: Input
198
+ }], required: [{
199
+ type: Input
200
+ }], error: [{
201
+ type: Input
202
+ }], hint: [{
203
+ type: Input
204
+ }], icon: [{
205
+ type: Input
206
+ }] } });
207
+
208
+ class CardComponent {
209
+ constructor() {
210
+ this.shadow = 'sm';
211
+ this.hoverable = false;
212
+ this.padding = 'normal';
213
+ this.hasHeader = false;
214
+ this.hasFooter = false;
215
+ }
216
+ get cardClasses() {
217
+ const classes = ['adu-card'];
218
+ if (this.shadow !== 'none') {
219
+ classes.push(`adu-card-shadow-${this.shadow}`);
220
+ }
221
+ if (this.hoverable) {
222
+ classes.push('adu-card-hoverable');
223
+ }
224
+ return classes.join(' ');
225
+ }
226
+ get bodyClasses() {
227
+ const classes = ['adu-card-body'];
228
+ if (this.padding === 'compact') {
229
+ classes.push('adu-card-body-compact');
230
+ }
231
+ else if (this.padding === 'spacious') {
232
+ classes.push('adu-card-body-spacious');
233
+ }
234
+ return classes.join(' ');
235
+ }
236
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
237
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CardComponent, isStandalone: true, selector: "adu-card", inputs: { shadow: "shadow", hoverable: "hoverable", padding: "padding", hasHeader: "hasHeader", hasFooter: "hasFooter" }, ngImport: i0, template: `
238
+ <div [class]="cardClasses">
239
+ <div *ngIf="hasHeader" class="adu-card-header">
240
+ <ng-content select="[card-header]"></ng-content>
241
+ </div>
242
+
243
+ <div class="adu-card-body">
244
+ <ng-content></ng-content>
245
+ </div>
246
+
247
+ <div *ngIf="hasFooter" class="adu-card-footer">
248
+ <ng-content select="[card-footer]"></ng-content>
249
+ </div>
250
+ </div>
251
+ `, isInline: true, styles: [".adu-card{overflow:hidden;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.adu-card-hoverable:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-header{border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:1rem 1.5rem}.adu-card-body{padding:1rem 1.5rem}.adu-card-body-compact{padding:.75rem 1rem}.adu-card-body-spacious{padding:1.5rem 2rem}.adu-card-footer{border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:1rem 1.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
252
+ }
253
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CardComponent, decorators: [{
254
+ type: Component,
255
+ args: [{ selector: 'adu-card', standalone: true, imports: [CommonModule], template: `
256
+ <div [class]="cardClasses">
257
+ <div *ngIf="hasHeader" class="adu-card-header">
258
+ <ng-content select="[card-header]"></ng-content>
259
+ </div>
260
+
261
+ <div class="adu-card-body">
262
+ <ng-content></ng-content>
263
+ </div>
264
+
265
+ <div *ngIf="hasFooter" class="adu-card-footer">
266
+ <ng-content select="[card-footer]"></ng-content>
267
+ </div>
268
+ </div>
269
+ `, styles: [".adu-card{overflow:hidden;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.adu-card-hoverable:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.adu-card-header{border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:1rem 1.5rem}.adu-card-body{padding:1rem 1.5rem}.adu-card-body-compact{padding:.75rem 1rem}.adu-card-body-spacious{padding:1.5rem 2rem}.adu-card-footer{border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:1rem 1.5rem}\n"] }]
270
+ }], propDecorators: { shadow: [{
271
+ type: Input
272
+ }], hoverable: [{
273
+ type: Input
274
+ }], padding: [{
275
+ type: Input
276
+ }], hasHeader: [{
277
+ type: Input
278
+ }], hasFooter: [{
279
+ type: Input
280
+ }] } });
281
+
282
+ class ModalComponent {
283
+ constructor() {
284
+ this.isOpen = false;
285
+ this.title = '';
286
+ this.size = 'md';
287
+ this.closeOnBackdrop = true;
288
+ this.showCloseButton = true;
289
+ this.hasFooter = false;
290
+ this.isOpenChange = new EventEmitter();
291
+ this.closed = new EventEmitter();
292
+ }
293
+ get modalClasses() {
294
+ return ['adu-modal-content', `adu-modal-${this.size}`].join(' ');
295
+ }
296
+ close() {
297
+ this.isOpen = false;
298
+ this.isOpenChange.emit(false);
299
+ this.closed.emit();
300
+ }
301
+ onBackdropClick() {
302
+ if (this.closeOnBackdrop) {
303
+ this.close();
304
+ }
305
+ }
306
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
307
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ModalComponent, isStandalone: true, selector: "adu-modal", inputs: { isOpen: "isOpen", title: "title", size: "size", closeOnBackdrop: "closeOnBackdrop", showCloseButton: "showCloseButton", hasFooter: "hasFooter" }, outputs: { isOpenChange: "isOpenChange", closed: "closed" }, ngImport: i0, template: `
308
+ <div class="adu-modal-wrapper" *ngIf="isOpen" (click)="onBackdropClick()">
309
+ <div [class]="modalClasses" (click)="$event.stopPropagation()">
310
+ <button
311
+ *ngIf="showCloseButton"
312
+ class="adu-modal-close"
313
+ (click)="close()"
314
+ aria-label="Close modal"
315
+ >
316
+ ×
317
+ </button>
318
+
319
+ <div *ngIf="title" class="adu-modal-title">
320
+ {{ title }}
321
+ </div>
322
+
323
+ <div class="adu-modal-body">
324
+ <ng-content></ng-content>
325
+ </div>
326
+
327
+ <div *ngIf="hasFooter" class="adu-modal-footer">
328
+ <ng-content select="[modal-footer]"></ng-content>
329
+ </div>
330
+ </div>
331
+ </div>
332
+ `, isInline: true, styles: [".adu-modal-wrapper{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1));--tw-bg-opacity: .5;padding:1rem;animation:fadeIn .2s ease-out}.adu-modal-content{position:relative;max-height:90vh;overflow-y:auto;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);animation:slideUp .3s ease-out}.adu-modal-sm{width:100%;max-width:24rem}.adu-modal-md{width:100%;max-width:28rem}.adu-modal-lg{width:100%;max-width:42rem}.adu-modal-xl{width:100%;max-width:56rem}.adu-modal-full{height:100%;width:100%;max-width:none;border-radius:0}.adu-modal-close{position:absolute;top:1rem;right:1rem;font-size:1.875rem;line-height:2.25rem;font-weight:300;line-height:1;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-modal-close:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.adu-modal-close{display:flex;height:2rem;width:2rem;align-items:center;justify-content:center}.adu-modal-title{border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));padding:1rem 1.5rem;font-size:1.25rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.adu-modal-body{padding:1rem 1.5rem}.adu-modal-footer{display:flex;justify-content:flex-end;gap:.5rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:1rem 1.5rem}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .2s ease-out}.animate-slideUp{animation:slideUp .3s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
333
+ }
334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalComponent, decorators: [{
335
+ type: Component,
336
+ args: [{ selector: 'adu-modal', standalone: true, imports: [CommonModule], template: `
337
+ <div class="adu-modal-wrapper" *ngIf="isOpen" (click)="onBackdropClick()">
338
+ <div [class]="modalClasses" (click)="$event.stopPropagation()">
339
+ <button
340
+ *ngIf="showCloseButton"
341
+ class="adu-modal-close"
342
+ (click)="close()"
343
+ aria-label="Close modal"
344
+ >
345
+ ×
346
+ </button>
347
+
348
+ <div *ngIf="title" class="adu-modal-title">
349
+ {{ title }}
350
+ </div>
351
+
352
+ <div class="adu-modal-body">
353
+ <ng-content></ng-content>
354
+ </div>
355
+
356
+ <div *ngIf="hasFooter" class="adu-modal-footer">
357
+ <ng-content select="[modal-footer]"></ng-content>
358
+ </div>
359
+ </div>
360
+ </div>
361
+ `, styles: [".adu-modal-wrapper{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1));--tw-bg-opacity: .5;padding:1rem;animation:fadeIn .2s ease-out}.adu-modal-content{position:relative;max-height:90vh;overflow-y:auto;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);animation:slideUp .3s ease-out}.adu-modal-sm{width:100%;max-width:24rem}.adu-modal-md{width:100%;max-width:28rem}.adu-modal-lg{width:100%;max-width:42rem}.adu-modal-xl{width:100%;max-width:56rem}.adu-modal-full{height:100%;width:100%;max-width:none;border-radius:0}.adu-modal-close{position:absolute;top:1rem;right:1rem;font-size:1.875rem;line-height:2.25rem;font-weight:300;line-height:1;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-modal-close:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.adu-modal-close{display:flex;height:2rem;width:2rem;align-items:center;justify-content:center}.adu-modal-title{border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));padding:1rem 1.5rem;font-size:1.25rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.adu-modal-body{padding:1rem 1.5rem}.adu-modal-footer{display:flex;justify-content:flex-end;gap:.5rem;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:1rem 1.5rem}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .2s ease-out}.animate-slideUp{animation:slideUp .3s ease-out}\n"] }]
362
+ }], propDecorators: { isOpen: [{
363
+ type: Input
364
+ }], title: [{
365
+ type: Input
366
+ }], size: [{
367
+ type: Input
368
+ }], closeOnBackdrop: [{
369
+ type: Input
370
+ }], showCloseButton: [{
371
+ type: Input
372
+ }], hasFooter: [{
373
+ type: Input
374
+ }], isOpenChange: [{
375
+ type: Output
376
+ }], closed: [{
377
+ type: Output
378
+ }] } });
379
+
380
+ class TableComponent {
381
+ constructor() {
382
+ this.data = [];
383
+ this.columns = [];
384
+ this.config = {
385
+ sortable: true,
386
+ pageable: true,
387
+ pageSize: 10,
388
+ striped: true,
389
+ hoverable: true
390
+ };
391
+ this.rowClicked = new EventEmitter();
392
+ this.sortChanged = new EventEmitter();
393
+ this.sortColumn = '';
394
+ this.sortDirection = 'asc';
395
+ this.currentPage = 1;
396
+ this.hasEmptyState = false;
397
+ }
398
+ ngOnInit() {
399
+ this.config = { ...this.getDefaultConfig(), ...this.config };
400
+ }
401
+ get sortedData() {
402
+ if (!this.config.sortable || !this.sortColumn) {
403
+ return this.data;
404
+ }
405
+ return [...this.data].sort((a, b) => {
406
+ const aVal = this.getNestedValue(a, this.sortColumn);
407
+ const bVal = this.getNestedValue(b, this.sortColumn);
408
+ if (aVal < bVal)
409
+ return this.sortDirection === 'asc' ? -1 : 1;
410
+ if (aVal > bVal)
411
+ return this.sortDirection === 'asc' ? 1 : -1;
412
+ return 0;
413
+ });
414
+ }
415
+ get paginatedData() {
416
+ if (!this.config.pageable) {
417
+ return this.sortedData;
418
+ }
419
+ const start = (this.currentPage - 1) * (this.config.pageSize || 10);
420
+ const end = start + (this.config.pageSize || 10);
421
+ return this.sortedData.slice(start, end);
422
+ }
423
+ get totalPages() {
424
+ return Math.ceil(this.data.length / (this.config.pageSize || 10));
425
+ }
426
+ onSort(column) {
427
+ if (!column.sortable || !this.config.sortable)
428
+ return;
429
+ if (this.sortColumn === column.key) {
430
+ this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
431
+ }
432
+ else {
433
+ this.sortColumn = column.key;
434
+ this.sortDirection = 'asc';
435
+ }
436
+ this.sortChanged.emit({ column: column.key, direction: this.sortDirection });
437
+ }
438
+ goToPage(page) {
439
+ if (page >= 1 && page <= this.totalPages) {
440
+ this.currentPage = page;
441
+ }
442
+ }
443
+ getCellValue(row, column) {
444
+ if (column.cellTemplate) {
445
+ return column.cellTemplate(row);
446
+ }
447
+ return this.getNestedValue(row, column.key);
448
+ }
449
+ getNestedValue(obj, path) {
450
+ return path.split('.').reduce((current, prop) => current?.[prop], obj);
451
+ }
452
+ getDefaultConfig() {
453
+ return {
454
+ sortable: true,
455
+ pageable: true,
456
+ pageSize: 10,
457
+ striped: true,
458
+ hoverable: true
459
+ };
460
+ }
461
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
462
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TableComponent, isStandalone: true, selector: "adu-table", inputs: { data: "data", columns: "columns", config: "config" }, outputs: { rowClicked: "rowClicked", sortChanged: "sortChanged" }, queries: [{ propertyName: "cellTemplate", first: true, predicate: ["cellTemplate"], descendants: true }], ngImport: i0, template: `
463
+ <div class="adu-table-container">
464
+ <table class="adu-table" [class.adu-table-striped]="config.striped" [class.adu-table-hoverable]="config.hoverable">
465
+ <thead class="adu-table-header">
466
+ <tr>
467
+ <th
468
+ *ngFor="let column of columns"
469
+ [style.width]="column.width"
470
+ [class.adu-table-sortable]="column.sortable && config.sortable"
471
+ (click)="onSort(column)"
472
+ class="adu-table-th"
473
+ >
474
+ <div class="flex items-center justify-between">
475
+ <span>{{ column.label }}</span>
476
+ <span *ngIf="column.sortable && config.sortable" class="adu-table-sort-icon">
477
+ <span *ngIf="sortColumn === column.key">
478
+ {{ sortDirection === 'asc' ? '↑' : '↓' }}
479
+ </span>
480
+ <span *ngIf="sortColumn !== column.key" class="text-gray-300">↕</span>
481
+ </span>
482
+ </div>
483
+ </th>
484
+ </tr>
485
+ </thead>
486
+ <tbody class="adu-table-body">
487
+ <tr *ngFor="let row of paginatedData; let i = index" class="adu-table-row">
488
+ <td *ngFor="let column of columns" class="adu-table-td">
489
+ <ng-container *ngIf="cellTemplate; else defaultCell">
490
+ <ng-container *ngTemplateOutlet="cellTemplate; context: { $implicit: row, column: column }"></ng-container>
491
+ </ng-container>
492
+ <ng-template #defaultCell>
493
+ {{ getCellValue(row, column) }}
494
+ </ng-template>
495
+ </td>
496
+ </tr>
497
+ <tr *ngIf="paginatedData.length === 0" class="adu-table-empty">
498
+ <td [attr.colspan]="columns.length" class="text-center py-8 text-gray-500">
499
+ <ng-content select="[empty-state]"></ng-content>
500
+ <span *ngIf="!hasEmptyState">No data available</span>
501
+ </td>
502
+ </tr>
503
+ </tbody>
504
+ </table>
505
+
506
+ <!-- Pagination -->
507
+ <div *ngIf="config.pageable && totalPages > 1" class="adu-table-pagination">
508
+ <button
509
+ class="adu-pagination-btn"
510
+ [disabled]="currentPage === 1"
511
+ (click)="goToPage(currentPage - 1)"
512
+ >
513
+ Previous
514
+ </button>
515
+
516
+ <div class="adu-pagination-info">
517
+ Page {{ currentPage }} of {{ totalPages }}
518
+ </div>
519
+
520
+ <button
521
+ class="adu-pagination-btn"
522
+ [disabled]="currentPage === totalPages"
523
+ (click)="goToPage(currentPage + 1)"
524
+ >
525
+ Next
526
+ </button>
527
+ </div>
528
+ </div>
529
+ `, isInline: true, styles: [".adu-table-container{width:100%;overflow-x:auto;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.adu-table{width:100%;border-collapse:collapse}.adu-table-header{border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-table-th{padding:.75rem 1.5rem;text-align:left;font-size:.75rem;line-height:1rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.adu-table-sortable{cursor:pointer;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-table-sortable:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.adu-table-sort-icon{margin-left:.5rem;display:inline-block}.adu-table-body>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.adu-table-row{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-table-striped .adu-table-row:nth-child(2n){--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-table-hoverable .adu-table-row:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.adu-table-td{padding:1rem 1.5rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.adu-table-empty{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-table-pagination{display:flex;align-items:center;justify-content:space-between;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:.75rem 1.5rem}.adu-pagination-btn{border-radius:.375rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-pagination-btn:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-pagination-btn:disabled{cursor:not-allowed;opacity:.5}.adu-pagination-info{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
530
+ }
531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableComponent, decorators: [{
532
+ type: Component,
533
+ args: [{ selector: 'adu-table', standalone: true, imports: [CommonModule], template: `
534
+ <div class="adu-table-container">
535
+ <table class="adu-table" [class.adu-table-striped]="config.striped" [class.adu-table-hoverable]="config.hoverable">
536
+ <thead class="adu-table-header">
537
+ <tr>
538
+ <th
539
+ *ngFor="let column of columns"
540
+ [style.width]="column.width"
541
+ [class.adu-table-sortable]="column.sortable && config.sortable"
542
+ (click)="onSort(column)"
543
+ class="adu-table-th"
544
+ >
545
+ <div class="flex items-center justify-between">
546
+ <span>{{ column.label }}</span>
547
+ <span *ngIf="column.sortable && config.sortable" class="adu-table-sort-icon">
548
+ <span *ngIf="sortColumn === column.key">
549
+ {{ sortDirection === 'asc' ? '↑' : '↓' }}
550
+ </span>
551
+ <span *ngIf="sortColumn !== column.key" class="text-gray-300">↕</span>
552
+ </span>
553
+ </div>
554
+ </th>
555
+ </tr>
556
+ </thead>
557
+ <tbody class="adu-table-body">
558
+ <tr *ngFor="let row of paginatedData; let i = index" class="adu-table-row">
559
+ <td *ngFor="let column of columns" class="adu-table-td">
560
+ <ng-container *ngIf="cellTemplate; else defaultCell">
561
+ <ng-container *ngTemplateOutlet="cellTemplate; context: { $implicit: row, column: column }"></ng-container>
562
+ </ng-container>
563
+ <ng-template #defaultCell>
564
+ {{ getCellValue(row, column) }}
565
+ </ng-template>
566
+ </td>
567
+ </tr>
568
+ <tr *ngIf="paginatedData.length === 0" class="adu-table-empty">
569
+ <td [attr.colspan]="columns.length" class="text-center py-8 text-gray-500">
570
+ <ng-content select="[empty-state]"></ng-content>
571
+ <span *ngIf="!hasEmptyState">No data available</span>
572
+ </td>
573
+ </tr>
574
+ </tbody>
575
+ </table>
576
+
577
+ <!-- Pagination -->
578
+ <div *ngIf="config.pageable && totalPages > 1" class="adu-table-pagination">
579
+ <button
580
+ class="adu-pagination-btn"
581
+ [disabled]="currentPage === 1"
582
+ (click)="goToPage(currentPage - 1)"
583
+ >
584
+ Previous
585
+ </button>
586
+
587
+ <div class="adu-pagination-info">
588
+ Page {{ currentPage }} of {{ totalPages }}
589
+ </div>
590
+
591
+ <button
592
+ class="adu-pagination-btn"
593
+ [disabled]="currentPage === totalPages"
594
+ (click)="goToPage(currentPage + 1)"
595
+ >
596
+ Next
597
+ </button>
598
+ </div>
599
+ </div>
600
+ `, styles: [".adu-table-container{width:100%;overflow-x:auto;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.adu-table{width:100%;border-collapse:collapse}.adu-table-header{border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-table-th{padding:.75rem 1.5rem;text-align:left;font-size:.75rem;line-height:1rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.adu-table-sortable{cursor:pointer;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-table-sortable:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.adu-table-sort-icon{margin-left:.5rem;display:inline-block}.adu-table-body>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));--tw-divide-opacity: 1;border-color:rgb(229 231 235 / var(--tw-divide-opacity, 1))}.adu-table-row{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-table-striped .adu-table-row:nth-child(2n){--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-table-hoverable .adu-table-row:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.adu-table-td{padding:1rem 1.5rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.adu-table-empty{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-table-pagination{display:flex;align-items:center;justify-content:space-between;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1));padding:.75rem 1.5rem}.adu-pagination-btn{border-radius:.375rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));padding:.5rem 1rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.adu-pagination-btn:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.adu-pagination-btn:disabled{cursor:not-allowed;opacity:.5}.adu-pagination-info{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}\n"] }]
601
+ }], propDecorators: { data: [{
602
+ type: Input
603
+ }], columns: [{
604
+ type: Input
605
+ }], config: [{
606
+ type: Input
607
+ }], cellTemplate: [{
608
+ type: ContentChild,
609
+ args: ['cellTemplate']
610
+ }], rowClicked: [{
611
+ type: Output
612
+ }], sortChanged: [{
613
+ type: Output
614
+ }] } });
615
+
616
+ class SpinnerComponent {
617
+ constructor() {
618
+ this.size = 'md';
619
+ this.color = 'primary';
620
+ this.overlay = false;
621
+ this.message = '';
622
+ }
623
+ get spinnerClasses() {
624
+ return ['adu-spinner', `adu-spinner-${this.size}`, `adu-spinner-${this.color}`].join(' ');
625
+ }
626
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
627
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SpinnerComponent, isStandalone: true, selector: "adu-spinner", inputs: { size: "size", color: "color", overlay: "overlay", message: "message" }, ngImport: i0, template: `
628
+ <div *ngIf="overlay" class="adu-spinner-overlay">
629
+ <div [class]="spinnerClasses"></div>
630
+ <p *ngIf="message" class="adu-spinner-message">{{ message }}</p>
631
+ </div>
632
+
633
+ <div *ngIf="!overlay" [class]="spinnerClasses"></div>
634
+ `, isInline: true, styles: [".adu-spinner{display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.adu-spinner{animation:spin 1s linear infinite;border-radius:9999px;border-width:4px;border-top-color:transparent}.adu-spinner-sm{height:1rem;width:1rem;border-width:2px}.adu-spinner-md{height:2rem;width:2rem;border-width:4px}.adu-spinner-lg{height:3rem;width:3rem;border-width:4px}.adu-spinner-primary{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1));border-top-color:transparent}.adu-spinner-secondary{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1));border-top-color:transparent}.adu-spinner-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1));border-top-color:transparent}.adu-spinner-overlay{position:fixed;inset:0;z-index:50;display:flex;flex-direction:column;align-items:center;justify-content:center;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1));--tw-bg-opacity: .5 }.adu-spinner-message{margin-top:1rem;font-size:1.125rem;line-height:1.75rem;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
635
+ }
636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SpinnerComponent, decorators: [{
637
+ type: Component,
638
+ args: [{ selector: 'adu-spinner', standalone: true, imports: [CommonModule], template: `
639
+ <div *ngIf="overlay" class="adu-spinner-overlay">
640
+ <div [class]="spinnerClasses"></div>
641
+ <p *ngIf="message" class="adu-spinner-message">{{ message }}</p>
642
+ </div>
643
+
644
+ <div *ngIf="!overlay" [class]="spinnerClasses"></div>
645
+ `, styles: [".adu-spinner{display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}.adu-spinner{animation:spin 1s linear infinite;border-radius:9999px;border-width:4px;border-top-color:transparent}.adu-spinner-sm{height:1rem;width:1rem;border-width:2px}.adu-spinner-md{height:2rem;width:2rem;border-width:4px}.adu-spinner-lg{height:3rem;width:3rem;border-width:4px}.adu-spinner-primary{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1));border-top-color:transparent}.adu-spinner-secondary{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1));border-top-color:transparent}.adu-spinner-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity, 1));border-top-color:transparent}.adu-spinner-overlay{position:fixed;inset:0;z-index:50;display:flex;flex-direction:column;align-items:center;justify-content:center;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1));--tw-bg-opacity: .5 }.adu-spinner-message{margin-top:1rem;font-size:1.125rem;line-height:1.75rem;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}\n"] }]
646
+ }], propDecorators: { size: [{
647
+ type: Input
648
+ }], color: [{
649
+ type: Input
650
+ }], overlay: [{
651
+ type: Input
652
+ }], message: [{
653
+ type: Input
654
+ }] } });
655
+
656
+ class ModalService {
657
+ constructor(appRef, injector) {
658
+ this.appRef = appRef;
659
+ this.injector = injector;
660
+ this.modalComponentRef = null;
661
+ this.closeSubject = new Subject();
662
+ }
663
+ open(component, config = {}) {
664
+ // Close existing modal if any
665
+ if (this.modalComponentRef) {
666
+ this.close();
667
+ }
668
+ // Create modal wrapper
669
+ const modalWrapper = document.createElement('div');
670
+ modalWrapper.className = this.getModalWrapperClasses(config);
671
+ // Create backdrop
672
+ const backdrop = document.createElement('div');
673
+ backdrop.className = 'adu-modal-backdrop';
674
+ if (config.closeOnBackdrop !== false) {
675
+ backdrop.onclick = () => this.close();
676
+ }
677
+ // Create modal content
678
+ const modalContent = document.createElement('div');
679
+ modalContent.className = this.getModalContentClasses(config);
680
+ modalContent.onclick = (e) => e.stopPropagation();
681
+ // Create close button if needed
682
+ if (config.showCloseButton !== false) {
683
+ const closeBtn = document.createElement('button');
684
+ closeBtn.className = 'adu-modal-close';
685
+ closeBtn.innerHTML = '×';
686
+ closeBtn.onclick = () => this.close();
687
+ modalContent.appendChild(closeBtn);
688
+ }
689
+ // Add title if provided
690
+ if (config.title) {
691
+ const titleEl = document.createElement('div');
692
+ titleEl.className = 'adu-modal-title';
693
+ titleEl.textContent = config.title;
694
+ modalContent.appendChild(titleEl);
695
+ }
696
+ // Create component container
697
+ const componentContainer = document.createElement('div');
698
+ componentContainer.className = 'adu-modal-body';
699
+ modalContent.appendChild(componentContainer);
700
+ // Assemble modal
701
+ modalWrapper.appendChild(backdrop);
702
+ modalWrapper.appendChild(modalContent);
703
+ document.body.appendChild(modalWrapper);
704
+ // Create and attach component
705
+ this.modalComponentRef = createComponent(component, {
706
+ environmentInjector: this.injector,
707
+ hostElement: componentContainer
708
+ });
709
+ this.appRef.attachView(this.modalComponentRef.hostView);
710
+ // Handle ESC key
711
+ if (config.closeOnEscape !== false) {
712
+ const escHandler = (e) => {
713
+ if (e.key === 'Escape') {
714
+ this.close();
715
+ document.removeEventListener('keydown', escHandler);
716
+ }
717
+ };
718
+ document.addEventListener('keydown', escHandler);
719
+ }
720
+ return {
721
+ close: (result) => this.close(result),
722
+ afterClosed: () => this.closeSubject
723
+ };
724
+ }
725
+ close(result) {
726
+ if (this.modalComponentRef) {
727
+ this.appRef.detachView(this.modalComponentRef.hostView);
728
+ this.modalComponentRef.destroy();
729
+ this.modalComponentRef = null;
730
+ // Remove modal from DOM
731
+ const modals = document.querySelectorAll('.adu-modal-wrapper');
732
+ modals.forEach(modal => modal.remove());
733
+ this.closeSubject.next(result);
734
+ this.closeSubject.complete();
735
+ this.closeSubject = new Subject();
736
+ }
737
+ }
738
+ getModalWrapperClasses(config) {
739
+ return 'adu-modal-wrapper';
740
+ }
741
+ getModalContentClasses(config) {
742
+ const size = config.size || 'md';
743
+ return `adu-modal-content adu-modal-${size}`;
744
+ }
745
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalService, deps: [{ token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
746
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalService, providedIn: 'root' }); }
747
+ }
748
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ModalService, decorators: [{
749
+ type: Injectable,
750
+ args: [{
751
+ providedIn: 'root'
752
+ }]
753
+ }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
754
+
755
+ /*
756
+ * Public API Surface of angular-dev-utils
757
+ */
758
+ // Components
759
+
760
+ /**
761
+ * Generated bundle index. Do not edit.
762
+ */
763
+
764
+ export { ButtonComponent, CardComponent, InputComponent, ModalComponent, ModalService, SpinnerComponent, TableComponent };
765
+ //# sourceMappingURL=hopesf-angular-dev-utils.mjs.map